OpenStreetMap: Get the building (way/relation) that encloses a node using the QLever SPARQL endpoint

When investigating commercially available location data, I use outlines of buildings from OpenStreetMap a lot.

The OpenStreetMap gives this context and transforms the raw data to information. For example, on the screenshot you can see the Bundesnachrichtendient in Berlin, the foreign intelligence service. I can download that orange line as a polygon.

But sometimes, this is not enough. Take this scenario: A company has its office or shop in a building that it shares with others. This occurs often in urban areas where different organizations or comanies rent space in the same building.

A simple example from Munich: There is a pharmacy in the building of the city hall: https://www.openstreetmap.org/node/254057401.

How can I get the enclosing building?

On a Wednesday afternoon in December 2024 I was not able to write the query in Overpass Turbo that solves this task. Luckily, the next day I attended a Wikidata workshop organised by WikiMuc about Federated Queries. One of the talks was by Hannah Bast called „Federated Queries with QLever“. Bast is a professor at the University of Freiburg, she holds the Chair for Algorithms and Data Structures.

QLever is a SPARQL engine that allows us to query multiple data sources from one endpoint, e.g. Wikidata and OpenStreetMap. On Github the developers describe QLever as „a very fast SPARQL engine, much faster than most existing engines. It can handle graphs with more than hundred billion triples on a single machine with moderate resources.“ I took advantage of the moment and asked her how she would write the query in QLever to get the corresponding building of a node. Bast wrote the query live in no time. She truly lived up to her reputation.

So, let’s return to the pharmacy in Munich. Let’s generalize the question a bit and query for all pharmacies in Munich that are nodes and get their enclosing buildings:

Link to QLever query

PREFIX osmkey: <https://www.openstreetmap.org/wiki/Key:>
PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>
PREFIX wd: <http://www.wikidata.org/entity/>
PREFIX wdt: <http://www.wikidata.org/prop/direct/>
PREFIX geo: <http://www.opengis.net/ont/geosparql#>
PREFIX osm2rdfkey: <https://osm2rdf.cs.uni-freiburg.de/rdf/key#>
PREFIX ogc: <http://www.opengis.net/rdf#>
PREFIX osm: <https://www.openstreetmap.org/>
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
PREFIX osmrel: <https://www.openstreetmap.org/relation/>
SELECT DISTINCT ?osm_id ?type ?building ?building_geometry WHERE {
  {
    osmrel:62428 ogc:sfContains ?osm_id .
    ?osm_id osmkey:amenity 'pharmacy' .
    ?osm_id rdf:type ?type .
    ?osm_id rdf:type osm:node .
    ?building ogc:sfContains ?osm_id .
    ?building osmkey:building [] .
    ?osm_id geo:hasCentroid/geo:asWKT ?node_geometry .
    ?building geo:hasGeometry/geo:asWKT ?building_geometry .
  }
}

The result on a map:

And how about the pharmacy in the city hall? QLever returns the whole city hall, not just the part that can be seen in the screenshot above. Why? That little part is not a building in OSM, since it’s a part of a building, see here the edit: „building=yes Tags entfernt, da es sich um Gebäudeteile handelt“.

This clearly shows that such a query and the spatial joins based on it make the results less certain – but perhaps also reveal connections that would not have been found otherwise.

Links

Schreibe einen Kommentar