Osm2geojson
Convert OSM and Overpass XML/JSON to GeoJSON
Install / Use
/learn @aspectumapp/Osm2geojsonREADME
osm2geojson
<!-- [](https://pypi.org/project/osm2geojson/) -->Parse OSM and Overpass JSON/XML to GeoJSON with Python.
This library is under development!
Installation
pip install osm2geojson
Usage
Python API
Convert OSM/Overpass data to GeoJSON using one of four main functions:
import osm2geojson
# From Overpass JSON
geojson = osm2geojson.json2geojson(overpass_json)
# From OSM/Overpass XML
geojson = osm2geojson.xml2geojson(osm_xml)
# To Shape objects (Shapely geometries + properties)
shapes = osm2geojson.json2shapes(overpass_json)
shapes = osm2geojson.xml2shapes(osm_xml)
Command-Line Interface
After installation, use as a command-line tool:
osm2geojson --help
# or
python -m osm2geojson --help
API Reference
Main Functions
json2geojson(data, **options)
Convert Overpass JSON to GeoJSON FeatureCollection.
xml2geojson(xml_str, **options)
Convert OSM/Overpass XML to GeoJSON FeatureCollection.
json2shapes(data, **options)
Convert Overpass JSON to Shape objects (Shapely geometry + properties).
xml2shapes(xml_str, **options)
Convert OSM/Overpass XML to Shape objects.
Options
All conversion functions accept these optional parameters:
| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| filter_used_refs | bool | True | Filter unused references (False returns all geometry) |
| log_level | str | 'ERROR' | Logging level ('DEBUG', 'INFO', 'WARNING', 'ERROR') |
| area_keys | dict | None | Custom area key definitions (defaults from areaKeys.json) |
| polygon_features | list | None | Custom polygon feature whitelist/blacklist (defaults from polygon-features.json) |
| raise_on_failure | bool | False | Raise exception on geometry conversion failure |
Helper Functions
overpass_call(query)
Execute Overpass API query (with 5 automatic retries).
result = osm2geojson.overpass_call('[out:json];node(50.746,7.154,50.748,7.157);out;')
shape_to_feature(shape_obj, properties)
Convert Shape object to GeoJSON Feature.
feature = osm2geojson.shape_to_feature(
shape_obj=shapely_shape_object,
properties={'custom': 'property'}
)
Shape Objects
Shape objects are dictionaries containing Shapely geometry and OSM properties:
{
'shape': Point | LineString | Polygon, # Shapely geometry
'properties': {
'type': 'node' | 'way' | 'relation',
'tags': { ... }, # OSM tags
'id': 123,
...
}
}
Examples
Convert OSM XML to GeoJSON
import osm2geojson
with open('data.osm', 'r', encoding='utf-8') as f:
xml = f.read()
geojson = osm2geojson.xml2geojson(xml, filter_used_refs=False, log_level='INFO')
# Returns: { "type": "FeatureCollection", "features": [ ... ] }
Convert Overpass JSON to Shapes
import json
import osm2geojson
with open('overpass.json', 'r', encoding='utf-8') as f:
data = json.load(f)
shapes = osm2geojson.json2shapes(data)
# Returns: [ { "shape": <Shapely geometry>, "properties": {...} }, ... ]
# Access geometry and properties
for shape_obj in shapes:
geometry = shape_obj['shape'] # Shapely object
osm_tags = shape_obj['properties']['tags']
print(f"Type: {geometry.geom_type}, Tags: {osm_tags}")
Query Overpass API Directly
import osm2geojson
# Overpass QL query
query = """
[out:json];
(
node["amenity"="restaurant"](50.746,7.154,50.748,7.157);
way["amenity"="restaurant"](50.746,7.154,50.748,7.157);
);
out body geom;
"""
result = osm2geojson.overpass_call(query)
geojson = osm2geojson.json2geojson(result)
Development
Quick Start
# Clone with submodules
git clone --recurse-submodules https://github.com/aspectumapp/osm2geojson.git
cd osm2geojson
# One-command setup (installs deps + pre-commit hooks)
make setup
Development Workflow
make format # Auto-format code with Ruff
make lint # Check code quality
make test # Run tests with pytest
make all # Run all checks (do this before committing!)
Run Specific Tests
# Single test (unittest-style class)
pytest tests/test_main.py::TestOsm2GeoJsonMethods::test_barrier_wall -vv
# Test file
pytest tests/test_main.py -vv
# By pattern
pytest -k barrier -vv
# With coverage
make test-coverage
Update Polygon Features
./update-osm-polygon-features.sh
Releasing
See RELEASE_GUIDE.md for the release process.
Quick version bump:
./bump_version.sh 0.3.0 # Updates version, commits, and tags
git push origin master --tags
# Then create GitHub Release to publish to PyPI
Contributing
See CONTRIBUTING.md for detailed development guidelines.
Documentation
- CONTRIBUTING.md - Development setup, workflow, and guidelines
- AI_AGENT_GUIDE.md - Comprehensive guide for AI coding assistants
- MIGRATION_NOTES.md - Guide for migrating from old setup
- RELEASE_GUIDE.md - Release process for maintainers
Project Structure
osm2geojson/
├── osm2geojson/ # Main package
│ ├── main.py # Core conversion logic
│ ├── parse_xml.py # XML parsing
│ ├── helpers.py # Helper functions
│ └── __main__.py # CLI interface
├── tests/ # Test suite
├── pyproject.toml # Project config (deps, tools)
├── Makefile # Development commands
└── README.md # This file
Technology Stack
- Python: 3.8+
- Shapely: Geometric operations
- Requests: Overpass API calls
- Ruff: Fast linting & formatting
- pytest: Modern testing framework
- mypy: Type checking
License
Credits
Developed by rapkin
Uses data from:
- osm-polygon-features - Polygon feature definitions
- id-area-keys - Area key definitions
ToDo
- Rewrite _convert_shapes_to_multipolygon (and other multipolygon methods) to support complex situations with enclaves
- Add tests and examples for cli tool
- Add actions related to cli tool (more info https://github.com/aspectumapp/osm2geojson/pull/32#issuecomment-1073386381)
