Skip to content

Commit

Permalink
Merge pull request #189 from hotosm/feat/split-task-area
Browse files Browse the repository at this point in the history
Feat: Improve small polygon merging logic in splitBySquare method
  • Loading branch information
nrjadkry authored Sep 3, 2024
2 parents 5b9a3c0 + 962c676 commit ddc2080
Showing 1 changed file with 32 additions and 23 deletions.
55 changes: 32 additions & 23 deletions src/backend/app/tasks/splitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,30 +151,39 @@ def splitBySquare(self, meters: int) -> FeatureCollection:
polygons.append(clipped_polygon)

for small_polygon in small_polygons:
adjacent_polygons = [
large_polygon
for large_polygon in polygons
if small_polygon.touches(large_polygon)
]
if adjacent_polygons:
# Get the adjacent polygon with the minimum area
nearest_small_polygon = min(adjacent_polygons, key=lambda p: p.area)

# Merge the small polygon with the nearest large polygon
merged_polygon = unary_union([small_polygon, nearest_small_polygon])

if merged_polygon.geom_type == "MultiPolygon":
# TODO we need merge Multipolygon into single polygon later....
log.warning("Found MultiPolygon, converting to simple polygon...")
while True:
adjacent_polygons = [
large_polygon
for large_polygon in polygons
if small_polygon.touches(large_polygon)
]
if adjacent_polygons:
# Get the adjacent polygon with the minimum area
nearest_polygon = min(adjacent_polygons, key=lambda p: p.area)

# Merge the small polygon with the nearest large polygon
merged_polygon = unary_union([small_polygon, nearest_polygon])

if merged_polygon.geom_type == "MultiPolygon":
# Handle MultiPolygon by adding the original small polygon back
log.warning(
"Found MultiPolygon, adding original small polygon..."
)
polygons.append(small_polygon)
break

# Remove both the small polygon and the nearest large polygon
polygons.remove(nearest_polygon)
small_polygon = merged_polygon

# Check if the merged polygon is greater than the area threshold
if small_polygon.area >= area_threshold:
polygons.append(small_polygon)
break
else:
# If no adjacent polygon is found, add the small polygon as is
polygons.append(small_polygon)
# Option 1: Convert to convex hull (simple polygon)
# merged_polygon = merged_polygon.convex_hull
# Remove both the small polygon and the nearest large polygon
polygons.remove(nearest_small_polygon)
polygons.append(merged_polygon)
else:
# If no adjacent polygon is found, add the small polygon as is
polygons.append(small_polygon)
break

merged_geojson = FeatureCollection(
[Feature(geometry=mapping(p)) for p in polygons]
Expand Down

0 comments on commit ddc2080

Please sign in to comment.