map-machine/roentgen/osm_getter.py
2021-08-15 17:18:30 +03:00

78 lines
2.1 KiB
Python

"""
Getting OpenStreetMap data from the web.
"""
import time
import urllib
from pathlib import Path
from typing import Dict, Optional
import logging
import urllib3
from roentgen.ui import BoundaryBox
__author__ = "Sergey Vartanov"
__email__ = "me@enzet.ru"
class NetworkError(Exception):
"""Failed network request."""
def __init__(self, message: str):
super().__init__()
self.message: str = message
def get_osm(
boundary_box: BoundaryBox, cache_path: Path, to_update: bool = False
) -> str:
"""
Download OSM data from the web or get if from the cache.
:param boundary_box: borders of the map part to download
:param cache_path: cache directory to store downloaded OSM files
:param to_update: update cache files
"""
result_file_name: Path = cache_path / f"{boundary_box.get_format()}.osm"
if not to_update and result_file_name.is_file():
return result_file_name.open().read()
content: Optional[str] = get_data(
"api.openstreetmap.org/api/0.6/map",
{"bbox": boundary_box.get_format()},
is_secure=True,
).decode("utf-8")
with result_file_name.open("w+") as output_file:
output_file.write(content)
return content
def get_data(
address: str, parameters: Dict[str, str], is_secure: bool = False
) -> bytes:
"""
Construct Internet page URL and get its descriptor.
:param address: first part of URL without "http://"
:param parameters: URL parameters
:param is_secure: https or http
:return: connection descriptor
"""
url: str = "http" + ("s" if is_secure else "") + "://" + address
if len(parameters) > 0:
url += f"?{urllib.parse.urlencode(parameters)}"
logging.info(f"Getting {url}...")
pool_manager: urllib3.PoolManager = urllib3.PoolManager()
urllib3.disable_warnings()
try:
result = pool_manager.request("GET", url)
except urllib3.exceptions.MaxRetryError:
raise NetworkError("Cannot download data: too many attempts.")
pool_manager.clear()
time.sleep(2)
return result.data