Kadaster SPARQL Tutorial

Laatst gewijzigd op: 18 juni 2018

Instructies: Gebruik de pijltjestoetsen (, , , ) om door de presentatie te navigeren. Druk op de ESC toets voor een overzicht.


Kadaster Data Science Team

Wat is Linked Data?

Source: Tim Berners-Lee (http://5stardata.info)

Deel I: De eerste SPARQL bevraging

De eerste SPARQL vraag

select ?s ?p ?o {
  ?s ?p ?o
}
limit 5

Onderdelen:
projectie: select ?s ?p ?o
patroon: ?s ?p ?o .
limiet: limit 5

Verander de projectie

select ?o ?p ?s {
  ?s ?p ?o
}
limit 5

Verander de limiet

select ?s ?p ?o {
  ?s ?p ?o
}
limit 10

Voeg een offset toe

select ?s ?p ?o {
  ?s ?p ?o
}
limit 5
offset 5

Deel II: Naamgeving & Ambiguïteit

Alles heeft een naam

Maar soms hebben 2 verschillende dingen toch dezelfde naam…

Wat is ‘De Brug’? 🌉

select ?s {
  ?s ?p "De Brug"^^<http://www.w3.org/2001/XMLSchema#string> .
}
limit 100

"De Brug"^^<http://www.w3.org/2001/XMLSchema#string> is een literal.

<http://www.w3.org/2001/XMLSchema#string> is het datatype.

Wat is ‘De Brug’? 🌉

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?s {
  ?s ?p "De Brug"^^xsd:string .
}
limit 100

URI kunnen worden afgekort met prefix declaraties.

Nog meer dingen die ‘De Brug’ heten…

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?s {
  {
    ?s ?p "De Brug"^^xsd:string .
  } union {
    ?s ?p "De Brug"@nl .
  }
}
limit 100

"De Brug"@nl is een language-tagged string. Dit betekent dat "De Brug" geïnterpreteerd moet worden in het Nederlands (nl).

{ A } union { B } geeft aan dat de de resultaten van query A én de resultaten van query B willen.

Wat iets is kunnen we zien aan de klasse

prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select distinct ?klasse {
  {
    ?s ?p "De Brug"^^xsd:string ; a ?klasse .
  } union {
    ?s ?p "De Brug"@nl ; a ?klasse .
  }
}
limit 100

a’ duidt de relatie aan tussen een instantie en een klasse. ‘a’ is een afkorting voor rdf:type, wat een afkorting is voor <http://www.w3.org/1999/02/22-rdf-syntax-ns#>.

distinct laat alleen unieke resultaten zien.

;’ is een afkorting die de subject term herhaalt.

Deel III: Linked Geodata

🏙 Wat is Apeldoorn?

prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?s {
  ?s rdfs:label "Apeldoorn"@nl .
}
limit 100

rdfs:label geeft een menselijk interpreteerbare naam van een ding.

Ook klasses hebben een label

prefix rdfs: 
select ?s ?label {
  ?s rdfs:label "Apeldoorn"@nl ; a ?klasse .
  ?klasse rdfs:label ?label .
}limit 100

Merk op dat we ?klasse niet gebruiken in de projectie (zie volgende query).

Wat we niet gebruiken mogen we overslaan

prefix rdfs: 
select ?s ?label {
  ?s rdfs:label "Apeldoorn"@nl ; a/rdfs:label ?label .
}
limit 100

We slaan ?klasse uit de vorige query over.

X/Y is een property path.

Ambiguïteit + geografie

prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt ?wktLabel {
  ?s rdfs:label "Apeldoorn"@nl ;
     geo:hasGeometry/geo:asWKT ?wkt ;
     a/rdfs:label ?wktLabel .
}
limit 100

geo:hasGeometry/geo:asWKT geeft de Well-Known Text (WKT) representatie van een geometrie.

Merk op dat we verschillende vocabulaires door elkaar heen gebruiken: rdfs van W3C en geo van OGC.

🏙 Welke Apeldoorn bedoel je?

“Ik bedoel het registratief gebied”

prefix brt: <http://brt.basisregistraties.overheid.nl/def/top10nl#>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt ?wktLabel {
  ?instantie rdfs:label "Apeldoorn"@nl ;
             geo:hasGeometry/geo:asWKT ?wkt ;
             a brt:RegistratiefGebied .
}
limit 100

Deel IV: De BAG bevragen met SPARQL

BAG openbare ruimte

prefix <http://bag.basisregistraties.overheid.nl/def/bag#>
select ?openbareRuimte {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat"
}
limit 100

Openbare ruimtes die ‘Hofstraat’ heten.

BAG openbare ruimte + woonplaats

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
select ?openbareRuimte ?woonplaats {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
}
limit 100

Openbare ruimtes die ‘Hofstraat’ heten én hun bijbehorende woonplaats.

Menselijk leesbare labels

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
select ?openbareRuimte ?woonplaats ?label {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats bag:naamWoonplaats ?label .
}
limit 100

Weer ambiguïteit: er zijn heel veel openbare ruimtes die ‘Hofstraat’ heten.

Maak het patroon specifieker

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?openbareRuimte ?woonplaats {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl .
}
limit 100

De Hofstraat in Apeldoorn.

(Merk op: er zijn 2 openbare ruimtes; hierover later meer.)

Voeg nummeraanduiding toe

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?nummeraanduiding ?openbareRuimte {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats/rdfs:label "Apeldoorn"@nl .
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:huisnummer 110 .
}
limit 100

Met property path notatie (/) slaan we de niet gebruikte ?woonplaats over.

Voeg verblijfsobject en pand toe

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats/rdfs:label "Apeldoorn"@nl .
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:huisnummer 110 .
  ?verblijfsobject bag:hoofdadres ?nummeraanduiding ;
                   bag:pandrelatering ?pand .
  ?pand bag:geometriePand/geo:asWKT ?wkt .
}
limit 100

Maak patroon generieker

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt ?wktLabel {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats/rdfs:label "Apeldoorn"@nl .
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:huisnummer ?wktLabel .
  ?verblijfsobject bag:hoofdadres ?nummeraanduiding ;
                   bag:pandrelatering/bag:geometriePand/geo:asWKT ?wkt .
}
limit 100

Waarom zien we sommige panden dubbel?

Één pand kan meerdere verblijfsobjecten hebben

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wktVerblijfsobject ?wktVerblijfsobjectColor ?wktVerblijfsobjectLabel ?wktPand ?wktPandLabel {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats/rdfs:label "Apeldoorn"@nl .
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:postcode ?postcode ;
                    bag:huisnummer ?huisnummer .
  ?verblijfsobject bag:hoofdadres ?nummeraanduiding ;
                   geo:hasGeometry/geo:asWKT ?wktVerblijfsobject ;
                   bag:pandrelatering ?pand ;
                   a/rdfs:label ?label .
  ?pand bag:geometriePand/geo:asWKT ?wktPand .
  bind (concat('Hofstraat ',str(?huisnummer)) as ?wktPandLabel)
  bind (concat(?wktPandLabel,' ',str(?postcode),'
',str(?label)) as ?wktVerblijfsobjectLabel) bind ("red" as ?wktVerblijfsobjectColor) } limit 1000

Deel V: Federatie

Who uses Linked Data? (1/2)

Who uses Linked Data? (2/2)

Schema.org:

  • 20M web sites
  • 35% of pages in search index
  • 50% of US/EU eCommerce emails
  • 800B small graphs of ~25 statements
Source: A.W.Moore & R.V. Gua, Google Research

LOD Cloud: 2014

Er zijn heel veel andere Linked Datasets op het web.

LOD Cloud: 2017

We kunnen al deze Datasets bevragen met SPARQL.

BRT/BAG gemeente → DBpedia 🕸

prefix brt: <http://brt.basisregistraties.overheid.nl/def/top10nl#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?shape ?shapeLabel {
  bind("Amsterdam"@nl as ?naam)
  ?plaats1 rdfs:label ?naam ; brt:isBAGwoonplaats true ; geo:hasGeometry/geo:asWKT ?shape
  service <https://dbpedia.org/sparql> {
    ?plaats2 rdfs:label ?naam ; foaf:depiction ?vlag
  }
  bind(concat(
    '<h2>',str(?naam),'</h2>',
    if(bound(?vlag),concat('<img src="',replace(str(?vlag),'http://','https://'),'" style="max-width: 150px;">'),''),
    '<p>Externe representatie: <a href="',str(?plaats2),'">[DBpedia]</a></p>'
  ) as ?shapeLabel)
}
limit 1

service <URL> { A } betekent: voer query A uit op SPARQL endpoint URL, en voeg de resultaten samen.

Apeldoorn heeft geen vlag

prefix brt: <http://brt.basisregistraties.overheid.nl/def/top10nl#>
prefix foaf: <http://xmlns.com/foaf/0.1/>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?shape ?shapeLabel {
  bind("Apeldoorn"@nl as ?naam)
  ?plaats1 rdfs:label ?naam ; brt:isBAGwoonplaats true ; geo:hasGeometry/geo:asWKT ?shape
  service <https://dbpedia.org/sparql> {
    ?plaats2 rdfs:label ?naam
    optional { ?plaats2 foaf:depiction ?vlag }
  }
  bind(concat(
    '<h2>',str(?naam),'</h2>',
    if(bound(?vlag),concat('<img src="',str(?vlag),'" style="max-width: 150px;">'),''),
    '<p>Externe representatie: <a href="',str(?plaats2),'">[DBpedia]</a></p>'
  ) as ?shapeLabel)
}
limit 1

optional { A } betekent: voer A uit, indien mogelijk.

Met name nuttig voor ontbrekende waardes (data op het web is vaak onvolledig).

Deel VI:
Aggregatie

Oudste pand in Apeldoorn 👵👴

prefix bag: 
prefix geo: 
select ?wkt ?wktLabel {
  ?verblijfsobject bag:hoofdadres/bag:bijbehorendeOpenbareRuimte/bag:bijbehorendeWoonplaats/bag:naamWoonplaats "Apeldoorn" ;
                   bag:pandrelatering ?pand .
  ?pand bag:oorspronkelijkBouwjaar ?wktLabel ;
        bag:geometriePand/geo:asWKT ?wkt .
}
order by asc(?wktLabel)
limit 50

Deel VII: Versies in de BAG

Zijn er meerdere Apeldoorns?

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?openbareRuimte ?woonplaats {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl .
}
limit 100
openbareRuimtewoonplaats
openbare-ruimte:0200300022471548woonplaats:2247
openbare-ruimte:0200300022471548woonplaats:3560

BAG status

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?woonplaats ?status {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl ;
              bag:status ?status .
}
limit 100
woonplaatsstatus
woonplaats:2247begrip:WoonplaatsAangewezen
woonplaats:2247begrip:WoonplaatsIngetrokken
woonplaats:3560begrip:WoonplaatsAangewezen

Alleen huidige woonplaatsen

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix begrip: <http://bag.basisregistraties.overheid.nl/id/begrip/>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?openbareRuimte ?woonplaats {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl .
  filter not exists {
    ?woonplaats bag:status begrip:WoonplaatsIngetrokken .
  }
}
limit 100

Nu hebben we de juiste Apeldoorn.

BAG voorkomen

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix begrip: <http://bag.basisregistraties.overheid.nl/id/begrip/>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt ?begin ?eind {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl .
  filter not exists {
    ?woonplaats bag:status begrip:WoonplaatsIngetrokken .
  }
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:huisnummer 110 .
  graph ?voorkomen {
    ?verblijfsobject bag:hoofdadres ?nummeraanduiding .
  }
  ?verblijfsobject bag:pandrelatering/bag:geometriePand/geo:asWKT ?wkt .
  ?voorkomen bag:beginGeldigheid ?begin .
  optional {
    ?voorkomen bag:eindGeldigheid ?eind .
  }
}
limit 100

graph { A } betekent: voer query A uit binnen deelgraaf URI.

Huidig voorkomen

prefix bag: <http://bag.basisregistraties.overheid.nl/def/bag#>
prefix begrip: <http://bag.basisregistraties.overheid.nl/id/begrip/>
prefix geo: <http://www.opengis.net/ont/geosparql#>
prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#>
select ?wkt ?begin {
  ?openbareRuimte bag:naamOpenbareRuimte "Hofstraat" ;
                  bag:bijbehorendeWoonplaats ?woonplaats .
  ?woonplaats rdfs:label "Apeldoorn"@nl .
  filter not exists {
    ?woonplaats bag:status begrip:WoonplaatsIngetrokken .
  }
  ?nummeraanduiding bag:bijbehorendeOpenbareRuimte ?openbareRuimte ;
                    bag:huisnummer 110 .
  graph ?voorkomen {
    ?verblijfsobject bag:hoofdadres ?nummeraanduiding .
  }
  ?verblijfsobject bag:pandrelatering/bag:geometriePand/geo:asWKT ?wkt .
  ?voorkomen bag:beginGeldigheid ?begin .
  filter not exists {
    ?voorkomen bag:eindGeldigheid ?eind .
  }
}
limit 100

Dank voor het meedoen!

Data stories
https://data.labs.kadaster.nl/stories

Kadaster