File size: 2,525 Bytes
008947a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
"""MapToPoster command-line interface."""

from __future__ import annotations

import argparse
from pathlib import Path

from .export import generate_output_filename
from .geocoding import GeocodingService
from .models import (
    ExportConfig,
    LayoutConfig,
    LayoutPreset,
    MapConfig,
    OutputFormat,
    PosterConfig,
    PosterSize,
    SizePreset,
    TypographyConfig,
)
from .service import PosterService
from .themes import list_themes, load_style
from .viewport import create_viewport


def build_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(description="Turn any place into a map poster.")
    parser.add_argument("--city", "-c")
    parser.add_argument("--country", "-C", default="")
    parser.add_argument("--theme", "-t", default="feature_based", choices=list_themes())
    parser.add_argument("--distance", "-d", type=float, default=10_000)
    parser.add_argument("--format", "-f", choices=[item.value for item in OutputFormat], default="png")
    parser.add_argument("--layout", choices=[item.value for item in LayoutPreset], default="classic")
    parser.add_argument("--list-themes", action="store_true")
    parser.add_argument("--output", type=Path)
    return parser


def main() -> None:
    args = build_parser().parse_args()
    if args.list_themes:
        print("\n".join(list_themes()))
        return
    if not args.city:
        raise SystemExit("--city is required unless --list-themes is used")

    query = f"{args.city}, {args.country}" if args.country else args.city
    results = GeocodingService().search(query, limit=1)
    if not results:
        raise SystemExit(f"Location not found: {query}")
    location = results[0]
    size = PosterSize(SizePreset.THREE_FOUR)
    width, height = size.dimensions
    config = PosterConfig(
        location=location,
        map=MapConfig(create_viewport(location.coordinate, args.distance, width, height)),
        style=load_style(args.theme),
        typography=TypographyConfig(title=args.city, subtitle=args.country),
        layout=LayoutConfig(LayoutPreset(args.layout)),
        size=size,
    )
    service = PosterService()
    reference = service.prepare_map(config)
    output = args.output or Path(generate_output_filename(args.city, args.theme, OutputFormat(args.format)))
    output.parent.mkdir(parents=True, exist_ok=True)
    output.write_bytes(service.export_poster(reference, config, ExportConfig(OutputFormat(args.format))))
    print(output)


if __name__ == "__main__":
    main()