Spaces:
Running
Running
ui: add optional layers controls (waterways, forests, coastline)
Browse files
app.py
CHANGED
|
@@ -1,6 +1,7 @@
|
|
| 1 |
import subprocess
|
| 2 |
from pathlib import Path
|
| 3 |
import gradio as gr
|
|
|
|
| 4 |
|
| 5 |
ROOT = Path(__file__).resolve().parent
|
| 6 |
THEMES_DIR = ROOT / "themes"
|
|
@@ -16,6 +17,14 @@ APP_CSS = """
|
|
| 16 |
}
|
| 17 |
"""
|
| 18 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
# Preset distances (meters)
|
| 20 |
PRESET_DIST = {
|
| 21 |
"Small town": 3000,
|
|
@@ -111,9 +120,9 @@ def on_preset_change(preset, distance_m, buildings_enabled):
|
|
| 111 |
hint = format_distance_hint(preset, distance_m)
|
| 112 |
|
| 113 |
return (
|
| 114 |
-
gr.update(value=int(distance_m)),
|
| 115 |
gr.update(interactive=allowed, value=buildings_enabled), # buildings checkbox
|
| 116 |
-
gr.update(value=hint),
|
| 117 |
)
|
| 118 |
|
| 119 |
|
|
@@ -134,9 +143,9 @@ def on_distance_change(distance_m, preset, buildings_enabled):
|
|
| 134 |
hint = format_distance_hint(preset, distance_m)
|
| 135 |
|
| 136 |
return (
|
| 137 |
-
gr.update(value=preset),
|
| 138 |
gr.update(interactive=allowed, value=buildings_enabled), # buildings checkbox
|
| 139 |
-
gr.update(value=hint),
|
| 140 |
)
|
| 141 |
|
| 142 |
|
|
@@ -154,6 +163,9 @@ def generate(
|
|
| 154 |
orientation,
|
| 155 |
buildings_enabled,
|
| 156 |
railroads_enabled,
|
|
|
|
|
|
|
|
|
|
| 157 |
text_fade,
|
| 158 |
margins_enabled,
|
| 159 |
):
|
|
@@ -176,25 +188,40 @@ def generate(
|
|
| 176 |
orientation = "portrait"
|
| 177 |
|
| 178 |
cmd = [
|
| 179 |
-
"python",
|
| 180 |
-
"
|
| 181 |
-
"--
|
| 182 |
-
|
| 183 |
-
"--
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 184 |
]
|
| 185 |
|
| 186 |
# Buildings flag (only if allowed + enabled)
|
| 187 |
if buildings_enabled and buildings_allowed(preset, distance_m):
|
| 188 |
cmd += ["--buildings"]
|
| 189 |
|
| 190 |
-
# Railroads flag
|
| 191 |
if railroads_enabled:
|
| 192 |
cmd += ["--railroads"]
|
| 193 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 194 |
if text_fade:
|
| 195 |
cmd += ["--text-fade"]
|
| 196 |
|
| 197 |
-
# Margins/fading logic (NEW)
|
| 198 |
if not margins_enabled:
|
| 199 |
cmd += ["--no-margins"]
|
| 200 |
|
|
@@ -240,7 +267,7 @@ def generate(
|
|
| 240 |
|
| 241 |
try:
|
| 242 |
for line in proc.stdout:
|
| 243 |
-
line = line.rstrip()
|
| 244 |
if not line:
|
| 245 |
continue
|
| 246 |
status_lines.append(line)
|
|
@@ -291,15 +318,14 @@ def on_center_mode_change(mode):
|
|
| 291 |
|
| 292 |
with gr.Blocks(css=APP_CSS) as demo:
|
| 293 |
gr.Markdown(
|
| 294 |
-
|
| 295 |
-
|
| 296 |
-
|
| 297 |
-
|
| 298 |
-
|
| 299 |
-
|
| 300 |
)
|
| 301 |
|
| 302 |
-
|
| 303 |
center_mode = gr.Radio(
|
| 304 |
label="Center",
|
| 305 |
choices=["City", "Coordinates"],
|
|
@@ -318,7 +344,7 @@ with gr.Blocks(css=APP_CSS) as demo:
|
|
| 318 |
on_center_mode_change,
|
| 319 |
inputs=[center_mode],
|
| 320 |
outputs=[city, country, lat, lon],
|
| 321 |
-
queue=False, #
|
| 322 |
)
|
| 323 |
|
| 324 |
theme = gr.Dropdown(
|
|
@@ -347,26 +373,41 @@ with gr.Blocks(css=APP_CSS) as demo:
|
|
| 347 |
interactive=False, # will be enabled automatically when allowed
|
| 348 |
)
|
| 349 |
|
| 350 |
-
# NEW: railroads option
|
| 351 |
railroads = gr.Checkbox(
|
| 352 |
label="Railroads layer",
|
| 353 |
value=False,
|
| 354 |
)
|
| 355 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 356 |
distance_hint = gr.Markdown(format_distance_hint("City", PRESET_DIST["City"]))
|
| 357 |
|
| 358 |
preset.change(
|
| 359 |
on_preset_change,
|
| 360 |
inputs=[preset, distance, buildings],
|
| 361 |
outputs=[distance, buildings, distance_hint],
|
| 362 |
-
queue=False,
|
| 363 |
)
|
| 364 |
|
| 365 |
distance.change(
|
| 366 |
on_distance_change,
|
| 367 |
inputs=[distance, preset, buildings],
|
| 368 |
outputs=[preset, buildings, distance_hint],
|
| 369 |
-
queue=False,
|
| 370 |
)
|
| 371 |
|
| 372 |
with gr.Row():
|
|
@@ -381,24 +422,28 @@ with gr.Blocks(css=APP_CSS) as demo:
|
|
| 381 |
value="portrait",
|
| 382 |
)
|
| 383 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 384 |
text_fade = gr.Checkbox(
|
| 385 |
label="Fade under text (improves readability)",
|
| 386 |
-
value=True
|
| 387 |
)
|
| 388 |
|
| 389 |
margins = gr.Checkbox(
|
| 390 |
label="Margins & edge fading (coastal frame + inland fade)",
|
| 391 |
-
value=True
|
| 392 |
)
|
| 393 |
|
| 394 |
-
|
| 395 |
-
|
| 396 |
-
|
| 397 |
-
|
| 398 |
-
queue=False, # <- UI interaction: do NOT queue
|
| 399 |
-
)
|
| 400 |
-
|
| 401 |
-
fast_mode = gr.Checkbox(label="Fast mode (cap ~12km)", value=True)
|
| 402 |
|
| 403 |
btn = gr.Button("Generate")
|
| 404 |
status = gr.Textbox(label="Logs / Status", lines=18)
|
|
@@ -407,16 +452,26 @@ with gr.Blocks(css=APP_CSS) as demo:
|
|
| 407 |
btn.click(
|
| 408 |
generate,
|
| 409 |
inputs=[
|
| 410 |
-
center_mode,
|
| 411 |
-
|
| 412 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 413 |
buildings,
|
| 414 |
railroads,
|
|
|
|
|
|
|
|
|
|
| 415 |
text_fade,
|
| 416 |
margins,
|
| 417 |
],
|
| 418 |
outputs=[status, out],
|
| 419 |
-
# leave default queuing behavior for the heavy job
|
| 420 |
)
|
| 421 |
|
| 422 |
demo.launch()
|
|
|
|
| 1 |
import subprocess
|
| 2 |
from pathlib import Path
|
| 3 |
import gradio as gr
|
| 4 |
+
import re
|
| 5 |
|
| 6 |
ROOT = Path(__file__).resolve().parent
|
| 7 |
THEMES_DIR = ROOT / "themes"
|
|
|
|
| 17 |
}
|
| 18 |
"""
|
| 19 |
|
| 20 |
+
# ---- ANSI cleanup (prevents weird \x1b[A logs from tqdm) ----
|
| 21 |
+
ANSI_ESCAPE = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
|
| 22 |
+
|
| 23 |
+
|
| 24 |
+
def strip_ansi(s: str) -> str:
|
| 25 |
+
return ANSI_ESCAPE.sub("", s)
|
| 26 |
+
|
| 27 |
+
|
| 28 |
# Preset distances (meters)
|
| 29 |
PRESET_DIST = {
|
| 30 |
"Small town": 3000,
|
|
|
|
| 120 |
hint = format_distance_hint(preset, distance_m)
|
| 121 |
|
| 122 |
return (
|
| 123 |
+
gr.update(value=int(distance_m)), # distance slider
|
| 124 |
gr.update(interactive=allowed, value=buildings_enabled), # buildings checkbox
|
| 125 |
+
gr.update(value=hint), # hint markdown
|
| 126 |
)
|
| 127 |
|
| 128 |
|
|
|
|
| 143 |
hint = format_distance_hint(preset, distance_m)
|
| 144 |
|
| 145 |
return (
|
| 146 |
+
gr.update(value=preset), # preset dropdown
|
| 147 |
gr.update(interactive=allowed, value=buildings_enabled), # buildings checkbox
|
| 148 |
+
gr.update(value=hint), # hint markdown
|
| 149 |
)
|
| 150 |
|
| 151 |
|
|
|
|
| 163 |
orientation,
|
| 164 |
buildings_enabled,
|
| 165 |
railroads_enabled,
|
| 166 |
+
waterways_enabled,
|
| 167 |
+
forests_enabled,
|
| 168 |
+
coastline_enabled,
|
| 169 |
text_fade,
|
| 170 |
margins_enabled,
|
| 171 |
):
|
|
|
|
| 188 |
orientation = "portrait"
|
| 189 |
|
| 190 |
cmd = [
|
| 191 |
+
"python",
|
| 192 |
+
"create_map_poster.py",
|
| 193 |
+
"--theme",
|
| 194 |
+
theme,
|
| 195 |
+
"--distance",
|
| 196 |
+
str(int(distance_m)),
|
| 197 |
+
"--format",
|
| 198 |
+
map_format,
|
| 199 |
+
"--orientation",
|
| 200 |
+
orientation,
|
| 201 |
]
|
| 202 |
|
| 203 |
# Buildings flag (only if allowed + enabled)
|
| 204 |
if buildings_enabled and buildings_allowed(preset, distance_m):
|
| 205 |
cmd += ["--buildings"]
|
| 206 |
|
| 207 |
+
# Railroads flag
|
| 208 |
if railroads_enabled:
|
| 209 |
cmd += ["--railroads"]
|
| 210 |
|
| 211 |
+
# Optional layers
|
| 212 |
+
if waterways_enabled:
|
| 213 |
+
cmd += ["--waterways"]
|
| 214 |
+
|
| 215 |
+
if forests_enabled:
|
| 216 |
+
cmd += ["--forests"]
|
| 217 |
+
|
| 218 |
+
# Coastline detection (ocean fill + coastal frame logic in script)
|
| 219 |
+
if coastline_enabled:
|
| 220 |
+
cmd += ["--coastline"]
|
| 221 |
+
|
| 222 |
if text_fade:
|
| 223 |
cmd += ["--text-fade"]
|
| 224 |
|
|
|
|
| 225 |
if not margins_enabled:
|
| 226 |
cmd += ["--no-margins"]
|
| 227 |
|
|
|
|
| 267 |
|
| 268 |
try:
|
| 269 |
for line in proc.stdout:
|
| 270 |
+
line = strip_ansi(line).rstrip()
|
| 271 |
if not line:
|
| 272 |
continue
|
| 273 |
status_lines.append(line)
|
|
|
|
| 318 |
|
| 319 |
with gr.Blocks(css=APP_CSS) as demo:
|
| 320 |
gr.Markdown(
|
| 321 |
+
"""
|
| 322 |
+
# MapToPoster – Gradio
|
| 323 |
+
Original project by Ankur (MapToPoster)
|
| 324 |
+
Based on the open-source repository: https://github.com/originalankur/maptoposter
|
| 325 |
+
Many thanks for the original work and inspiration.
|
| 326 |
+
"""
|
| 327 |
)
|
| 328 |
|
|
|
|
| 329 |
center_mode = gr.Radio(
|
| 330 |
label="Center",
|
| 331 |
choices=["City", "Coordinates"],
|
|
|
|
| 344 |
on_center_mode_change,
|
| 345 |
inputs=[center_mode],
|
| 346 |
outputs=[city, country, lat, lon],
|
| 347 |
+
queue=False, # UI interaction: do NOT queue
|
| 348 |
)
|
| 349 |
|
| 350 |
theme = gr.Dropdown(
|
|
|
|
| 373 |
interactive=False, # will be enabled automatically when allowed
|
| 374 |
)
|
| 375 |
|
|
|
|
| 376 |
railroads = gr.Checkbox(
|
| 377 |
label="Railroads layer",
|
| 378 |
value=False,
|
| 379 |
)
|
| 380 |
|
| 381 |
+
# Optional layers
|
| 382 |
+
waterways = gr.Checkbox(
|
| 383 |
+
label="Waterways (rivers/streams/brooks…)",
|
| 384 |
+
value=True,
|
| 385 |
+
)
|
| 386 |
+
|
| 387 |
+
forests = gr.Checkbox(
|
| 388 |
+
label="Forests (wood/forest only)",
|
| 389 |
+
value=True,
|
| 390 |
+
)
|
| 391 |
+
|
| 392 |
+
coastline = gr.Checkbox(
|
| 393 |
+
label="Coastline detection (ocean fill + coastal frame)",
|
| 394 |
+
value=True,
|
| 395 |
+
)
|
| 396 |
+
|
| 397 |
distance_hint = gr.Markdown(format_distance_hint("City", PRESET_DIST["City"]))
|
| 398 |
|
| 399 |
preset.change(
|
| 400 |
on_preset_change,
|
| 401 |
inputs=[preset, distance, buildings],
|
| 402 |
outputs=[distance, buildings, distance_hint],
|
| 403 |
+
queue=False,
|
| 404 |
)
|
| 405 |
|
| 406 |
distance.change(
|
| 407 |
on_distance_change,
|
| 408 |
inputs=[distance, preset, buildings],
|
| 409 |
outputs=[preset, buildings, distance_hint],
|
| 410 |
+
queue=False,
|
| 411 |
)
|
| 412 |
|
| 413 |
with gr.Row():
|
|
|
|
| 422 |
value="portrait",
|
| 423 |
)
|
| 424 |
|
| 425 |
+
map_format.change(
|
| 426 |
+
on_format_change,
|
| 427 |
+
inputs=[map_format],
|
| 428 |
+
outputs=[orientation],
|
| 429 |
+
queue=False,
|
| 430 |
+
)
|
| 431 |
+
|
| 432 |
+
with gr.Row():
|
| 433 |
text_fade = gr.Checkbox(
|
| 434 |
label="Fade under text (improves readability)",
|
| 435 |
+
value=True,
|
| 436 |
)
|
| 437 |
|
| 438 |
margins = gr.Checkbox(
|
| 439 |
label="Margins & edge fading (coastal frame + inland fade)",
|
| 440 |
+
value=True,
|
| 441 |
)
|
| 442 |
|
| 443 |
+
fast_mode = gr.Checkbox(
|
| 444 |
+
label="Fast mode (cap ~12km)",
|
| 445 |
+
value=True,
|
| 446 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
| 447 |
|
| 448 |
btn = gr.Button("Generate")
|
| 449 |
status = gr.Textbox(label="Logs / Status", lines=18)
|
|
|
|
| 452 |
btn.click(
|
| 453 |
generate,
|
| 454 |
inputs=[
|
| 455 |
+
center_mode,
|
| 456 |
+
city,
|
| 457 |
+
country,
|
| 458 |
+
lat,
|
| 459 |
+
lon,
|
| 460 |
+
theme,
|
| 461 |
+
preset,
|
| 462 |
+
distance,
|
| 463 |
+
fast_mode,
|
| 464 |
+
map_format,
|
| 465 |
+
orientation,
|
| 466 |
buildings,
|
| 467 |
railroads,
|
| 468 |
+
waterways,
|
| 469 |
+
forests,
|
| 470 |
+
coastline,
|
| 471 |
text_fade,
|
| 472 |
margins,
|
| 473 |
],
|
| 474 |
outputs=[status, out],
|
|
|
|
| 475 |
)
|
| 476 |
|
| 477 |
demo.launch()
|