Skip to content

Instantly share code, notes, and snippets.

@rasher
Last active July 23, 2025 22:50
Show Gist options
  • Save rasher/d0c6bb672b04bbef1986c73d5c1fe6f1 to your computer and use it in GitHub Desktop.
Save rasher/d0c6bb672b04bbef1986c73d5c1fe6f1 to your computer and use it in GitHub Desktop.
Parse a osm.pbf file (e.g. from https://download.geofabrik.de/) and output a csv file listing all populated places in it
#!/usr/bin/env python3
import osmium
import sys
import csv
from shapely.geometry import shape
PLACE_TYPES = [
"city",
"town",
"village",
"hamlet",
"isolated_dwelling", # These are often farms and such. Might want to skip.
]
def get_location(obj):
cnt = shape(obj.__geo_interface__["geometry"]).centroid
return {"lat": cnt.y, "lon": cnt.x}
def main(osmfile):
out_csv = csv.DictWriter(
sys.stdout, ["place", "lat", "lon", "name"], extrasaction="ignore"
)
out_csv.writeheader()
processor = (
osmium.FileProcessor(osmfile)
.with_filter(osmium.filter.KeyFilter("name"))
.with_filter(osmium.filter.TagFilter(*[("place", v) for v in PLACE_TYPES]))
.with_filter(osmium.filter.GeoInterfaceFilter())
.with_locations()
.with_areas()
)
for obj in processor:
tags = {k: v for k, v in obj.tags}
tags.update(get_location(obj))
out_csv.writerow(tags)
if __name__ == "__main__":
if len(sys.argv) != 2:
print("Usage: python %s <osmfile>" % sys.argv[0])
sys.exit(1)
exit(main(sys.argv[1]))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment