[diff:…] compares the answer of a query at two dates. compare(delta:id()) drops the elements that are in both answers, so only the restaurants that were added or removed remain.
This query compares the restaurants in the Niederdorf, the old town of Zürich east of the Limmat, on 1 January 2023 and 1 January 2025.
The query
[out:xml][timeout:60][diff:"2023-01-01T00:00:00Z","2025-01-01T00:00:00Z"]; nw(47.369,8.541,47.376,8.547)(if:t["amenity"]=="restaurant"); compare(delta:id()); out meta center;
Run it
Live result from overpass.ch, cached for up to 12 hours. Map data © OpenStreetMap contributors (ODbL).
How it works
[diff:"2023-01-01T00:00:00Z","2025-01-01T00:00:00Z"]runs the query on both dates. Diffs need[out:xml].(if:t["amenity"]=="restaurant")selects the restaurants. In history queries it is faster than a tag filter in square brackets.compare(delta:id())keeps the elements whoseid()differs between the two dates. An id never changes, so what remains is in only one of the two answers.<action type="create">is a restaurant that was added.<action type="delete">is one that was removed, with its version of the first date.- Removed does not always mean closed. Of the ten here, five were deleted, two are marked as disused, and three became a bar, a fast food place and an untagged point.
Variations
- Added does not always mean opened either: a restaurant may have existed for years before someone mapped it.
[adiff:…]adds the new version of each removed element, so you can see what it became: see changes in an area.- Shops instead:
(if:t["shop"]!=""). - A whole city:
area["name"="Zürich"]["admin_level"="8"]->.a;andnw(area.a). Five years of restaurants in Zürich took about 15 seconds.
Run it from your code
curl https://api.overpass.ch/v1/YOUR_API_KEY/interpreter \
--data-urlencode 'data@query.overpassql'
import requests
query = open("query.overpassql").read()
r = requests.post("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter",
data={"data": query}, timeout=120)
r.raise_for_status()
print(r.text)
const res = await fetch("https://api.overpass.ch/v1/YOUR_API_KEY/interpreter", {
method: "POST",
body: new URLSearchParams({ data: query }),
});
if (!res.ok) throw new Error(await res.text());
console.log(await res.text());
Save the query as query.overpassql. It works the same in Overpass Turbo, QGIS and JOSM.