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

update: backtrack to method 2

parent d7b5e10f
No related branches found
No related tags found
1 merge request!6Clhp map
No preview for this file type
import geopandas as gpd import geopandas as gpd
from shapely.geometry import Polygon, Point, LineString, MultiPolygon from shapely.geometry import Polygon, LineString
from shapely.ops import linemerge, unary_union, polygonize
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import matplotlib.ticker as ticker import matplotlib.ticker as ticker
import random import random
...@@ -18,44 +19,14 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -18,44 +19,14 @@ 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
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) lines = create_grid(polygon, cell_size)
vrt_lines = grid_lines[0] # Vertical grid coordinates
hrz_lines = grid_lines[1] # Horizontal grid coordinates
# Cut polygon into horizontal sections, bottom to top
for hrz_line in hrz_lines:
# Split shape into upper and lower section as hrz_line as divider
divided_poly = cut_polygon_by_points(polygon, hrz_line, cell_size)
horizontal_section = divided_poly[0] # Save upper horizontal section
polygon = divided_poly[1] # Set polygon to the remaining, un-split shape for next iteration
if not horizontal_section or not divided_poly[0]:
continue
# Cut each horizontal section into vertical sections, right to left
for vrt_line in vrt_lines:
if len(horizontal_section.exterior.coords) < 3:
break # Break from loop im remaining section has no coordinates
# Split the horizontal section into two vertical parts
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
# Set horizontal_section to the remaining, un-split, horizontal section for next iteration lines.append(polygon.boundary)
horizontal_section = vertical_parts[1] lines = unary_union(lines)
lines = linemerge(lines)
polygon = divided_poly[1] # Set polygon to the remaining, un-split shape for next iteration divided_map.extend(list(polygonize(lines)))
divided_map.append(polygon)
break
tiles = gpd.GeoDataFrame(geometry=divided_map) tiles = gpd.GeoDataFrame(geometry=divided_map)
...@@ -85,77 +56,6 @@ def get_relation(self, body_of_water: str): # NB: implement body_of_water ...@@ -85,77 +56,6 @@ 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'))
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
for i in range(len(exterior_coords) - 1):
point1 = Point(exterior_coords[i])
point2 = Point(exterior_coords[i + 1])
# Check if both points are on the same side of the divisor
if (point1.y < divisor and point2.y < divisor) or (point1.y >= divisor and point2.y >= divisor):
# Both points on same side, add to appropriate shape
if point1.y < divisor:
split_shape.append(exterior_coords[i])
else:
remaining_shape.append(exterior_coords[i])
else:
# Points on different sides, calculate intersection with divisor
x_intersect = point1.x + (divisor - point1.y) * (point2.x - point1.x) / (point2.y - point1.y)
# Add intersection point to both shapes
split_shape.append((x_intersect, divisor))
remaining_shape.append((x_intersect, divisor))
# Determine which side each original point belongs to
if point1.y < divisor:
split_shape.append((point2.x, point2.y))
else:
remaining_shape.append((point2.x, point2.y))
# Populate newly created edges with points to facilitate vertical cutting
populated_split = populate_new_edge(split_shape, cell_size, divisor)
if populated_split is not None:
split_shape = populated_split
populated_rem = populate_new_edge(remaining_shape, cell_size, divisor)
if populated_rem is not None:
remaining_shape = populated_rem
# Ensure that the shapes are closed loops
if len(split_shape) > 0 and split_shape[0] != split_shape[-1]:
split_shape.append(split_shape[0])
if len(remaining_shape) > 0 and remaining_shape[0] != remaining_shape[-1]:
remaining_shape.append(remaining_shape[0])
return Polygon(split_shape), Polygon(remaining_shape)
# Generate grid of equally spaced x and y coordinates where the grid size is determined by cell_size
def create_grid_coords(polygon: Polygon, cell_size: float):
# Define boundaries of grid
min_x, min_y, max_x, max_y = polygon.bounds
global polygon_min_x
polygon_min_x = min_x
# Divide grid into sections of size *cell_size
x_step = max((max_x - min_x) / 10, cell_size)
y_step = max((max_y - min_y) / 10, cell_size)
x_coords = np.arange(min_x, max_x + x_step, x_step)
y_coords = np.arange(min_y, max_y + y_step, y_step)
return x_coords, y_coords
# NB: only for testing # NB: only for testing
def circle_polygon(): def circle_polygon():
circle_points = [] circle_points = []
...@@ -173,42 +73,25 @@ def circle_polygon(): ...@@ -173,42 +73,25 @@ def circle_polygon():
return Polygon(circle_points) return Polygon(circle_points)
def populate_new_edge(polygon, cell_size: float, divisor: float): def create_grid(poly: Polygon, cell_size):
if polygon is not None and polygon_min_x is not None: # Retrieve bounds of the entire polygon
bounds = poly.bounds
final_shape = []
left_edge = []
left_most_point = None
# Add all coordinates on the right side of the divisor first
for i in range(len(polygon)):
x, y = polygon[i]
if x > divisor:
final_shape.append((x, y))
elif x < divisor:
left_edge.append((x, y))
if len(final_shape) < 1 or len(left_edge) < 1:
return None
# Find most left point in the polygon
for point in left_edge:
if not left_most_point:
left_most_point = point[0]
elif point[0] < left_most_point:
left_most_point = point[0]
# Sort final_shape from bottom to top min_x, min_y, max_x, max_y = bounds
if final_shape[0][1] > final_shape[-1][1]: grid_lines = []
final_shape = sorted(final_shape, key=lambda point: final_shape[1])
i = 0 # Horizontal lines
while polygon[i][0] < left_most_point: # While to haven't reached left edge y = min_y
final_shape.append(polygon[i][0] + cell_size) while y <= max_y:
i += 1 line = LineString([(min_x, y), (max_x, y)])
grid_lines.append(line)
y += cell_size
# NB VERY IMPORTANT MUST CREATE LOGIC FOR SHAPES THAT ARE SPLIT # Vertical lines
final_shape.append(left_edge) x = min_x
final_shape.append(final_shape[0]) while x <= max_x:
line = LineString([(x, min_y), (x, max_y)])
grid_lines.append(line)
x += cell_size
return final_shape return grid_lines
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