From 608b7b478363b5aba52954c74abe99b5e3ee1db1 Mon Sep 17 00:00:00 2001 From: Pradip-p Date: Mon, 4 Nov 2024 11:28:42 +0545 Subject: [PATCH 1/2] fix: Adjust task dimensions to allow customization and prevent accidental rectangles --- src/backend/app/tasks/task_splitter.py | 43 +++++++++++++++++++------- 1 file changed, 31 insertions(+), 12 deletions(-) diff --git a/src/backend/app/tasks/task_splitter.py b/src/backend/app/tasks/task_splitter.py index 27279053..606f11a8 100644 --- a/src/backend/app/tasks/task_splitter.py +++ b/src/backend/app/tasks/task_splitter.py @@ -10,6 +10,10 @@ from shapely.geometry import Polygon, shape from shapely.geometry.geo import mapping from shapely.ops import unary_union +from pyproj import Transformer +from shapely.ops import transform as shapely_transform +### + # Instantiate logger log = logging.getLogger(__name__) @@ -119,27 +123,36 @@ def geojson_to_shapely_polygon( return shape(features[0].get("geometry")) def splitBySquare(self, meters: int) -> FeatureCollection: - xmin, ymin, xmax, ymax = self.aoi.bounds + # Set up transformations: WGS84 (EPSG:4326) <-> Web Mercator (EPSG:3857) + transformer_to_mercator = Transformer.from_crs( + "EPSG:4326", "EPSG:3857", always_xy=True + ) + transformer_to_wgs84 = Transformer.from_crs( + "EPSG:3857", "EPSG:4326", always_xy=True + ) - meter = 0.0000114 - length = float(meters) * meter - width = float(meters) * meter + # Transform AOI to Web Mercator for accurate grid calculations in meters + aoi_mercator = shapely_transform(transformer_to_mercator.transform, self.aoi) + xmin, ymin, xmax, ymax = aoi_mercator.bounds - area_threshold = (length * width) / 3 + # Generate grid columns and rows based on AOI bounds and specified square length in meters + cols = np.arange(xmin, xmax + meters, meters) + rows = np.arange(ymin, ymax + meters, meters) - # Generate grid columns and rows based on AOI bounds - cols = np.arange(xmin, xmax + width, width) - rows = np.arange(ymin, ymax + length, length) polygons = [] small_polygons = [] + + area_threshold = (meters**2) / 3 + + # Create a grid of square cells in Web Mercator for x in cols[:-1]: for y in rows[:-1]: - # Create a square grid polygon grid_polygon = Polygon( - [(x, y), (x + width, y), (x + width, y + length), (x, y + length)] + [(x, y), (x + meters, y), (x + meters, y + meters), (x, y + meters)] ) + # Clip the grid polygon to fit within the AOI - clipped_polygon = grid_polygon.intersection(self.aoi) + clipped_polygon = grid_polygon.intersection(aoi_mercator) if not clipped_polygon.is_empty: if clipped_polygon.area < area_threshold: small_polygons.append(clipped_polygon) @@ -186,8 +199,14 @@ def splitBySquare(self, meters: int) -> FeatureCollection: polygons.append(small_polygon) break + # Transform all polygons back to WGS84 for final output + polygons_wgs84 = [ + shapely_transform(transformer_to_wgs84.transform, p) for p in polygons + ] + + # Convert polygons to GeoJSON FeatureCollection merged_geojson = FeatureCollection( - [Feature(geometry=mapping(p)) for p in polygons] + [Feature(geometry=mapping(p)) for p in polygons_wgs84] ) # Store the result in the instance variable and return it From 0cb463b50d907aca559b6c013612f074f98b0970 Mon Sep 17 00:00:00 2001 From: Pradip-p Date: Mon, 4 Nov 2024 11:40:30 +0545 Subject: [PATCH 2/2] refac: remove ## from import section --- src/backend/app/tasks/task_splitter.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/backend/app/tasks/task_splitter.py b/src/backend/app/tasks/task_splitter.py index 606f11a8..439f3a65 100644 --- a/src/backend/app/tasks/task_splitter.py +++ b/src/backend/app/tasks/task_splitter.py @@ -12,7 +12,6 @@ from shapely.ops import unary_union from pyproj import Transformer from shapely.ops import transform as shapely_transform -### # Instantiate logger