Spaces:
Running
Running
fix: handle coordinate swapping and fix 'Shell empty' geometry error
Browse files- app.py +8 -4
- create_map_poster.py +16 -6
app.py
CHANGED
|
@@ -194,10 +194,14 @@ def generate_poster(
|
|
| 194 |
cmp.THEME = cmp.load_theme(theme_name)
|
| 195 |
|
| 196 |
if location_mode == "自定义坐标" or location_mode == "Custom Coordinates":
|
| 197 |
-
|
| 198 |
-
|
| 199 |
-
|
| 200 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 201 |
display_city = custom_city_name if custom_city_name else ""
|
| 202 |
display_country = custom_country_name if custom_country_name else ""
|
| 203 |
|
|
|
|
| 194 |
cmp.THEME = cmp.load_theme(theme_name)
|
| 195 |
|
| 196 |
if location_mode == "自定义坐标" or location_mode == "Custom Coordinates":
|
| 197 |
+
lat_val = float(custom_lat)
|
| 198 |
+
lon_val = float(custom_lon)
|
| 199 |
+
|
| 200 |
+
# Basic validation: Latitude must be between -90 and 90
|
| 201 |
+
if lat_val < -90 or lat_val > 90:
|
| 202 |
+
return None, f"❌ 纬度超出范围 (-90 到 90)。你是否填反了经纬度?(当前填入: {lat_val})"
|
| 203 |
+
|
| 204 |
+
coords = (lat_val, lon_val)
|
| 205 |
display_city = custom_city_name if custom_city_name else ""
|
| 206 |
display_country = custom_country_name if custom_country_name else ""
|
| 207 |
|
create_map_poster.py
CHANGED
|
@@ -343,8 +343,8 @@ def create_poster(
|
|
| 343 |
delta_lat = dist_ns / 111320.0
|
| 344 |
delta_lon = dist_ew / (111320.0 * math.cos(math.radians(lat)))
|
| 345 |
|
| 346 |
-
north, south = lat + delta_lat, lat - delta_lat
|
| 347 |
-
west, east = lon - delta_lon, lon + delta_lon
|
| 348 |
|
| 349 |
bbox = (west, south, east, north)
|
| 350 |
|
|
@@ -396,9 +396,13 @@ def create_poster(
|
|
| 396 |
water.geometry.type.isin(["Polygon", "MultiPolygon"])
|
| 397 |
]
|
| 398 |
if not water_polys.empty:
|
|
|
|
|
|
|
| 399 |
water_polys.geometry = water_polys.geometry.simplify(
|
| 400 |
tolerance=0.00001, preserve_topology=True
|
| 401 |
)
|
|
|
|
|
|
|
| 402 |
|
| 403 |
# Water Lines (Rivers, Streams represented as lines)
|
| 404 |
water_lines = water[
|
|
@@ -427,10 +431,16 @@ def create_poster(
|
|
| 427 |
parks = features[park_mask]
|
| 428 |
if not parks.empty:
|
| 429 |
parks = parks[parks.geometry.type.isin(["Polygon", "MultiPolygon"])]
|
| 430 |
-
#
|
| 431 |
-
|
| 432 |
-
|
| 433 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 434 |
else:
|
| 435 |
parks = None # No park features found
|
| 436 |
else:
|
|
|
|
| 343 |
delta_lat = dist_ns / 111320.0
|
| 344 |
delta_lon = dist_ew / (111320.0 * math.cos(math.radians(lat)))
|
| 345 |
|
| 346 |
+
north, south = max(lat + delta_lat, lat - delta_lat), min(lat + delta_lat, lat - delta_lat)
|
| 347 |
+
west, east = min(lon - delta_lon, lon + delta_lon), max(lon - delta_lon, lon + delta_lon)
|
| 348 |
|
| 349 |
bbox = (west, south, east, north)
|
| 350 |
|
|
|
|
| 396 |
water.geometry.type.isin(["Polygon", "MultiPolygon"])
|
| 397 |
]
|
| 398 |
if not water_polys.empty:
|
| 399 |
+
# Fix invalid geometries if any, then simplify
|
| 400 |
+
water_polys.geometry = water_polys.geometry.apply(lambda g: g.buffer(0) if not g.is_valid else g)
|
| 401 |
water_polys.geometry = water_polys.geometry.simplify(
|
| 402 |
tolerance=0.00001, preserve_topology=True
|
| 403 |
)
|
| 404 |
+
# Filter out any that became empty after simplification
|
| 405 |
+
water_polys = water_polys[~water_polys.geometry.is_empty]
|
| 406 |
|
| 407 |
# Water Lines (Rivers, Streams represented as lines)
|
| 408 |
water_lines = water[
|
|
|
|
| 431 |
parks = features[park_mask]
|
| 432 |
if not parks.empty:
|
| 433 |
parks = parks[parks.geometry.type.isin(["Polygon", "MultiPolygon"])]
|
| 434 |
+
# Fix invalid geometries, then simplify
|
| 435 |
+
if not parks.empty:
|
| 436 |
+
parks.geometry = parks.geometry.apply(lambda g: g.buffer(0) if not g.is_valid else g)
|
| 437 |
+
parks.geometry = parks.geometry.simplify(
|
| 438 |
+
tolerance=0.00001, preserve_topology=True
|
| 439 |
+
)
|
| 440 |
+
# Filter empty
|
| 441 |
+
parks = parks[~parks.geometry.is_empty]
|
| 442 |
+
else:
|
| 443 |
+
parks = None
|
| 444 |
else:
|
| 445 |
parks = None # No park features found
|
| 446 |
else:
|