This release is a pre-release and may not be stable for production use.
osm2geojson
Convert OpenStreetMap and Overpass API data (JSON or XML) to GeoJSON or Shapely geometries.
Output closely matches osmtogeojson (the JavaScript converter used by overpass-turbo), verified by a compatibility suite.
Highlights:
- Assembles full geometries from raw OSM elements: multipolygon and boundary relations, routes, ways and POI nodes
- Accepts Overpass JSON, Overpass XML and plain OSM XML, including
out centerandout bbresponses - Produces a GeoJSON
FeatureCollectionor a list of Shapely shapes with properties — ready for GIS pipelines or rendering - Ships a command-line tool (
osm2geojson) - Lightweight: the only dependencies are
shapelyandrequests
Installation
pip install osm2geojson
Requires Python 3.8+.
Quick start
import osm2geojson
# Fetch data from the Overpass API and convert it
xml = osm2geojson.overpass_call('rel(448930); out geom;')
geojson = osm2geojson.xml2geojson(xml)
# Or convert a local OSM/Overpass file
with open('data.osm', encoding='utf-8') as f:
geojson = osm2geojson.xml2geojson(f.read())
Command-line interface
osm2geojson map.osm map.geojson -i 2 # convert a file, pretty-printed
osm2geojson data.json - # Overpass JSON to stdout
Run osm2geojson --help for all options (input format autodetect/override,
indentation, custom area/polygon definitions, verbosity).
API reference
Conversion functions
| Function | Input | Output |
|---|---|---|
json2geojson(data, **options) |
Overpass JSON (dict or str) | GeoJSON FeatureCollection |
xml2geojson(xml_str, **options) |
OSM/Overpass XML | GeoJSON FeatureCollection |
json2shapes(data, **options) |
Overpass JSON (dict or str) | list of Shape objects |
xml2shapes(xml_str, **options) |
OSM/Overpass XML | list of Shape objects |
All conversion functions accept these optional keyword-only parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
filter_used_refs |
bool | True |
Drop elements that are only used as parts of other features (False returns everything) |
log_level |
str | None |
Set the library logger level for this call ('DEBUG', 'INFO', ...); None leaves your logging configuration untouched |
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 ConversionError on geometry conversion failure instead of skipping the element |
Conversion functions never modify the data passed to them.
Shape objects
json2shapes/xml2shapes return dictionaries pairing a Shapely geometry with
the OSM properties:
{
'shape': Point | LineString | Polygon | ..., # Shapely geometry
'properties': {
'type': 'node' | 'way' | 'relation',
'tags': { ... },
'id': 123,
...
}
}
Use shape_to_feature(shape_obj, properties) to turn a Shape object back into
a GeoJSON Feature.
overpass_call(query, **options)
Execute an Overpass QL query and return the raw response text:
result = osm2geojson.overpass_call('[out:json];node(50.746,7.154,50.748,7.157);out;')
Optional keyword-only parameters:
| Parameter | Type | Default | Description |
|---|---|---|---|
endpoint |
str | overpass-api.de | Overpass API endpoint URL |
timeout |
float | 180 |
Timeout in seconds for each HTTP request |
retries |
int | 5 |
Retries on rate limiting (429), transient server errors (5xx), timeouts and connection errors; other errors fail immediately (0 disables retrying) |
retry_delay |
float | 5 |
Seconds to sleep between attempts |
Examples
Query the Overpass API and convert to GeoJSON
import osm2geojson
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)
Work with Shapely geometries
import json
import osm2geojson
with open('overpass.json', encoding='utf-8') as f:
data = json.load(f)
shapes = osm2geojson.json2shapes(data)
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}")
Upgrading to 1.0
Version 1.0 changed the produced GeoJSON (to match osmtogeojson) and made converter options keyword-only. See the CHANGELOG for what changed and MIGRATION_NOTES.md for upgrade help.
Development
git clone https://github.com/rapkin/osm2geojson.git
cd osm2geojson
make setup # one-command setup (installs deps + pre-commit hooks)
make all # format, lint and test (do this before committing!)
Submodules (osm-polygon-features, id-area-keys) are optional - they are
only needed to regenerate the bundled JSON data (update-osm-polygon-features.sh).
Fetch them with git submodule update --init when needed.
- CONTRIBUTING.md - development setup, workflow and guidelines
- AI_AGENT_GUIDE.md - codebase guide for AI coding assistants
- RELEASE_GUIDE.md - release process for maintainers
License
Credits
Developed by rapkin
Uses data from:
- osm-polygon-features - polygon feature definitions
- id-area-keys - area key definitions (extracted from the iD editor's tagging schema)
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file osm2geojson-1.0.0rc1.tar.gz.
File metadata
- Download URL: osm2geojson-1.0.0rc1.tar.gz
- Upload date:
- Size: 25.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b2400bec4db9b48637d944c14388ff3320141719a630c317642b7bbd7e1b75f
|
|
| MD5 |
abdf5651e5279f7ab10207e8820c40f1
|
|
| BLAKE2b-256 |
9989afc2327bf93165bbb073a2b1db12bab77a093be08c22f6d1c3248ca703a1
|
Provenance
The following attestation bundles were made for osm2geojson-1.0.0rc1.tar.gz:
Publisher:
pythonpublish.yml on rapkin/osm2geojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osm2geojson-1.0.0rc1.tar.gz -
Subject digest:
3b2400bec4db9b48637d944c14388ff3320141719a630c317642b7bbd7e1b75f - Sigstore transparency entry: 2194955879
- Sigstore integration time:
-
Permalink:
rapkin/osm2geojson@ab6c551935eb978de9826ddc3f5ac60bad0df7e8 -
Branch / Tag:
refs/tags/v1.0.0rc1 - Owner: https://github.com/rapkin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@ab6c551935eb978de9826ddc3f5ac60bad0df7e8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file osm2geojson-1.0.0rc1-py3-none-any.whl.
File metadata
- Download URL: osm2geojson-1.0.0rc1-py3-none-any.whl
- Upload date:
- Size: 22.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a72de0e17fc57acb043cd68cafcbbd4b580518b1ddaa7aa27c58e45b0744870b
|
|
| MD5 |
385aeb9762ee107dad89c3c0272ded9e
|
|
| BLAKE2b-256 |
1864af183b696df2e4e807294e2ef30e23818c284cd10633463e607bd9eee638
|
Provenance
The following attestation bundles were made for osm2geojson-1.0.0rc1-py3-none-any.whl:
Publisher:
pythonpublish.yml on rapkin/osm2geojson
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
osm2geojson-1.0.0rc1-py3-none-any.whl -
Subject digest:
a72de0e17fc57acb043cd68cafcbbd4b580518b1ddaa7aa27c58e45b0744870b - Sigstore transparency entry: 2194955889
- Sigstore integration time:
-
Permalink:
rapkin/osm2geojson@ab6c551935eb978de9826ddc3f5ac60bad0df7e8 -
Branch / Tag:
refs/tags/v1.0.0rc1 - Owner: https://github.com/rapkin
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
pythonpublish.yml@ab6c551935eb978de9826ddc3f5ac60bad0df7e8 -
Trigger Event:
release
-
Statement type: