Last active
July 23, 2025 22:50
-
-
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
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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