mirror of
https://github.com/enzet/map-machine.git
synced 2025-05-19 03:56:22 +02:00
Refactor map constructor.
This commit is contained in:
parent
09dc44567c
commit
f452a08177
3 changed files with 789 additions and 735 deletions
|
@ -26,7 +26,7 @@ class OSMNode:
|
|||
self.user: Optional[str] = None
|
||||
self.uid: Optional[str] = None
|
||||
|
||||
def parse_from_xml(self, text: str, is_full: bool = False):
|
||||
def parse_from_xml(self, text: str, is_full: bool = False) -> "OSMNode":
|
||||
"""
|
||||
Parse from XML node representation.
|
||||
|
||||
|
@ -64,7 +64,7 @@ class OSMWay:
|
|||
self.timestamp: Optional[str] = None
|
||||
self.uid: Optional[str] = None
|
||||
|
||||
def parse_from_xml(self, text: str, is_full: bool = False):
|
||||
def parse_from_xml(self, text: str, is_full: bool = False) -> "OSMWay":
|
||||
"""
|
||||
Parse from XML way representation.
|
||||
|
||||
|
@ -96,41 +96,51 @@ class OSMWay:
|
|||
return OSMWay(nodes=self.nodes + other.nodes[1:])
|
||||
|
||||
def __repr__(self):
|
||||
return str(self.nodes)
|
||||
return f"Way <{self.id_}> {self.nodes}"
|
||||
|
||||
|
||||
class OSMRelation:
|
||||
def __init__(self, id_: int):
|
||||
"""
|
||||
OpenStreetMap relation.
|
||||
|
||||
See https://wiki.openstreetmap.org/wiki/Relation
|
||||
"""
|
||||
def __init__(self, id_: int = 0):
|
||||
self.id_: int = id_
|
||||
self.tags = {}
|
||||
self.members = []
|
||||
self.tags: Dict[str, str] = {}
|
||||
self.members: List["OSMMember"] = []
|
||||
|
||||
def parse_from_xml(self, text: str) -> "OSMRelation":
|
||||
"""
|
||||
Parse from XML relation representation.
|
||||
|
||||
:param text: XML way representation
|
||||
"""
|
||||
self.id_ = int(get_value("id", text))
|
||||
|
||||
return self
|
||||
|
||||
|
||||
class OSMMember:
|
||||
"""
|
||||
Member of OpenStreetMap relation.
|
||||
"""
|
||||
def __init__(self, text: str):
|
||||
self.type_ = get_value("type", text)
|
||||
self.ref = int(get_value("ref", text))
|
||||
self.role = get_value("role", text)
|
||||
|
||||
|
||||
def get_value(key: str, text: str):
|
||||
"""
|
||||
Parse xml value from the tag in the format of key="value".
|
||||
"""
|
||||
if key + '="' in text:
|
||||
index: int = text.find(key + '="')
|
||||
value = text[index + len(key) + 2:text.find('"', index + len(key) + 4)]
|
||||
return value
|
||||
|
||||
|
||||
def parse_relation(text) -> OSMRelation:
|
||||
"""
|
||||
Just parse relation identifier.
|
||||
"""
|
||||
id = text[text.find("id=\"") + 4:text.find('"', text.find("id=\"") + 6)]
|
||||
return OSMRelation(int(id))
|
||||
|
||||
|
||||
def parse_member(text) -> Dict[str, Any]:
|
||||
"""
|
||||
Parse member type, reference, and role.
|
||||
"""
|
||||
type = get_value("type", text)
|
||||
ref = get_value("ref", text)
|
||||
role = get_value("role", text)
|
||||
return {'type': type, 'ref': int(ref), 'role': role}
|
||||
|
||||
|
||||
class Map:
|
||||
def __init__(self, node_map, way_map, relation_map):
|
||||
self.node_map = node_map
|
||||
|
@ -139,51 +149,49 @@ class Map:
|
|||
|
||||
|
||||
class OSMReader:
|
||||
"""
|
||||
OSM XML representation reader.
|
||||
"""
|
||||
def __init__(self, file_name: str):
|
||||
self.file_name = file_name
|
||||
|
||||
def parse_osm_file(
|
||||
self, parse_nodes: bool = True, parse_ways: bool = True,
|
||||
parse_relations: bool = True, full: bool = False) -> Map:
|
||||
|
||||
map_ = self.parse_osm_file_fast(
|
||||
parse_nodes=parse_nodes, parse_ways=parse_ways,
|
||||
parse_relations=parse_relations, full=full)
|
||||
return map_
|
||||
|
||||
def parse_osm_file_fast(self, parse_nodes=True, parse_ways=True,
|
||||
parse_relations=True, full=False) -> Map:
|
||||
"""
|
||||
Parse OSM XML representation.
|
||||
"""
|
||||
node_map: Dict[int, OSMNode] = {}
|
||||
way_map: Dict[int, OSMWay] = {}
|
||||
relation_map: Dict[int, OSMRelation] = {}
|
||||
print('Line number counting for ' + self.file_name + '...')
|
||||
print(f"Line number counting for {self.file_name}...")
|
||||
with open(self.file_name) as f:
|
||||
for lines_number, l in enumerate(f):
|
||||
for lines_number, _ in enumerate(f):
|
||||
pass
|
||||
print('Done.')
|
||||
print('Parsing OSM file ' + self.file_name + '...')
|
||||
print("Done.")
|
||||
print(f"Parsing OSM file {self.file_name}...")
|
||||
input_file = open(self.file_name)
|
||||
line = input_file.readline()
|
||||
line_number = 0
|
||||
|
||||
while line != '':
|
||||
while line != "":
|
||||
line_number += 1
|
||||
ui.write_line(line_number, lines_number)
|
||||
|
||||
# Node parsing.
|
||||
|
||||
if line[:6] in [' <node', '\t<node'] or line[:7] == " <node":
|
||||
if line[:6] in [" <node", "\t<node"] or line[:7] == " <node":
|
||||
if not parse_nodes:
|
||||
if parse_ways or parse_relations:
|
||||
continue
|
||||
else:
|
||||
break
|
||||
if line[-3] == '/':
|
||||
if line[-3] == "/":
|
||||
node: OSMNode = OSMNode().parse_from_xml(line[7:-3], full)
|
||||
node_map[node.id_] = node
|
||||
else:
|
||||
element = OSMNode().parse_from_xml(line[7:-2], full)
|
||||
elif line in [' </node>\n', '\t</node>\n', " </node>\n"]:
|
||||
elif line in [" </node>\n", "\t</node>\n", " </node>\n"]:
|
||||
node_map[element.id_] = element
|
||||
|
||||
# Way parsing.
|
||||
|
@ -204,30 +212,30 @@ class OSMReader:
|
|||
|
||||
# Relation parsing.
|
||||
|
||||
elif line[:10] in [' <relation', '\t<relation'] or \
|
||||
elif line[:10] in [" <relation", "\t<relation"] or \
|
||||
line[:11] == " <relation":
|
||||
if not parse_relations:
|
||||
break
|
||||
if line[-3] == '/':
|
||||
relation = parse_relation(line[11:-3])
|
||||
if line[-3] == "/":
|
||||
relation = OSMRelation().parse_from_xml(line[11:-3])
|
||||
relation_map[relation.id_] = relation
|
||||
else:
|
||||
element = parse_relation(line[11:-2])
|
||||
elif line in [' </relation>\n', '\t</relation>\n'] or \
|
||||
element = OSMRelation().parse_from_xml(line[11:-2])
|
||||
elif line in [" </relation>\n", "\t</relation>\n"] or \
|
||||
line == " </relation>\n":
|
||||
relation_map[element.id_] = element
|
||||
|
||||
# Elements parsing.
|
||||
|
||||
elif line[:6] in [' <tag', '\t\t<tag'] or line[:8] == " <tag":
|
||||
elif line[:6] in [" <tag", "\t\t<tag"] or line[:8] == " <tag":
|
||||
k = get_value("k", line[7:-3])
|
||||
v = get_value("v", line[7:-3])
|
||||
element.tags[k] = v
|
||||
elif line[:5] in [' <nd', '\t\t<nd'] or line[:7] == " <nd":
|
||||
elif line[:5] in [" <nd", "\t\t<nd"] or line[:7] == " <nd":
|
||||
element.nodes.append(int(get_value("ref", line)))
|
||||
elif line[:9] in [' <member', '\t\t<member'] or line[:11] == " <member":
|
||||
member = parse_member(line[10:-3])
|
||||
element.members.append(member)
|
||||
elif line[:9] in [" <member", "\t\t<member"] or \
|
||||
line[:11] == " <member":
|
||||
element.members.append(OSMMember(line[10:-3]))
|
||||
line = input_file.readline()
|
||||
input_file.close()
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue