Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,8 @@ python create_map_poster.py --city <city> --country <country> [options]
| **OPTIONAL:** `--all-themes` | | Generate posters for all available themes | |
| **OPTIONAL:** `--width` | `-W` | Image width in inches | 12 (max: 20) |
| **OPTIONAL:** `--height` | `-H` | Image height in inches | 16 (max: 20) |
| **OPTIONAL:** `--quality` | `-q` | Output DPI preset for png: `low` (150), `standard` (300), `high` (400), `ultra` (600) | standard |
| **OPTIONAL:** `--dpi` | | Explicit output DPI for png (overrides `--quality`) | 300 |

### Multilingual Support - i18n

Expand Down Expand Up @@ -107,7 +109,7 @@ python create_map_poster.py -c "Dubai" -C "UAE" -dc "دبي" -dC "الإمارا

### Resolution Guide (300 DPI)

Use these values for `-W` and `-H` to target specific resolutions:
Use these values for `-W` and `-H` to target specific resolutions (pixels = inches x DPI; change DPI with `--quality` or `--dpi`):

| Target | Resolution (px) | Inches (-W / -H) |
|--------|-----------------|------------------|
Expand Down Expand Up @@ -396,4 +398,4 @@ G = ox.graph_from_point(point, dist=dist, network_type='walk') # pedestrian
- Large `dist` values (>20km) = slow downloads + memory heavy
- Cache coordinates locally to avoid Nominatim rate limits
- Use `network_type='drive'` instead of `'all'` for faster renders
- Reduce `dpi` from 300 to 150 for quick previews
- Use `--quality low` (150 DPI) for quick previews
42 changes: 41 additions & 1 deletion create_map_poster.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ class CacheError(Exception):
FONTS_DIR = "fonts"
POSTERS_DIR = "posters"

# Output DPI presets for --quality (applies to png only; svg/pdf are vector)
QUALITY_DPI = {
"low": 150,
"standard": 300,
"high": 400,
"ultra": 600,
}

FILE_ENCODING = "utf-8"

FONTS = load_fonts()
Expand Down Expand Up @@ -493,6 +501,7 @@ def create_poster(
display_city=None,
display_country=None,
fonts=None,
dpi=300,
):
"""
Generate a complete map poster with roads, water, parks, and typography.
Expand All @@ -511,6 +520,7 @@ def create_poster(
height: Poster height in inches (default: 16)
country_label: Optional override for country text on poster
_name_label: Optional override for city name (unused, reserved for future use)
dpi: Output resolution in dots per inch (png only; default: 300)

Raises:
RuntimeError: If street network data cannot be retrieved
Expand Down Expand Up @@ -764,7 +774,7 @@ def create_poster(

# DPI matters mainly for raster formats
if fmt == "png":
save_kwargs["dpi"] = 300
save_kwargs["dpi"] = dpi

plt.savefig(output_file, format=fmt, **save_kwargs)

Expand Down Expand Up @@ -928,6 +938,24 @@ def list_themes():
default=16,
help="Image height in inches (default: 16, max: 20)",
)
quality_group = parser.add_mutually_exclusive_group()
quality_group.add_argument(
"--quality",
"-q",
type=str,
default="standard",
choices=list(QUALITY_DPI.keys()),
help=(
"Output quality preset for png: "
+ ", ".join(f"{k} ({v} DPI)" for k, v in QUALITY_DPI.items())
+ " (default: standard)"
),
)
quality_group.add_argument(
"--dpi",
type=int,
help="Explicit output DPI for png (overrides --quality)",
)
parser.add_argument(
"--list-themes", action="store_true", help="List all available themes"
)
Expand Down Expand Up @@ -986,6 +1014,17 @@ def list_themes():
)
args.height = 20.0

# Resolve output DPI (explicit --dpi wins over --quality preset)
dpi = args.dpi if args.dpi is not None else QUALITY_DPI[args.quality]
if dpi <= 0:
print(f"Error: --dpi must be a positive integer, got {dpi}.")
sys.exit(1)
if args.format == "png":
print(
f"Output: {args.width}x{args.height} in @ {dpi} DPI "
f"(~{round(args.width * dpi)}x{round(args.height * dpi)} px)"
)

available_themes = get_available_themes()
if not available_themes:
print("No themes found in 'themes/' directory.")
Expand Down Expand Up @@ -1037,6 +1076,7 @@ def list_themes():
display_city=args.display_city,
display_country=args.display_country,
fonts=custom_fonts,
dpi=dpi,
)

print("\n" + "=" * 50)
Expand Down
15 changes: 13 additions & 2 deletions test/all_variations.sh
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,18 @@ uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -W 12.8 -H 7.2
echo "A4 Print (8.3x11.7)"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -W 8.3 -H 11.7

# 6. Distance Guide Variations
# 6. Quality / DPI Variations
echo "--- Quality / DPI Variations ---"
echo "Low quality preset (150 DPI)"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -q low

echo "Ultra quality preset (600 DPI)"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" --quality ultra

echo "Explicit DPI with custom size"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -W 8.3 -H 11.7 --dpi 200

# 7. Distance Guide Variations
echo "--- Distance Guide Variations ---"
echo "Small/Dense focal (5000m)"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -d 5000
Expand All @@ -86,7 +97,7 @@ uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -d 10000
echo "Large metro view (default 18000m)"
uv run python3 create_map_poster.py -c "Bengaluru" -C "India" -d 18000

# 7. Utility flags
# 8. Utility flags
echo "--- Utility Flags ---"
echo "Listing themes"
uv run python3 create_map_poster.py --list-themes
Expand Down