GeoDesk for Python
| GeoDesk for Python | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Author: | Clarisma / GeoDesk contributors | |||||||||||||||||||
| License: | GNU LGPL v3 | |||||||||||||||||||
| Version: | 2.1.2 (2025-12-10) | |||||||||||||||||||
| Language: | python
| |||||||||||||||||||
| Website: | https://docs.geodesk.com/python | |||||||||||||||||||
| Source code: | https://github.com/clarisma/geodesk-py | |||||||||||||||||||
|
Python SDK for querying, analyzing and visualizing OpenStreetMap data stored in Geo-Object Libraries (GOLs) | ||||||||||||||||||||
| ||||||||||||||||||||
GeoDesk for Python is a Python library for fast querying, analysis, and visualization of OpenStreetMap data. It is part of the GeoDesk toolkit and provides a Pythonic API for working with Geographic Object Libraries (GOLs) — compact spatial databases designed specifically for OSM data.
GeoDesk for Python is also available for Java and for C++.
Overview
GeoDesk for Python allows developers to query, analyze, display and transform OpenStreetMap features using Python. It works directly with GOL files (no server process required) and returns native Python objects instead of requiring object-relational mapping. Key characteristics include:
- Compact storage — GOL files are only 20% to 50% larger than OSM-PBF source data, less than a tenth of the storage consumed by a traditional SQL-based database.
- Fast queries — typically 50 times faster than SQL.
- Intuitive API — queries return Python objects. Quickly discover tags, way-nodes and relation members. Get a feature's geometry, measure its length/area.
- Full relation support — unlike traditional geospatial databases, GeoDesk natively handles relations, a unique and powerful aspect of OSM data.
- Shapely integration — seamless interoperability with Shapely for advanced geometric operations such as buffer, union, simplify, convex and concave hulls, Voronoi diagrams, and more.
- Modest hardware requirements — any 64-bit system that can run Python 3.9+ can run GeoDesk.
System Requirements
- Python 3.9 or above
- 64-bit system running Windows, macOS or Linux
- The GOL Tool is required to create or manage GOL files
Installation
Install via pip:
pip install geodesk
Pre-built binary wheels are available for Windows (x86-64), macOS (x86-64 and ARM64), and Linux (x86-64, including musl-based distributions).
You also need the GOL Tool to build or manage GOL files. See the GOL Tool download page for installation instructions.
Getting Started
Creating a GOL
Before using GeoDesk for Python, you need a Geo-Object Library (GOL) containing OSM data. You can create one from any .osm.pbf file using the GOL Tool:
gol build france france-latest.osm.pbf
Country and regional extracts can be downloaded from sites such as GeoFabrik or BBBike. Alternatively, you can download pre-made data tiles from a Geo-Object Bundle (e.g. from Open Planet Data) using the gol load command.
Opening a GOL
from geodesk import *
france = Features("france") # Opens france.gol
The Features object represents the entire set of features in the GOL.
Querying Features
Features can be filtered using GOQL (Geo-Object Query Language), a concise query syntax similar to MapCSS:
museums = france("na[tourism=museum]") # Nodes and areas tagged as museums
hydrants = france("n[emergency=fire_hydrant]") # Only nodes
highways = france("w[highway]") # Linear ways
The type selectors are: n (nodes), w (ways, excluding areas), a (areas, which can be ways or relations), r (relations, excluding areas), and * (any type).
Spatial Queries
Features can be filtered spatially using methods like within(), intersecting(), containing(), crossing(), and around():
# Get the administrative area for Paris
paris = france("a[boundary=administrative][admin_level=8][name=Paris]").one
# Find all museums within Paris
paris_museums = museums.within(paris)
# Find bus stops within 500 meters of a restaurant
nearby_stops = france("n[highway=bus_stop]").around(restaurant, meters=500)
# Find railway bridges crossing a river
bridges = france("w[railway][bridge]").crossing(river)
Bounding Box Queries
Features can also be restricted to a bounding box:
from geodesk import Box
paris_bounds = Box(west=2.2, south=48.8, east=2.5, north=48.9)
features_in_paris = france(paris_bounds)
Working with Features
Each Feature object represents an OSM element (node, way, or relation). Tags are accessed directly as attributes or via dictionary-style access:
>>> city.name
'Praha'
>>> city["name:en"]
'Prague'
>>> city.population
1275406
Properties
Features expose the following key properties:
osm_type—"node","way", or"relation"id— the feature's numeric OSM IDtags— all tags as key-value pairsis_node,is_way,is_relation,is_area— type testslon,lat— WGS-84 coordinatescentroid— the calculated centroidbounds— the bounding boxshape— the Shapely geometry (Point,LineString,Polygon, etc.)area— area in square meters (for polygonal features)length— length in meters (for lineal features) or circumference (for polygonal features)nodes— the nodes of a waymembers— the members of a relationparents— relations containing this feature, or ways that contain a given node
Feature Sets
Feature sets support iteration, counting, and aggregate properties:
>>> museums.count
4495
for hotel in hotels:
print(hotel.name)
Feature sets also provide geometric and topological filters:
min_area()/max_area()— filter by area sizemin_length()/max_length()— filter by lengthnodes_of(),members_of(),parents_of(),connected_to()— topological filters
Sets can be combined using the & operator or by calling one set with another as a filter.
Visualization
GeoDesk for Python can display features on interactive Leaflet-based web maps:
# Quick map display
paris_museums.map.show()
# Customized map with tooltips and links
map = Map()
map.tooltip = "{name}<br>{opening_hours}"
map.link = "{website}"
map.add(paris_museums, color="purple")
map.show()
Maps can be saved as self-contained HTML files:
map.save("museums-in-paris") # Creates museums-in-paris.html
Multiple feature sets can be added to the same map with different colors and styles.
Output Formats
Features and feature sets can be exported to standard geospatial formats:
- GeoJSON —
feature.geojsonorfeatures.geojson - GeoJSON Lines —
features.geojsonl(one feature per line) - Well-Known Text (WKT) —
feature.wktorfeatures.wkt
Output can be saved to files:
streets.geojson.save("london-streets") # Creates london-streets.geojson
Formatters support options for precision, pretty-printing, custom IDs, and output limits.
Example Code
Find all pubs in Zurich and print their names:
from geodesk import *
features = Features("switzerland")
zurich = features("a[boundary=administrative][admin_level=8][name:en=Zurich]").one
pubs = features("na[amenity=pub]")
for pub in pubs.within(zurich):
print(pub.name)
Find all movie theaters within 500 meters of a given point:
cinemas = features("na[amenity=cinema]").around(
meters=500, lat=47.37, lon=8.54)
Count the number of entrances of a building:
number_of_entrances = building.nodes("[entrance]").count
More examples (museums, streets, railway bridges, mailboxes, U.S. counties) are available in the documentation.
Documentation
Full documentation is available at docs.geodesk.com/python, covering:
- Quickstart guide
- Feature objects
- Sets of features and queries
- Map visualization
- Output formatters
- GOQL query language
See Also
- GeoDesk — main article covering the overall toolkit and GOL Tool
- Geographic Object Library — the GOL file format
- Geo-Object Bundle — format for distributing tiled OSM data
- GeoDesk for Java — the Java SDK
- GeoDesk for C++ — the C++ SDK
- Databases and data access APIs — other tools for accessing OSM data