summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGustav Sörnäs <gusso230@student.liu.se>2020-12-16 07:04:00 +0100
committerGustav Sörnäs <gusso230@student.liu.se>2020-12-16 07:04:00 +0100
commit90cba31d48974f1b7f694e570f8732098359a5ea (patch)
tree8c7a8222d368675fc580497877b57dbd257e4237
parent6c8acb4f4eabb20da41b941158bf52038035699f (diff)
parente15617848b6837216a8ceed4ca23b3bb415a42f7 (diff)
downloadtdde25-90cba31d48974f1b7f694e570f8732098359a5ea.tar.gz
Merge remote-tracking branch 'origin/xml-iterparse'
-rw-r--r--osm_parser.py81
-rw-r--r--server.py6
-rw-r--r--store.py8
3 files changed, 47 insertions, 48 deletions
diff --git a/osm_parser.py b/osm_parser.py
index 60754c9..7145726 100644
--- a/osm_parser.py
+++ b/osm_parser.py
@@ -57,9 +57,9 @@ OUT_TAGS_KEY = "tags"
class OSMParser:
"""
- A Parser that parses OSM data and enables iterating over
+ A Parser that parses OSM data and enables iterating over
Nodes and Ways as well as selecting which tags to show from the data.
-
+
One of the focuses of the parser has been to create something simple
that abstracts away as much object oriented features as possible from a normal user
@@ -67,69 +67,74 @@ class OSMParser:
in the XML file into a python dictionary. (since this key-value stuff is basically what xml is)
"""
-
def __init__(self, fname, all_way_tags):
- """
+ """
Initialize. if all_way_tags is True then the parser will return ways
with all tags, otherwise it will only choose specific tags
"""
- if not FILEEXT in fname:
+ if not fname.endswith(FILEEXT):
fname = fname + FILEEXT
- self.tree = ET.parse(fname) # ET, parse home
+ self.fname = fname
self.node_tags = set()
self.way_tags = set()
self.allow_all = all_way_tags
-
def add_node_tag(self, tag):
""" Adds a tag to be searched for when looking at nodes """
self.node_tags.add(tag)
-
def add_way_tag(self, tag):
""" Adds a tag to be searched for when looking at ways (edges) """
self.way_tags.add(tag)
-
def iter_nodes(self):
- """
+ """
Iterator-object for all nodes in osm-tree.
Returns a dictionary with the (manually) added tags
"""
- # Root of xml tree
- root = self.tree.getroot()
- for node in root.iter(OSM_NODE):
-
- # yield a dictionary with all tags that are added to self.node_tags
- yield { tag : node.attrib.get(tag, None)
- for tag in self.node_tags
- if tag in node.attrib }
-
+ for ev, el in ET.iterparse(self.fname, events=("start", "end")):
+ if ev == "start" and el.tag == "osm":
+ root = el
+ elif ev == "end" and el.tag == "node":
+ yield {k: v for k, v in el.items()}
+ if ev == "end":
+ if el in root:
+ root.remove(el)
+ el.clear()
def iter_ways(self):
- """
+ """
Iterator-object for all ways (edges) in osm-tree.
Returns a dictionary with the ways
"""
- # Root of xml-tree
- root = self.tree.getroot()
- for way in root.iter(OSM_WAY):
-
- # Take out roads and tags
- road = tuple( node.attrib[OSM_NODE_REFERENCE]
- for node in way.iter(OSM_WAYNODE) )
- tags = { tag.attrib[OSM_TAG_KEY] : tag.attrib[OSM_TAG_VALUE]
- for tag in way.iter(OSM_TAG)
- if self.allow_all or tag.attrib[OSM_TAG_KEY] in self.way_tags}
-
- # Yield the edge id, the road and the tags
- yield {
- OUT_EDGE_ID : way.attrib[OSM_WAY_ID],
- OUT_EDGES_KEY : road,
- OUT_TAGS_KEY : tags,
- }
-
+ reading_way = False
+ for ev, el in ET.iterparse(self.fname, events=("start", "end")):
+ if ev == "start" and el.tag == "osm":
+ root = el
+ elif ev == "start" and el.tag == "way":
+ reading_way = True
+ elif ev == "end" and el.tag == "way":
+ reading_way = False
+ # Take out roads and tags
+ road = tuple(node.get(OSM_NODE_REFERENCE)
+ for node in el.iter(OSM_WAYNODE))
+ tags = {tag.get(OSM_TAG_KEY): tag.get(OSM_TAG_VALUE)
+ for tag in el.iter(OSM_TAG)
+ if self.allow_all or tag.get(OSM_TAG_KEY) in self.way_tags}
+
+ # Yield the edge id, the road and the tags
+ yield {
+ OUT_EDGE_ID: el.get(OSM_WAY_ID),
+ OUT_EDGES_KEY: road,
+ OUT_TAGS_KEY: tags,
+ }
+
+ if ev == "end" and not reading_way:
+ if el in root:
+ root.remove(el)
+ el.clear()
+
##########################################
# Example Usage and Default Getter #
diff --git a/server.py b/server.py
index 25d2826..90e135e 100644
--- a/server.py
+++ b/server.py
@@ -14,7 +14,7 @@ def index():
global grid
global unconnected_nodes
- nodes, grid, unconnected_nodes = store.extract_osm_nodes("university.osm")
+ nodes, grid, unconnected_nodes = store.extract_osm_nodes("linkoping.osm")
return read_html('templates/index.html')
@@ -55,9 +55,7 @@ def shortest_path(body):
body['lng2']))
path = algorithms.find_shortest_path(nodes, source_id, target_id)
- print(path)
- response = {
- "path": [(nodes[node].lat, nodes[node].lng) for node in path]}
+ response = {"path": [(nodes[node].lat, nodes[node].lng) for node in path]}
return json.dumps(response)
diff --git a/store.py b/store.py
index c988e47..87cd940 100644
--- a/store.py
+++ b/store.py
@@ -42,10 +42,7 @@ class Node:
return self.lat, self.lng
-parser = None # Have a global reusable parser object
-
-
-def add_neighbours(nodes):
+def add_neighbours(nodes, parser):
for way in parser.iter_ways():
if 'highway' not in way['tags']:
continue
@@ -65,7 +62,6 @@ def add_neighbours(nodes):
def extract_osm_nodes(f_name):
- global parser
parser = get_default_parser(f_name)
nodes = dict()
grid = defaultdict()
@@ -74,7 +70,7 @@ def extract_osm_nodes(f_name):
new_node = Node(node['id'], node['lat'], node['lon'])
nodes[node['id']] = new_node
- add_neighbours(nodes)
+ add_neighbours(nodes, parser)
# Remove nodes without neighbours
for node_id, node in nodes.copy().items():