Witam
Mam problem ze skryptem. Nie jestem biegły w Python więc zwracam się o pomoc.
Skrypt inicjuje obiekt handler
, wczytuje do niego dane z plika, wtedy jeszcze w debuggerze widze w nim dane, ale zaraz potem tuż przed wejściem do funkcji write_osm_file
obiekt handler tak jakby już nie istniał albo miał inny problem.
Jak pisałem jestem słaby w python więc proszę o pomoc.
Poniżej zrzut z konsoli i skrypt.
KONSOLA:
c:\3DTiles>python filter.py
Applying file...
Added way with building tag: id=961961143, nodes=5
Node ref: ref=8898381795
Node ref: ref=8898381989
Node ref: ref=8898381128
Node ref: ref=8898381368
Node ref: ref=8898381795
Tag: k=addr:city, v=Warszawa
Tag: k=addr:city:simc, v=0918123
Tag: k=addr:housenumber, v=19
Tag: k=addr:postcode, v=02-995
Tag: k=addr:street, v=Prętowa
Tag: k=building, v=detached
Tag: k=building:levels, v=2
Tag: k=source, v=www.geoportal.gov.pl
Tag: k=source:addr, v=gugik.gov.pl
Finished applying file.
Writing buildings to file...
Skipping element due to invalid id access: Illegal access to removed OSM object (element: {'_pyosmium_data': <osmium.osm._osm.COSMWay object at 0x000002A6147FF570>, 'tags': osmium.osm.TagList({<invalid>}), '_nodes': osmium.osm.WayNodeList([<invalid>])})
Found 1 buildings.
SKRYPT:
import osmium as osm
import xml.etree.ElementTree as ET
class BuildingHandler(osm.SimpleHandler):
def __init__(self):
osm.SimpleHandler.__init__(self)
self.buildings = []
def node(self, n):
try:
if 'building' in n.tags and n.location.valid():
self.buildings.append(n)
print(f"Added building node: id={n.id}, lat={n.location.lat}, lon={n.location.lon}")
except Exception as e:
print(f"Error processing node: id={n.id}, error={e}")
def way(self, w):
try:
if 'building' in w.tags or 'building' in w.tags.get('other_tags', ''):
self.buildings.append(w)
print(f"Added way with building tag: id={w.id}, nodes={len(w.nodes)}")
for node in w.nodes:
print(f" Node ref: ref={node.ref}")
for tag in w.tags:
print(f" Tag: k={tag.k}, v={tag.v}")
except Exception as e:
print(f"Error processing way: id={w.id}, error={e}")
def relation(self, r):
try:
if 'building' in r.tags:
self.buildings.append(r)
print(f"Added building relation: id={r.id}, members={len(r.members)}")
except Exception as e:
print(f"Error processing relation: id={r.id}, error={e}")
def write_osm_file(filename, elements):
root = ET.Element("osm", version="0.6")
for element in elements:
try:
if isinstance(element, osm.osm.Node):
element_id = str(element.id)
print(f"Node element_id: {element_id}")
if int(element_id) == -1:
raise RuntimeError("Invalid id")
node = ET.SubElement(root, "node", id=element_id, lat=str(element.location.lat), lon=str(element.location.lon))
for tag in element.tags:
ET.SubElement(node, "tag", k=tag.k, v=tag.v)
print(f"Processed node: id={element_id}")
elif isinstance(element, osm.osm.Way):
element_id = str(element.id)
print(f"Way element_id: {element_id}")
if int(element_id) == -1:
raise RuntimeError("Invalid id")
way = ET.SubElement(root, "way", id=element_id)
print(f"Processing way: id={element_id}")
for node_ref in element.nodes:
print(f" Adding node_ref: ref={node_ref.ref}")
ET.SubElement(way, "nd", ref=str(node_ref.ref))
for tag in element.tags:
print(f" Adding tag: k={tag.k}, v={tag.v}")
ET.SubElement(way, "tag", k=tag.k, v=tag.v)
print(f"Processed way: id={element_id}, nodes={len(element.nodes)}")
elif isinstance(element, osm.osm.Relation):
element_id = str(element.id)
print(f"Relation element_id: {element_id}")
if int(element_id) == -1:
raise RuntimeError("Invalid id")
relation = ET.SubElement(root, "relation", id=element_id)
for member in element.members:
ET.SubElement(relation, "member", type=member.type, ref=str(member.ref), role=member.role)
for tag in element.tags:
ET.SubElement(relation, "tag", k=tag.k, v=tag.v)
print(f"Processed relation: id={element_id}, members={len(element.members)}")
else:
print(f"Unknown element type: {type(element)}")
except RuntimeError as e:
print(f"Skipping element due to invalid id access: {e} (element: {element.__dict__})")
except Exception as ex:
print(f"Unexpected error for element: {ex} (element: {element.__dict__})")
tree = ET.ElementTree(root)
tree.write(filename, encoding="utf-8", xml_declaration=True)
if __name__ == "__main__":
# Initialize the handler
handler = BuildingHandler()
# Read the OSM file
print("Applying file...")
handler.apply_file(r'C:\3DTiles\map.osm')
print("Finished applying file.")
# Save the filtered buildings to a new file
print("Writing buildings to file...")
write_osm_file(r'C:\3DTiles\filtered_buildings.osm', handler.buildings)
print(f"Found {len(handler.buildings)} buildings.")