From 945af54dc9eea173bf901d7e5695da657f5abf24 Mon Sep 17 00:00:00 2001 From: Sergey Vartanov Date: Sun, 23 Aug 2020 11:15:51 +0300 Subject: [PATCH] Add OSM data downloading using API. --- readme.md | 42 +++++++++++++++++++++++++++++------ roentgen/mapper.py | 21 ++++++++++++------ roentgen/network.py | 50 +----------------------------------------- roentgen/osm_getter.py | 47 +++++++++++++++++++-------------------- run.py | 2 -- 5 files changed, 73 insertions(+), 89 deletions(-) diff --git a/readme.md b/readme.md index ba54dd1..25587ee 100644 --- a/readme.md +++ b/readme.md @@ -22,25 +22,53 @@ There are simple Python renderer that generates SVG map from OpenStreetMap data. You can run it using: ```bash -python3 roentgen.py -i ${INPUT_FILE_NAME} -o ${OUTPUT_FILE_NAME} +python3 run.py \ + -bbox ${LONGITUDE_1},${LATITUDE_1},${LONGITUDE_2},${LATITUDE_2} \ + -o ${OUTPUT_FILE_NAME} \ + -s ${WIDTH},${HEIGHT} ``` -### Options ### +Example: + +```bash +python3 run.py -bbox 2.284,48.86,2.29,48.865 -o map.svg -s 1000,1000 +``` + +### Main arguments ### + +#### Required #### - + - - + + + + + + + + +
OptionValueDescription
-bbox, --boundary-box - <longitude 1>,<latitude 1>,<longitude 2>,<latitude 2> - (decimal float) + <longitude 1>,<latitude 1>,<longitude + 2>,<latitude 2> Boundary box to drawBoundary box to draw.
-s, --size<width>,<height> (pixels)Result image size<width>,<height>Result image size in pixels.
-o<path>Path to output SVG file name.
+ +#### Optional #### + + + + + + +
OptionValueDescription
-i<path>Path to input XML file name. If this argument is not set, XML file + will be downloaded throung Openstreetmap API.
diff --git a/roentgen/mapper.py b/roentgen/mapper.py index 35c2841..ba05653 100644 --- a/roentgen/mapper.py +++ b/roentgen/mapper.py @@ -16,6 +16,7 @@ from roentgen import ui from roentgen import svg from roentgen.flinger import GeoFlinger, Geo from roentgen.osm_reader import OSMReader, OSMWay +from roentgen.osm_getter import get_osm from datetime import datetime from typing import List, Optional, Set @@ -1064,17 +1065,25 @@ def main(): if not options: sys.exit(1) - background_color = "EEEEEE" # "DDDDDD" + background_color = "EEEEEE" if options.mode in ["user-coloring", "time"]: background_color = "111111" - outline_color = "111111" - input_file_name = options.input_file_name + if options.input_file_name: + input_file_name = options.input_file_name + else: + content = get_osm(options.boundary_box) + if not content: + ui.error("cannot download OSM data") + input_file_name = os.path.join("map", options.boundary_box + ".osm") if not os.path.isfile(input_file_name): print("Fatal: no such file: " + input_file_name + ".") sys.exit(1) + boundary_box = list(map( + lambda x: float(x.replace('m', '-')), options.boundary_box.split(','))) + full = False # Full keys getting if options.mode in ["user-coloring", "time"]: @@ -1095,10 +1104,8 @@ def main(): "Rͧntgen\n") output_file.rect(0, 0, w, h, color=background_color) - if "boundary_box" in options: - bb = options.boundary_box - min1 = Geo(bb[1], bb[0]) - max1 = Geo(bb[3], bb[2]) + min1 = Geo(boundary_box[1], boundary_box[0]) + max1 = Geo(boundary_box[3], boundary_box[2]) authors = {} missed_tags = {} diff --git a/roentgen/network.py b/roentgen/network.py index 1eeed0c..2b1db17 100644 --- a/roentgen/network.py +++ b/roentgen/network.py @@ -25,7 +25,7 @@ def get_data(address: str, parameters: Dict[str, str], is_secure: bool=False, na """ url = "http" + ("s" if is_secure else "") + "://" + address if len(parameters) > 0: - url += "?" + "&".join(parameters) # urllib.parse.urlencode(parameters) + url += "?" + urllib.parse.urlencode(parameters) if not name: name = url print("getting " + name) @@ -36,51 +36,3 @@ def get_data(address: str, parameters: Dict[str, str], is_secure: bool=False, na pool_manager.clear() time.sleep(2) return result.data - - -def get_content(address, parameters, cache_file_name, kind, is_secure, name=None, exceptions=None, update_cache=False): - """ - Read content from URL or from cached file. - - :param address: first part of URL without "http://" - :param parameters: URL parameters - :param cache_file_name: name of cache file - :param kind: type of content: "html" or "json" - :return: content if exist - """ - if exceptions and address in exceptions: - return None - if os.path.isfile(cache_file_name) and \ - datetime(1, 1, 1).fromtimestamp(os.stat(cache_file_name).st_mtime) > \ - datetime.now() - timedelta(days=90) and \ - not update_cache: - with open(cache_file_name) as cache_file: - if kind == "json": - try: - return json.load(cache_file) - except ValueError: - return None - if kind == "html": - return cache_file.read() - else: - try: - data = get_data(address, parameters, is_secure=is_secure, name=name) - if kind == "json": - try: - obj = json.loads(data) - with open(cache_file_name, "w+") as cached: - cached.write(json.dumps(obj, indent=4)) - return obj - except ValueError: - print("cannot get " + address + " " + str(parameters)) - return None - if kind == "html": - with open(cache_file_name, "w+") as cached: - cached.write(data) - return data - except Exception as e: - print("during getting JSON from " + address + " with parameters " + str(parameters)) - print(e) - if exceptions: - exceptions.append(address) - return None diff --git a/roentgen/osm_getter.py b/roentgen/osm_getter.py index 0c46f38..84bedb4 100644 --- a/roentgen/osm_getter.py +++ b/roentgen/osm_getter.py @@ -1,48 +1,47 @@ +import os import re -import sys + +from typing import Optional from roentgen.ui import error from roentgen import network -USAGE: str = '' +def get_osm(boundary_box: str, to_update: bool = False) -> Optional[str]: + result_file_name = os.path.join("map", boundary_box + ".osm") + if not to_update and os.path.isfile(result_file_name): + return open(result_file_name).read() -def main(boundary_box: str): - result_file_name = 'map/' + boundary_box + '.xml' - - matcher = re.match('(?P[0-9\\.-]*),(?P[0-9\\.-]*),' + \ - '(?P[0-9\\.-]*),(?P[0-9\\.-]*)', boundary_box) + matcher = re.match("(?P[0-9.-]*),(?P[0-9.-]*)," + + "(?P[0-9.-]*),(?P[0-9.-]*)", boundary_box) if not matcher: - error('invalid boundary box') + error("invalid boundary box") return try: - left = float(matcher.group('left')) - bottom = float(matcher.group('bottom')) - right = float(matcher.group('right')) - top = float(matcher.group('top')) - except Exception: - error('parsing boundary box') + left = float(matcher.group("left")) + bottom = float(matcher.group("bottom")) + right = float(matcher.group("right")) + top = float(matcher.group("top")) + except ValueError: + error("parsing boundary box") return if left >= right: - error('negative horizontal boundary') + error("negative horizontal boundary") return if bottom >= top: - error('negative vertical boundary') + error("negative vertical boundary") return if right - left > 0.5 or top - bottom > 0.5: - error('box too big') + error("box too big") return - network.get_content('api.openstreetmap.org/api/0.6/map', - {'bbox': boundary_box}, result_file_name, 'html', is_secure=True) + content = network.get_data("api.openstreetmap.org/api/0.6/map", + {"bbox": boundary_box}, is_secure=True) -if __name__ == "__main__": - if len(sys.argv) < 2: - print('Usage: python ' + sys.argv[0] + ' ' + USAGE) - sys.exit(0) + open(result_file_name, "w+").write(content.decode("utf-8")) - main(sys.argv[1]) + return content.decode("utf-8") diff --git a/run.py b/run.py index e91319e..98a3ffb 100644 --- a/run.py +++ b/run.py @@ -1,6 +1,4 @@ -from roentgen.osm_getter import main from roentgen.mapper import main if __name__ == "__main__": - # main("2.374,48.843,2.378,48.846") main()