{"id":10017,"library":"osmium","title":"PyOsmium","description":"PyOsmium provides Python bindings for libosmium, a high-performance C++ library designed for processing OpenStreetMap (OSM) data. It enables efficient reading, writing, and manipulation of various OSM file formats (PBF, XML, O5M) and change files, making it suitable for large-scale geospatial data tasks. The library is actively maintained with regular updates, typically aligning with new libosmium releases, and is currently at version 4.3.1.","status":"active","version":"4.3.1","language":"en","source_language":"en","source_url":"https://github.com/osmcode/pyosmium","tags":["GIS","OSM","geospatial","data processing","mapping","OpenStreetMap"],"install":[{"cmd":"pip install osmium","lang":"bash","label":"Install stable version"}],"dependencies":[],"imports":[{"symbol":"SimpleHandler","correct":"from osmium import SimpleHandler"},{"symbol":"FileProcessor","correct":"from osmium import FileProcessor"},{"symbol":"Node","correct":"from osmium.osm import Node"},{"symbol":"Location","correct":"from osmium.osm import Location"},{"symbol":"SimpleWriter","correct":"from osmium import SimpleWriter"}],"quickstart":{"code":"import osmium\nimport osmium.osm\nimport tempfile\nimport os\nfrom datetime import datetime\n\n# Create a dummy PBF file for demonstration purposes\n# In a real scenario, you'd process an existing .osm.pbf file.\ntemp_pbf_file = os.path.join(tempfile.gettempdir(), \"test.osm.pbf\")\nwriter = osmium.SimpleWriter(temp_pbf_file)\nwriter.add_node(osmium.osm.Node(1, location=osmium.osm.Location(1.0, 1.0), user='test_user', timestamp=datetime.now()))\nwriter.add_node(osmium.osm.Node(2, location=osmium.osm.Location(2.0, 2.0), user='test_user', timestamp=datetime.now()))\nwriter.add_way(osmium.osm.Way(3, nodes=[1, 2], user='test_user', timestamp=datetime.now()))\nwriter.add_relation(osmium.osm.Relation(4, user='test_user', timestamp=datetime.now()))\nwriter.close()\n\nclass ElementCounter(osmium.SimpleHandler):\n    def __init__(self):\n        super().__init__()\n        self.nodes = 0\n        self.ways = 0\n        self.relations = 0\n\n    def node(self, n):\n        self.nodes += 1\n\n    def way(self, w):\n        self.ways += 1\n\n    def relation(self, r):\n        self.relations += 1\n\ntry:\n    # Process the (dummy) PBF file using the handler\n    handler = ElementCounter()\n    handler.apply_file(temp_pbf_file)\n\n    print(f\"Nodes: {handler.nodes}\")\n    print(f\"Ways: {handler.ways}\")\n    print(f\"Relations: {handler.relations}\")\nfinally:\n    # Clean up the temporary file\n    if os.path.exists(temp_pbf_file):\n        os.remove(temp_pbf_file)\n","lang":"python","description":"This example demonstrates how to use `osmium.SimpleHandler` to process an OSM PBF file. It creates a temporary dummy PBF file, then defines a handler to count nodes, ways, and relations, and applies it to the file. This pattern is fundamental for reading and iterating over OSM data."},"warnings":[{"fix":"Rewrite processing logic to use `osmium.FileProcessor` for efficient, iterative handling of large OSM files. For simpler cases, `osmium.SimpleHandler.apply_file()` is still available and performs iterative processing.","message":"Prior to v4.0.0, PyOsmium loaded entire OSM files into memory, which was inefficient for large files. Version 4.0.0 introduced `osmium.FileProcessor` for iterative processing. Scripts written for older versions that implicitly assumed full in-memory loading will likely fail or be extremely slow with large datasets.","severity":"breaking","affected_versions":"<4.0.0"},{"fix":"If you need to persist data from an OSM object, you must copy the relevant attributes (e.g., `node.id`, `node.tags`, `node.location`) into new Python objects or data structures, rather than storing the `osmium.osm.Node` itself.","message":"Objects (Node, Way, Relation) passed to handler callbacks are only valid for the duration of that specific callback. Keeping direct Python references to these objects beyond the callback's scope will lead to errors, as the underlying C++ memory is deallocated. This is a common source of `TypeError: cannot convert 'osmium._osmium.Node' object to Python type`.","severity":"gotcha","affected_versions":"All versions"},{"fix":"Update custom `ReplicationServer` implementations to use `set_request_parameter()` for configuring HTTP requests instead of overriding `open_url()`.","message":"The method `ReplicationServer.open_url()` was deprecated in favor of `ReplicationServer.set_request_parameter()` in v3.7.0. Direct overrides of `open_url()` are no longer supported, making old custom replication logic incompatible.","severity":"deprecated","affected_versions":">=3.7.0"},{"fix":"Ensure your build environment is updated. If you have custom C++ components interacting with PyOsmium's internals, review their Boost dependencies. For most users installing via pip, this change is transparent.","message":"Version 4.3.0 removed the direct dependency on Boost C++. While this simplifies the build process, custom C++ extensions or very specific build environments that previously relied on PyOsmium's Boost dependency might need adjustments.","severity":"breaking","affected_versions":">=4.3.0"},{"fix":"When installing from source, update your build scripts or commands to use the new CMake `_ROOT` variables for custom component locations.","message":"The build process for installing PyOsmium from source changed significantly in v4.1.0. `pybind11` is now installed from PyPI, and custom location variables for `libosmium`, `protozero`, or `boost` (e.g., `LIBOSMIUM_PREFIX`) have been replaced by CMake's standard `Libosmium_ROOT`, `Protozero_ROOT` variables.","severity":"breaking","affected_versions":">=4.1.0"},{"fix":"Upgrade to PyOsmium 4.3.1 or later immediately if you are working with change files for OSM data extracts.","message":"Version 4.3.1 fixed a critical regression introduced in `libosmium` 2.23.0 (used by PyOsmium 4.3.0) where deletions in extract diffs were not handled correctly. Users processing OSM change files, especially for extracts like those from Geofabrik, might encounter incorrect data if using earlier versions.","severity":"breaking","affected_versions":"4.3.0"}],"env_vars":null,"last_verified":"2026-04-17T00:00:00.000Z","next_check":"2026-07-16T00:00:00.000Z","problems":[{"fix":"Instead of storing the entire Osmium object, extract and store only the necessary data (e.g., `node.id`, `node.tags.get('name')`, `node.location`) into a new Python dictionary or custom object.","cause":"Attempting to store a direct reference to an Osmium C++ object (like Node, Way, Relation) outside of its handler callback, leading to access violations once the underlying C++ memory is deallocated.","error":"TypeError: cannot convert 'osmium._osmium.Node' object to Python type"},{"fix":"For basic file processing using a handler, instantiate your custom handler and call `handler.apply_file(filename)`. `FileProcessor` is used differently, typically with a `osmium.apply()` function or by managing its processing stages explicitly.","cause":"Confusing the `osmium.FileProcessor` class (used for advanced, granular processing of file sections) with the `apply_file()` method, which belongs to `osmium.SimpleHandler`.","error":"AttributeError: 'FileProcessor' object has no attribute 'apply_file'"},{"fix":"Verify that the file path is correct and absolute, or that the file exists in the current working directory. Ensure the Python process has read permissions for the file.","cause":"The specified OpenStreetMap data file (.osm.pbf, .osm, .o5m, etc.) does not exist at the given path, or the path is incorrect/inaccessible.","error":"FileNotFoundError: [Errno 2] No such file or directory: 'your_file.osm.pbf'"}]}