Jun-23-2024, 04:26 PM
Hello
I have a problem with the script. I'm not fluent in Python so I'm asking for help.
The script initializes the "handler" object, loads data from the file into it, then I can still see the data in the debbuger, but then, just before entering the "write_osm_file" function, the handler object as if it no longer existed or had another problem.
As I wrote, I'm weak in python, so I'm asking for help.
Below is a screenshot from the console and the script.
-----------------------------------
CONSOLE:
SCRIPT:
I have a problem with the script. I'm not fluent in Python so I'm asking for help.
The script initializes the "handler" object, loads data from the file into it, then I can still see the data in the debbuger, but then, just before entering the "write_osm_file" function, the handler object as if it no longer existed or had another problem.
As I wrote, I'm weak in python, so I'm asking for help.
Below is a screenshot from the console and the script.
-----------------------------------
CONSOLE:
Output: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.
-----------------------------SCRIPT:
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.")