Spaces:
Running
Running
province added
Browse files- app.py +28 -2
- cities_data.py +8 -1
- create_map_poster.py +19 -3
app.py
CHANGED
|
@@ -189,18 +189,44 @@ def generate_poster(
|
|
| 189 |
else city_dropdown
|
| 190 |
)
|
| 191 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 192 |
if not selected_location:
|
| 193 |
return None, "❌ 请选择城市或区县名称"
|
| 194 |
|
| 195 |
if not selected_country:
|
| 196 |
return None, "❌ 请选择国家"
|
| 197 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 198 |
# Determine display names based on poster_lang
|
| 199 |
lang_code = "en" if poster_lang == "English" else "cn"
|
| 200 |
|
| 201 |
if selected_country == "中国" and lang_code == "cn":
|
|
|
|
|
|
|
|
|
|
| 202 |
# Hierarchical logic for China (Chinese language)
|
| 203 |
-
|
| 204 |
# Case 3 & 4: District selected
|
| 205 |
display_city = district_dropdown
|
| 206 |
if province == city_dropdown:
|
|
@@ -265,7 +291,7 @@ def generate_poster(
|
|
| 265 |
display_city, # Pass translated names for display
|
| 266 |
display_country,
|
| 267 |
coords,
|
| 268 |
-
|
| 269 |
output_file,
|
| 270 |
output_format,
|
| 271 |
width=width,
|
|
|
|
| 189 |
else city_dropdown
|
| 190 |
)
|
| 191 |
|
| 192 |
+
# Detect if we are selecting an entire province
|
| 193 |
+
is_whole_province = False
|
| 194 |
+
if selected_country == "中国":
|
| 195 |
+
p_adcode = get_china_adcode(province)
|
| 196 |
+
if selected_location == province and p_adcode:
|
| 197 |
+
# Check if this province has 'city' children or 'district' children
|
| 198 |
+
from cities_data import _load_china_info
|
| 199 |
+
info = _load_china_info()
|
| 200 |
+
p_entry = info.get(str(p_adcode))
|
| 201 |
+
if p_entry and p_entry.get("childrenNum", 0) > 0:
|
| 202 |
+
if p_entry["children"][0].get("level") == "city":
|
| 203 |
+
is_whole_province = True
|
| 204 |
+
|
| 205 |
if not selected_location:
|
| 206 |
return None, "❌ 请选择城市或区县名称"
|
| 207 |
|
| 208 |
if not selected_country:
|
| 209 |
return None, "❌ 请选择国家"
|
| 210 |
|
| 211 |
+
# For whole province, we might want to override the distance if it's too small
|
| 212 |
+
actual_distance = distance
|
| 213 |
+
if is_whole_province:
|
| 214 |
+
# A province is much larger than a city. Default 10km is way too small.
|
| 215 |
+
# We'll use a larger default or just trust the user if they've slid it up,
|
| 216 |
+
# but let's ensure it's at least 150km for a province.
|
| 217 |
+
if distance < 100000:
|
| 218 |
+
actual_distance = 200000 # 200km default for province
|
| 219 |
+
print(f"Whole province detected. Increasing distance to {actual_distance}m")
|
| 220 |
+
|
| 221 |
# Determine display names based on poster_lang
|
| 222 |
lang_code = "en" if poster_lang == "English" else "cn"
|
| 223 |
|
| 224 |
if selected_country == "中国" and lang_code == "cn":
|
| 225 |
+
if is_whole_province:
|
| 226 |
+
display_city = province
|
| 227 |
+
display_country = "中国"
|
| 228 |
# Hierarchical logic for China (Chinese language)
|
| 229 |
+
elif district_dropdown and district_dropdown != city_dropdown:
|
| 230 |
# Case 3 & 4: District selected
|
| 231 |
display_city = district_dropdown
|
| 232 |
if province == city_dropdown:
|
|
|
|
| 291 |
display_city, # Pass translated names for display
|
| 292 |
display_country,
|
| 293 |
coords,
|
| 294 |
+
actual_distance,
|
| 295 |
output_file,
|
| 296 |
output_format,
|
| 297 |
width=width,
|
cities_data.py
CHANGED
|
@@ -1156,6 +1156,11 @@ def get_cities(country_name, province_name, lang="en"):
|
|
| 1156 |
p_entry = info.get(str(p_adcode))
|
| 1157 |
if p_entry:
|
| 1158 |
choices = []
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1159 |
for c in p_entry.get("children", []):
|
| 1160 |
name = c["name"]
|
| 1161 |
display = translate(name, lang)
|
|
@@ -1168,7 +1173,9 @@ def get_cities(country_name, province_name, lang="en"):
|
|
| 1168 |
and p_entry["children"][0].get("level") == "district"
|
| 1169 |
):
|
| 1170 |
return [(translate(province_name, lang), province_name)]
|
| 1171 |
-
|
|
|
|
|
|
|
| 1172 |
|
| 1173 |
province_key = province_name
|
| 1174 |
if country_key in CITIES:
|
|
|
|
| 1156 |
p_entry = info.get(str(p_adcode))
|
| 1157 |
if p_entry:
|
| 1158 |
choices = []
|
| 1159 |
+
|
| 1160 |
+
# Add "Whole Province" option
|
| 1161 |
+
whole_province_display = "整个省" if lang == "cn" else "Whole Province"
|
| 1162 |
+
choices.append((whole_province_display, province_name))
|
| 1163 |
+
|
| 1164 |
for c in p_entry.get("children", []):
|
| 1165 |
name = c["name"]
|
| 1166 |
display = translate(name, lang)
|
|
|
|
| 1173 |
and p_entry["children"][0].get("level") == "district"
|
| 1174 |
):
|
| 1175 |
return [(translate(province_name, lang), province_name)]
|
| 1176 |
+
|
| 1177 |
+
# Keep "Whole Province" at top, then sorted cities
|
| 1178 |
+
return [choices[0]] + sorted(choices[1:], key=lambda x: x[0])
|
| 1179 |
|
| 1180 |
province_key = province_name
|
| 1181 |
if country_key in CITIES:
|
create_map_poster.py
CHANGED
|
@@ -327,8 +327,14 @@ def create_poster(
|
|
| 327 |
# Progress bar for data fetching
|
| 328 |
# Note: tqdm writes to stderr, we will just yield status updates for the UI
|
| 329 |
|
| 330 |
-
# 1. Fetch Street Network
|
| 331 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 332 |
|
| 333 |
import math
|
| 334 |
|
|
@@ -340,7 +346,17 @@ def create_poster(
|
|
| 340 |
west, east = lon - delta_lon, lon + delta_lon
|
| 341 |
|
| 342 |
bbox = (west, south, east, north)
|
| 343 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 344 |
|
| 345 |
# 2. Fetch Water and Parks in one request
|
| 346 |
yield "Downloading features (water, parks)..."
|
|
|
|
| 327 |
# Progress bar for data fetching
|
| 328 |
# Note: tqdm writes to stderr, we will just yield status updates for the UI
|
| 329 |
|
| 330 |
+
# 1. Fetch Street Network
|
| 331 |
+
# Detect if we are doing a "Whole Province" (large area)
|
| 332 |
+
# If the bounding box is very large, we should limit the road types to avoid timeouts
|
| 333 |
+
is_large_area = False
|
| 334 |
+
if dist > 50000: # Over 50km half-width is likely a province or large region
|
| 335 |
+
is_large_area = True
|
| 336 |
+
print(f"Large area detected (dist={dist}m). Fetching major roads only.")
|
| 337 |
+
yield "Large region detected. Fetching major roads only to avoid timeout..."
|
| 338 |
|
| 339 |
import math
|
| 340 |
|
|
|
|
| 346 |
west, east = lon - delta_lon, lon + delta_lon
|
| 347 |
|
| 348 |
bbox = (west, south, east, north)
|
| 349 |
+
|
| 350 |
+
if is_large_area:
|
| 351 |
+
# Use custom filter for major roads only
|
| 352 |
+
custom_filter = (
|
| 353 |
+
'["highway"~"motorway|trunk|primary|secondary"]'
|
| 354 |
+
)
|
| 355 |
+
yield "Downloading major road network..."
|
| 356 |
+
G = ox.graph_from_bbox(bbox, custom_filter=custom_filter, network_type="drive")
|
| 357 |
+
else:
|
| 358 |
+
yield "Downloading street network..."
|
| 359 |
+
G = ox.graph_from_bbox(bbox, network_type="all")
|
| 360 |
|
| 361 |
# 2. Fetch Water and Parks in one request
|
| 362 |
yield "Downloading features (water, parks)..."
|