mirror of
https://github.com/enzet/map-machine.git
synced 2025-07-22 02:48:02 +02:00
Add OSM data downloading using API.
This commit is contained in:
parent
f1a5c2244c
commit
945af54dc9
5 changed files with 73 additions and 89 deletions
42
readme.md
42
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 ####
|
||||
|
||||
<table>
|
||||
<tr><td>Option</td><td>Value</td><td>Description</td></tr>
|
||||
<tr>
|
||||
<td><tt>-bbox</tt>, <tt>--boundary-box</tt></td>
|
||||
<td>
|
||||
<tt><longitude 1>,<latitude 1>,<longitude 2>,<latitude 2></tt>
|
||||
(decimal float)
|
||||
<tt><longitude 1>,<latitude 1>,<longitude
|
||||
2>,<latitude 2></tt>
|
||||
</td>
|
||||
<td>Boundary box to draw</td>
|
||||
<td>Boundary box to draw.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-s</tt>, <tt>--size</tt></td>
|
||||
<td><tt><width>,<height></tt> (pixels)</td>
|
||||
<td>Result image size</td>
|
||||
<td><tt><width>,<height></tt></td>
|
||||
<td>Result image size in pixels.</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><tt>-o</tt></td>
|
||||
<td><tt><path></tt></td>
|
||||
<td>Path to output SVG file name.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
#### Optional ####
|
||||
|
||||
<table>
|
||||
<tr><td>Option</td><td>Value</td><td>Description</td></tr>
|
||||
<tr>
|
||||
<td><tt>-i</tt></td>
|
||||
<td><tt><path></tt></td>
|
||||
<td>Path to input XML file name. If this argument is not set, XML file
|
||||
will be downloaded throung Openstreetmap API.</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
|
|
@ -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"
|
||||
|
||||
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():
|
|||
"<title>Rӧntgen</title><style>path:hover {stroke: #FF0000;}</style>\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 = {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 = '<box coordinates: left,bottom,right,top>'
|
||||
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<left>[0-9\\.-]*),(?P<bottom>[0-9\\.-]*),' + \
|
||||
'(?P<right>[0-9\\.-]*),(?P<top>[0-9\\.-]*)', boundary_box)
|
||||
matcher = re.match("(?P<left>[0-9.-]*),(?P<bottom>[0-9.-]*)," +
|
||||
"(?P<right>[0-9.-]*),(?P<top>[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")
|
||||
|
|
2
run.py
2
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()
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue