OverPass API

How many restaurants in Stuttgart Mitte actually serve vegan food? This could be solved using the Overpass QL on the overpass turbo website. But I wanted to use this from Python by using OSMPythonTools. The positive of this Python package: It has a query builder. Overpass QL doesn't come naturally, at least for me. To get the bounding box I used bbox-tool. Additionally I may want to use this in a SpatiaLite SQLite database later, so having GeoJson already simplifies that.

Annotated Python code:

import json
# pip install OSMPythonTools
from OSMPythonTools import overpass

api = overpass.Overpass()
# bbox for Stuttgart Mitte (roughly)
bbox_coords = [48.76605, 9.1657, 48.78508, 9.18995]
query = overpass.overpassQueryBuilder(
    bbox=bbox_coords,
    elementType=["node", "way"],
    # all restaurants that have a positive diet:vegan tag
    selector=['"amenity"="restaurant"', '"diet:vegan"~"yes|only"'],
    out="body",
    # include geometry, to export as GeoJson
    includeGeometry=True,
)
result = api.query(query, timeout=60)

data = []
# each element and the json version of it
for item_xml, item_json in zip(result.elements(), result.toJSON()["elements"]):
    # add the geometry to the json version
    item_json["geojson"] = item_xml.geometry()
    data.append(item_json)

# dump as json for later usage
json.dump(
    data,
    open("vegan__" + "_".join([str(i) for i in bbox_coords]) + ".json", "w"),
    indent=2,
)

One example result looks like this (random example; no testimonial):

{
  "type": "node",
  "id": 2998162386,
  "lat": 48.7727435,
  "lon": 9.1766046,
  "tags": {
    "amenity": "restaurant",
    "check_date:diet:vegan": "2022-09-25",
    "diet:vegan": "yes",
    "diet:vegetarian": "yes",
    "name": "reiskorn",
    "opening_hours": "Su-Th 17:00-22:00; Fr 17:00-23:00; Sa 12:00-23:00",
    "phone": "+497116647633",
    "website": "http://www.das-reiskorn.de/"
  },
  "geojson": {
    "type": "Point",
    "coordinates": [
      9.176605,
      48.772743
    ]
  }
}

The geojson part can be points or polygons, depending on if this was a node or a way.

For this bounding box (Stuttgart Mitte) only 14 restaurants are found! 😞