Python Forum
Script problem - Illegal access to removed OSM object - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: Script problem - Illegal access to removed OSM object (/thread-42354.html)



Script problem - Illegal access to removed OSM object - MarcPolo72 - Jun-23-2024

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:

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.")