From 9aa3f4cc4ade632d1774b8477e39b605e42ecf55 Mon Sep 17 00:00:00 2001 From: Will Date: Thu, 15 Aug 2024 19:42:09 -0400 Subject: [PATCH] Updating write_tags file and adding basic CLI --- .gitignore | 1 + requirements.txt | 2 +- scripts/write_tags.py | 20 +++++----- src/overturetoosm/__main__.py | 6 +++ src/overturetoosm/cli.py | 70 +++++++++++++++++++++++++++++++++++ src/overturetoosm/objects.py | 2 +- 6 files changed, 90 insertions(+), 11 deletions(-) create mode 100644 src/overturetoosm/__main__.py create mode 100644 src/overturetoosm/cli.py diff --git a/.gitignore b/.gitignore index fabf65c..fb08b32 100644 --- a/.gitignore +++ b/.gitignore @@ -46,6 +46,7 @@ pip-delete-this-directory.txt # Temporary files *scratch*.py scripts/test*.py +scripts/out*.geojson .pypirc .coverage .vscode diff --git a/requirements.txt b/requirements.txt index 5c8af12..6c2258b 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,2 +1,2 @@ -pydantic>=2.8.2 +pydantic>=2.8.0 pytest>=8.3.2 diff --git a/scripts/write_tags.py b/scripts/write_tags.py index 00e8b59..cf1c250 100644 --- a/scripts/write_tags.py +++ b/scripts/write_tags.py @@ -1,17 +1,19 @@ import json +import re with open("scripts/tags.json", "r+", encoding="utf-8") as f: tags = json.load(f) tags_filled = {k: v for k, v in tags.items() if v} -with open("src/overturetoosm/resources.py", "w+", encoding="utf-8") as f: - f.write( - f'''"""A mapping of Overture tags to OSM tags.""" +new_dict_str = json.dumps(tags_filled, indent=4).replace(":", ": ") +pattern = r"places_tags: Dict\[str, Dict\[str, str\]\]\s*=\s*\{.*\}" +replacement = f"places_tags: Dict[str, Dict[str, str]] = {new_dict_str}" + +with open("src/overturetoosm/resources.py", "r", encoding="utf-8") as f: + contents = f.read() -tags: dict[str, dict[str, str]] = {json.dumps(tags_filled, indent=4)} -"""dict[str, dict[str, str]]: A mapping of Overture to OSM tags, -excluding blank values. This is downstream from the `scripts/tag.json` -file.""" -''' - ) +replace = re.sub(pattern, replacement, contents, flags=re.DOTALL) + +with open("src/overturetoosm/resources.py", "w+", encoding="utf-8") as f: + f.write(replace) diff --git a/src/overturetoosm/__main__.py b/src/overturetoosm/__main__.py new file mode 100644 index 0000000..9637633 --- /dev/null +++ b/src/overturetoosm/__main__.py @@ -0,0 +1,6 @@ +"""Entrypoint for the package.""" + +from .cli import main + +if __name__ == "__main__": + main() diff --git a/src/overturetoosm/cli.py b/src/overturetoosm/cli.py new file mode 100644 index 0000000..1926953 --- /dev/null +++ b/src/overturetoosm/cli.py @@ -0,0 +1,70 @@ +"""Command line interface for the overturetoosm package.""" + +import argparse +import json +from typing import Dict + +from . import process_address, process_building, process_geojson, process_place + + +def parse_kwargs(pairs) -> Dict[str, str]: + """Parse key-value pairs into a dictionary.""" + kwargs = {} + for pair in pairs: + key, value = pair.split("=") + kwargs[key] = value + return kwargs + + +def main(): + """Configure the argument parser for the CLI.""" + parser = argparse.ArgumentParser( + description="Convert Overture data to the OSM schema in the GeoJSON format." + ) + + parser.add_argument( + "-i", "--input", required=True, help="Path to the input GeoJSON file" + ) + out = parser.add_argument_group("Output options") + output_group = out.add_mutually_exclusive_group(required=True) + output_group.add_argument("-o", "--output", help="Path to the output GeoJSON file") + output_group.add_argument( + "--in-place", + action="store_true", + help="Convert the input file in place (overwrites the original file)", + ) + + parser.add_argument( + "-t", + "--type", + choices=["place", "building", "address"], + type=str, + required=True, + help="Type of feature to convert (place, building, or address)", + ) + parser.add_argument("kwargs", nargs="*", help="Additional arguments") + + args = parser.parse_args() + + kwargs = parse_kwargs(args.kwargs) + + fx_dict = { + "place": process_place, + "building": process_building, + "address": process_address, + } + + with open(args.input, "r", encoding="utf-8") as f: + contents: dict = json.load(f) + conf = float(kwargs.get("confidence", 0)) + kwargs.pop("confidence", None) + geojson = process_geojson( + contents, fx=fx_dict.get(args.type, None), confidence=conf, options=kwargs + ) + + if args.in_place: + with open(args.input, "w+", encoding="utf-8") as f: + json.dump(geojson, f, indent=4) + else: + with open(args.output, "w+", encoding="utf-8") as f: + json.dump(geojson, f, indent=4) diff --git a/src/overturetoosm/objects.py b/src/overturetoosm/objects.py index db82bc2..1872a7a 100644 --- a/src/overturetoosm/objects.py +++ b/src/overturetoosm/objects.py @@ -380,4 +380,4 @@ def to_osm(self, style: str) -> Dict[str, str]: def source_statement(source: List[Sources]) -> str: """Return a source statement from a list of sources.""" - return ", ".join(i.dataset.strip(", ") for i in source) + " via overturetoosm" + return ", ".join({i.dataset.strip(", ") for i in source}) + " via overturetoosm"