refactoring, object oriented. CLI interface needs polishing

This commit is contained in:
fordprefect
2020-03-26 17:58:12 +01:00
parent 293e29409a
commit 2b62bc4725
2 changed files with 100 additions and 95 deletions

100
osmsearch.py Normal file
View File

@@ -0,0 +1,100 @@
#!/usr/bin/python
"""
Script to retrieve all Openstreetmap items matching a query and save
them as GPX Waypoints to a given output file in GPX format.
"""
__author__ = "fordprefect"
__date__ = "2020-03-26"
__version__ = "0.1"
import gpxpy
import requests
import os
import sys
assert sys.version_info >= (3, 6), "At least Python 3.8 required due to fStrings. Replace all f\"\" and comment this line to enable running in lower versions (but really, you should just update your Python version…)."
class OSMSearch():
def __init__(self, args):
self.url = args.pop("url")
self.maxsearchnums = args.pop("maxsearchnums")
self.gpxfilename = args.pop("outputfilename")
self.use_boundingbox = args.pop("use_boundingbox")
if self.use_boundingbox:
assert isinstance(list, args["boundingbox"])
assert len(args["boundingbox"]) == 4
else:
args.pop("boundingbox")
self.searchargs = args
self.initialize_gpx_file()
self.search()
self.save_to_disk()
def initialize_gpx_file(self):
if os.path.isfile(self.gpxfilename):
# open file and parse
#if verbosity > 0: print(f"found file, extending")
self.gpxfile = gpxpy.parse(open(gpxfilename, "r"))
else:
#if verbosity > 0: print("creating new file")
self.gpxfile = gpxpy.gpx.GPX()
def get_argstring(self):
argstrings = []
if self.use_boundingbox:
argstring.append(",".join(list(map(str, self.searchargs["boundingbox"]))))
for arg in self.searchargs:
argstrings.append(f"{arg}={self.searchargs[arg]}")
return "?"+"&".join(argstrings)
def search(self):
"""
"""
for i in range(self.maxsearchnums):
# fetch request
r = requests.get(self.url + self.get_argstring())
if r.status_code != 200:
#if verbosity > 0: print(f"Query gone wrong: HTTP returned {r.status_code}")
exit(1)
# parse reply
reply = r.json()
assert isinstance(reply, list), "Unexpected type of reply: " + type(reply)
if len(reply) == 0:
if verbosity > 0: print(f"found {len(ignore_ids)} results in {i-1} iterations, finishing")
break
for point in reply:
self.searchargs["ignore_ids"].append(point["place_id"])
self.gpxfile.waypoints.append(gpxpy.gpx.GPXWaypoint(latitude=point["lat"], longitude=point["lon"], name=point["display_name"]))
def save_to_disk(self):
with open(self.gpxfilename, "w") as f:
f.write(self.gpxfile.to_xml())
#if verbosity > 0: print(f"GPX file written to {gpxfilename}")
default_args = {
"q": "Camping",
"format": "json",
"limit": 50,
"use_boundingbox": False,
"boundingbox": [],
"outputfilename": "test.gpx",
"ignore_ids": [],
"maxsearchnums": 10,
"url": "https://nominatim.openstreetmap.org/search/",
}
if __name__ == "__main__":
# cli invocation goes here
# TODO: take user arguments and bring together with sensible defaults above
OSMSearch(default_args)