Skip to content
Snippets Groups Projects
Commit f02c128e authored by Sara Savanovic Djordjevic's avatar Sara Savanovic Djordjevic
Browse files

update: new edge approach, bugged

parent 932a6b89
No related branches found
No related tags found
1 merge request!6Clhp map
No preview for this file type
...@@ -19,7 +19,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -19,7 +19,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water
# Divide all polygons into sections # Divide all polygons into sections
for polygon in polygons: for polygon in polygons:
cell_size = 1.5 cell_size = 0.4
# Divide the length and with of polygon into a grid of equally sized parts # Divide the length and with of polygon into a grid of equally sized parts
grid_lines = create_grid_coords(polygon, cell_size) grid_lines = create_grid_coords(polygon, cell_size)
...@@ -28,6 +28,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -28,6 +28,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water
# Cut polygon into horizontal sections, bottom to top # Cut polygon into horizontal sections, bottom to top
for hrz_line in hrz_lines: for hrz_line in hrz_lines:
# Split shape into upper and lower section as hrz_line as divider # Split shape into upper and lower section as hrz_line as divider
divided_poly = cut_polygon_by_points(polygon, hrz_line, cell_size) divided_poly = cut_polygon_by_points(polygon, hrz_line, cell_size)
horizontal_section = divided_poly[0] # Save upper horizontal section horizontal_section = divided_poly[0] # Save upper horizontal section
...@@ -43,7 +44,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -43,7 +44,7 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water
break # Break from loop im remaining section has no coordinates break # Break from loop im remaining section has no coordinates
# Split the horizontal section into two vertical parts # Split the horizontal section into two vertical parts
vertical_parts = cut_polygon_by_points(horizontal_section, vrt_line, cell_size) vertical_parts = cut_polygon_by_points(horizontal_section, vrt_line, -0.1)
divided_map.append(vertical_parts[0]) # Append split vertical sections to final list of shapes divided_map.append(vertical_parts[0]) # Append split vertical sections to final list of shapes
...@@ -84,8 +85,89 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -84,8 +85,89 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water
self.wfile.write(tiles_json.encode('utf-8')) self.wfile.write(tiles_json.encode('utf-8'))
'''
# Takes a polygon and divides its coordinates into two shapes, where divisor is a # Takes a polygon and divides its coordinates into two shapes, where divisor is a
# coordinate that defines the point of division. # coordinate that defines the point of division.
def cut_polygon_by_points(polygon: Polygon, divisor: float, cell_size: float):
# Extract polygon exterior coordinates
exterior_coords = list(polygon.exterior.coords)
# Initialize lists to store coordinates of new shapes after split
split_shape = []
remaining_shape = []
# Loop through points and check which side of the division line they are
if cell_size > 0: # Horizontal split
prev_point = exterior_coords[0]
for point in exterior_coords:
point = Point(point) # Convert coordinates to Shapely Point object
if point.y < divisor < prev_point.y:
remaining_shape.append(point)
remaining_shape.append((point.x, divisor))
split_shape.append((prev_point.x, divisor))
split_shape.append(prev_point)
elif point.y > divisor > prev_point.y:
split_shape.append(point)
split_shape.append((point.x, divisor))
remaining_shape.append((prev_point.x, divisor))
remaining_shape.append(prev_point)
elif point.y < divisor: # Check if point is over or below divisor
split_shape.append(point) # Append to appropriate shape
elif point.y > divisor:
remaining_shape.append(point)
prev_point = point
# Populate newly created edges with points to facilitate vertical cutting
populated_shapes = populate_new_edge(split_shape, remaining_shape, cell_size, divisor)
if populated_shapes is not None:
split_shape = populated_shapes[0]
remaining_shape = populated_shapes[1]
else: # Vertical split
prev_point = exterior_coords[1]
for point in exterior_coords:
point = Point(point) # Convert coordinates to Shapely Point object
if point.x < divisor < prev_point:
remaining_shape.append(point)
remaining_shape.append((divisor, point.y))
split_shape.append((divisor, prev_point.y))
split_shape.append(prev_point)
elif point.x > divisor > prev_point:
split_shape.append(point)
split_shape.append((divisor, point.y))
remaining_shape.append((divisor, prev_point.y))
remaining_shape.append(prev_point)
elif point.x < divisor: # Check if point is over or below divisor
split_shape.append(point) # Append to appropriate shape
elif point.x > divisor:
remaining_shape.append(point)
prev_point = point
# Check if the split_shape has enough coordinates to create a polygon
if len(split_shape) < 3:
# print("Not enough coordinates to create valid polygon: Split shape: ", len(split_shape))
split_shape = None
else:
split_shape.append(split_shape[0]) # Append first coord to create closed loop
# Check if the remaining_shape has enough coordinates to create a polygon
if len(remaining_shape) < 3:
# print("Not enough coordinates to create valid polygon: Remaining shape: ", len(remaining_shape))
remaining_shape = None
else:
remaining_shape.append(remaining_shape[0]) # Append first coord to create closed loop
# Return split polygons as Shapely Polygon objects
return Polygon(split_shape), Polygon(remaining_shape)
'''
def cut_polygon_by_points(polygon: Polygon, divisor: float, cell_size: float): def cut_polygon_by_points(polygon: Polygon, divisor: float, cell_size: float):
# Extract polygon exterior coordinates # Extract polygon exterior coordinates
exterior_coords = list(polygon.exterior.coords) exterior_coords = list(polygon.exterior.coords)
...@@ -174,8 +256,80 @@ def circle_polygon(): ...@@ -174,8 +256,80 @@ def circle_polygon():
return Polygon(circle_points) return Polygon(circle_points)
def populate_new_edge(polygon, cell_size: float, divisor: float):
if polygon is not None and polygon_min_x is not None:
sub_division = []
final_shapes = []
last_sub_division = []
left_most_point = None
for i in range(len(polygon)):
x, y = polygon[i]
if x > divisor:
sub_division.append((x, y))
elif x < divisor:
last_sub_division.append((x, y))
if len(sub_division) < 1 or len(last_sub_division) < 1:
return None
# Find most left point in the polygon
for point in last_sub_division:
if not left_most_point:
left_most_point = point[0]
elif point[0] < left_most_point:
left_most_point = point[0]
# Sort sub_division from bottom to top
if sub_division[0][1] > sub_division[-1][1]:
sub_division = sorted(sub_division, key=lambda point: sub_division[1])
# Append corners to edge piece
sub_division.append((sub_division[-1][0] - cell_size, sub_division[-1][1]))
sub_division.append((sub_division[-1][0] - cell_size, sub_division[0][1]))
# Append first section to list as Shapely Polygon object
final_shapes.append(Polygon(sub_division))
# Save last point of previous tile (upper left corner) as the starting coordinate for a new tile
next_point = sub_division[-1]
# Clear subdivision list for next tile and add point as a reference
sub_division = [next_point]
# Continue making tiles on the horizontal section while the left edge is not reached
while sub_division[-1][0] > left_most_point:
# Append three more corners to new tile
sub_division.append((sub_division[0][0], sub_division[0][1] - cell_size))
sub_division.append((sub_division[0][0] - cell_size, sub_division[-1][1]))
sub_division.append((sub_division[-1][0] - cell_size, sub_division[0][0]))
# NB maybe have to close loop???
# Append new shape, save next starting coordinate, and clear sub_div for next tile
final_shapes.append(Polygon(sub_division))
next_point = sub_division[-1]
sub_division = [next_point]
print("sub_div: ", sub_division[-1], " left_most_point: ", left_most_point)
# Sort last coordinates of last tile from bottom to top
if last_sub_division[0][1] > last_sub_division[-1][1]:
last_sub_division = sorted(last_sub_division, key=lambda point: last_sub_division[1])
# Append two corners to complete the last tile
last_sub_division.append((sub_division[-1][0] - cell_size, sub_division[-1][1]))
last_sub_division.append((sub_division[-1][0] - cell_size, sub_division[-1][1] - cell_size))
# NB maybe have to close loop???
final_shapes.append(Polygon(last_sub_division))
return final_shapes # Return list of all tiles for current horizontal section
'''
# Adds equally spaced points along an edge that is created after a polygon is cut. # Adds equally spaced points along an edge that is created after a polygon is cut.
def populate_new_edge(split_shape, cell_size: float, divisor: float): def populate_new_edge(split_shape, remaining_shape, cell_size: float, divisor: float):
# Prepend new points onto the newly created edge to facilitate vertical splitting # Prepend new points onto the newly created edge to facilitate vertical splitting
if split_shape is not None and polygon_min_x is not None: if split_shape is not None and polygon_min_x is not None:
# Define starting point with an x-value that will be common for all polygons # Define starting point with an x-value that will be common for all polygons
...@@ -184,23 +338,31 @@ def populate_new_edge(split_shape, cell_size: float, divisor: float): ...@@ -184,23 +338,31 @@ def populate_new_edge(split_shape, cell_size: float, divisor: float):
# Create list of corners # Create list of corners
corners = [] corners = []
divisor_range = ((divisor - 0.1),(divisor + 0.1)) # Define tolerance
# Find all corners of split shape. Corner = point that intersects divisor # Find all corners of split shape. Corner = point that intersects divisor
for point in split_shape: for point in split_shape:
if point[1] == divisor: if divisor_range[0] < point.y < divisor_range[1]:
corners.append(point) corners.append(point)
if not corners or len(corners) < 2: if not corners or len(corners) < 2:
return None return None
# Sort corners in ascending order (left to right) based on x coordinate # Sort corners in ascending order (left to right) based on x coordinate
sorted_corners = sorted(corners, key=lambda p: p[0]) sorted_corners = sorted(corners, key=lambda p: p.x)
while starting_point < sorted_corners[0][0]: # Increment starting point until it is withing the polygons bounds while starting_point < sorted_corners[0].x: # Increment starting point until it is withing the polygons bounds
starting_point += cell_size starting_point += cell_size
# if starting_point < left_corner.x: # NB: optimised substitute for previous while loop, requires testing
# starting_point += cell_size * math.floor(starting_point - left_corner.x)
# Insert new points with cell_size spacing while starting_point is within bounds # Insert new points with cell_size spacing while starting_point is within bounds
while starting_point < sorted_corners[-1][0]: while starting_point < sorted_corners[-1].x:
split_shape.insert(0, (starting_point, divisor)) # NB may have to add/subtract small offset of 0.00001 split_shape.insert(0, (starting_point, divisor)) # NB may have to add/subtract small offset of 0.00001
remaining_shape.insert(-1, (starting_point, divisor)) # Prepend new point to shape
starting_point += cell_size starting_point += cell_size
return split_shape return split_shape, remaining_shape
'''
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment