A Python interface to the OpenStreetMap Overpass API for querying geographical data
—
Helper utilities for working with OpenStreetMap data, including functions for converting between different ID formats used in the OpenStreetMap ecosystem.
Convert OpenStreetMap IDs to Overpass API format for use in queries.
class Utils:
@staticmethod
def to_overpass_id(osmid: int, area: bool = False) -> int:
"""
Convert OSM ID to Overpass ID format.
The Overpass API uses different ID ranges for different object types.
This function converts standard OSM relation/area IDs to the format
expected by Overpass queries.
Args:
osmid: OpenStreetMap ID (integer)
area: If True, convert to area ID format; if False, convert to relation ID format
Returns:
Overpass ID in the appropriate format:
- For areas: osmid + 2400000000
- For relations: osmid + 3600000000
"""import overpass
# Convert relation ID to Overpass format
osm_relation_id = 123456
overpass_relation_id = overpass.Utils.to_overpass_id(osm_relation_id)
print(f"OSM relation {osm_relation_id} -> Overpass ID {overpass_relation_id}")
# Output: OSM relation 123456 -> Overpass ID 3600123456
# Convert area ID to Overpass format
osm_area_id = 789012
overpass_area_id = overpass.Utils.to_overpass_id(osm_area_id, area=True)
print(f"OSM area {osm_area_id} -> Overpass ID {overpass_area_id}")
# Output: OSM area 789012 -> Overpass ID 2400789012
# Use in queries
api = overpass.API()
# Query using converted relation ID
relation_query = f'relation({overpass_relation_id});'
response = api.get(relation_query)
# Query using converted area ID
area_query = f'node(area:{overpass_area_id})[amenity=restaurant];'
response = api.get(area_query)def query_restaurants_in_city(api, city_relation_id):
"""
Query restaurants in a city using its OSM relation ID.
Args:
api: Overpass API instance
city_relation_id: OpenStreetMap relation ID for the city
Returns:
GeoJSON response with restaurant data
"""
# Convert OSM relation ID to Overpass area ID
area_id = overpass.Utils.to_overpass_id(city_relation_id, area=True)
# Query restaurants in the area
query = f'node(area:{area_id})[amenity=restaurant];'
return api.get(query)
# Example usage
api = overpass.API()
# Salt Lake City relation ID from OpenStreetMap
salt_lake_city_id = 161645 # This is the actual OSM relation ID
restaurants = query_restaurants_in_city(api, salt_lake_city_id)
print(f"Found {len(restaurants['features'])} restaurants")
for restaurant in restaurants['features']:
name = restaurant['properties'].get('name', 'Unnamed')
cuisine = restaurant['properties'].get('cuisine', 'Unknown')
print(f"- {name} ({cuisine})")OpenStreetMap uses different ID spaces for different object types:
The Overpass API uses offset ID ranges to distinguish object types in certain contexts:
# Constants used in ID conversion (for reference)
AREA_BASE = 2400000000 # Added to OSM relation ID for area queries
RELATION_BASE = 3600000000 # Added to OSM relation ID for relation queriesArea Queries: When querying for objects within an administrative boundary:
# Query amenities within a city boundary
area_id = overpass.Utils.to_overpass_id(city_relation_id, area=True)
query = f'node(area:{area_id})[amenity];'Relation Queries: When specifically querying relation objects:
# Query a specific relation
relation_id = overpass.Utils.to_overpass_id(osm_relation_id)
query = f'relation({relation_id});'Node/Way Queries: Use original OSM IDs (no conversion needed):
# Query specific nodes or ways
query = f'node({osm_node_id});'
query = f'way({osm_way_id});'Install with Tessl CLI
npx tessl i tessl/pypi-overpass