Kadaster SPARQL Hands-on Sessie


Wouter Beek wouter@triply.cc

Jesse Bakker Jesse.Bakker@kadaster.nl

6 Februari, 2018

Wat is Linked Data?

World Wide Web: Web of Documents 🖺

Linked Data: Web of data 🖼

Linked Data 5 sterren

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

Deel I: De eerste SPARQL vraag

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#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?wkt ?wktLabel {
  ?plaats1 rdfs:label "Swalmen"^^xsd:string ;
           brt:isBAGwoonplaats true ;
           geo:hasGeometry/geo:asWKT ?wkt .
  service <https://dbpedia.org/sparql> {
    ?plaats2 rdfs:label "Swalmen"@nl ; foaf:depiction ?vlag . }
  }
}
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#>
prefix xsd: <http://www.w3.org/2001/XMLSchema#>
select ?wkt ?wktLabel {
  ?plaats1 rdfs:label "Apeldoorn"^^xsd:string ;
           brt:isBAGwoonplaats true ;
           geo:hasGeometry/geo:asWKT ?wkt .
  service <https://dbpedia.org/sparql> {
    ?plaats2 rdfs:label "Apeldoorn"@nl .
    optional { ?plaats2 foaf:depiction ?vlag . }
  }
}
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
            

Kadaster SPARQL

Productie endpoint:
https://data.pdok.nl/sparql

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


Dank voor het meedoen!