Een kaart met de meest recente Streetview opnamedata per straat: hoe begin je daaraan?

DEZE BLOGPOST WERD OP 29/12/2020 GEÜPDATET, OMDAT DE OUDE API NIET MEER WERKTE. ER KAN VANAF NU EEN OFFICIËLE API VAN GOOGLE GEBRUIKT WORDEN. AANPASSINGEN WERDEN OP 29/12/2020 IN HET ROOD AANGEDUID.

Mijn werkwijze om een overzichtskaart te maken van de meest recente data waarvoor er Google Streetview beelden beschikbaar zijn, bestaat uit verschillende stappen. Kort samengevat komt het er op neer dat ik voor elke locatie apart aan Google vraag of er een Streetview beeld beschikbaar is en daarna al de antwoorden daarop op een kaart zet. De technische uitleg van hoe ik het aangepakt heb, vind je hieronder.

Stratenplan

Omdat de Streetview beelden in de meeste gevallen gemaakt zijn op straat, start ik met een kaartlaag van de straten in de gemeente. Gelukkig zijn er verschillende databronnen beschikbaar die dit soort gegevens als open data beschikbaar stellen. 

Ik heb gebruik gemaakt van de wegverbindingen-kaartlaag (Wvb) van het Grootschalig ReferentieBestand (GRB) van Informatie Vlaanderen. Deze kaartlaag wordt aan iedereen ter beschikking gesteld met de Vlaamse Open Data licentie v1.2. Deze kaartlaag is gratis en legaal te downloaden op download.agiv.be. Je zou ook gebruik kunnen maken van OpenStreetMap Data. Meer informatie daarover kan je vinden op wiki.openstreetmap.org

Ik heb in de downloadapplicatie van Informatie Vlaanderen (voorheen AGIV) alleen de gegevens van de gemeente gedownload, maar met behulp van QGIS (qgis.org) kan je ook een clip uitvoeren op een groter stratenplan, zodat je alleen de straten van de gemeente overhoudt.

Kaartlaag te controleren punten

Een stratenplan is meestal een polylijnen kaartlaag, maar voor mijn bevragingen aan Google heb ik de XY-coördinaten nodig van een punt. Daarom moest ik de kaartlaag van het stratenplan omzetten naar een puntenlaag. Hiervoor heb ik gebruik gemaakt van QGIS en de plugin “Locate points along lines” die te downloaden is via de officiële repository van QGIS plugins. Met behulp van deze plugin heb ik op alle straten om de 5 meter een punt gezet en al deze punten opgeslagen in een nieuwe puntenkaartlaag. In die kaartlaag heb ik 2 kolommen toegevoegd met daarin de X- en Y-coördinaten in WGS84. Het is wel belangrijk dat er een punt gebruikt wordt in plaats van een komma voor kommagetallen, omdat Google dat verwacht. Daarnaast heb ik ook een veld puntID toegevoegd met daarin voor elk punt een unieke nummer.

Aanmaken MySQL tabel

Als databank gebruik ik MySQL, omdat ik voor de controles gebruik maak van PHP en dat eenvoudig samenwerkt met MySQL, maar je kan evengoed gebruik maken van bijvoorbeeld PostgreSQL of een andere databank. Ik heb in MySQL een tabel aangemaakt met de velden “puntID”, “X”, “Y”, “Xgoogle”, “Ygoogle”, “DatumStreetview” en “ControleDatum”. Het veld “puntID” is de primaire sleutel en kreeg een index toegekend.

De tabel van de kaartlaag met de controlepunten heb ik omgezet naar een CSV-bestand, omdat dat via phpMyAdmin eenvoudig te importeren is. De coördinaten uit de databank komen in de velden “X” en “Y” en het unieke nummer in de databank komt in het veld “puntID”. 

Nu heb ik een MySQL tabel met daarin een massa records waarvan de velden “puntID”, “X” en “Y” ingevuld zijn en waarvan de andere velden leeg zijn.

Uitvoeren controles

Op 29/12/2020 heb ik gemerkt dat de oude onofficiële API van Google niet meer werkt. Ondertussen heeft Google wel een officiële API waarmee dezelfde informatie opgevraagd kan worden. Het nadeel hiervan is wel dat je in de Google Cloud Console een API key voor de “Street View Static API” moet aanvragen en dat je je betaalgegevens moet ingeven in de “Billing” module van de Google Cloud Console. Gelukkig is het gratis om metadata van Streetview gegevens op te vragen. Het opvragen van Streetviewbeelden zelf via de API kost wel geld. Omdat een API key persoonlijk is en omdat daar betaalgegevens aan gekoppeld zijn, vervang ik mijn API key in dit artikel door MyApiKey, maar als je deze methode zelf wil gebruiken, moet je uiteraard je eigen API key gebruiken.

In de oude API werd een XML-bestand opgevraagd, in de nieuwe API kan alleen een JSON-bestand opgevraagd worden, dus ik moest mijn script een beetje aanpassen om het opnieuw te laten werken.

Wat ik doe, is voor elk van de punten in de databank de url van de API bevragen. Hiervoor heb ik een PHP-script gemaakt dat een punt controleert en de informatie per punt opslaat in de MySQL databank. De lat- en lng-gegevens uit het JSON-bestand sla ik op in de velden “Xgoogle” en “Ygoogle”. Het gegeven date uit het JSON-bestand sla ik op in het veld “DatumStreetview”. De huidge datum en tijd bij controle sla ik op in het veld “ControleDatum”. Door te sorteren op het veld “ControleDatum” zorg ik er voor dat steeds het punt gecontroleerd wordt dat al het langst niet meer gecontroleerd werd. Op deze manier kan ik de gegevens steeds up-to-date houden.

Deze API kan via de volgende url bevraagd worden: https://maps.googleapis.com/maps/api/streetview/metadata?location=$y,$x&key=MyApiKey waarbij ik $y en $x vervang door de Y en X coördinaten in WGS84 (de volgorde van Y en X is van belang). Door naar die url te gaan, verkrijg ik een JSON bestand met daarin de nodige info.

Dit resulteert dan bijvoorbeeld in volgend JSON-bestand:

{
   "copyright" : "© Google",
   "date" : "2020-08",
   "location" : {
      "lat" : 51.22039286329926,
      "lng" : 4.359739876319615
   },
   "pano_id" : "KGJzmAhMdJs290cBSG7A-g",
   "status" : "OK"
}

Je mag 30.000 meta-data bevragingen per minuut doen, voordat je geblokkeerd zou worden. Ik voer de script 24 uur per dag elke 2 minuten uit met behulp van een CRON-job om mijn webserver niet te overbelasten. Dus het duurt wel even om alle punten te controleren.

Voor de controles maak ik gebruik van een niet-officiële API van Google. Het voordeel van deze API is dat je er detailinformatie kan opvragen van Streetview-beelden, maar het grote nadeel is dat je nooit weet hoe lang deze nog blijft werken, want Google kan zonder aankondiging of reden de API stopzetten of de toegang blokkeren. Het is dus een API van Google zelf, maar deze is niet publiekelijk gedocumenteerd. 

Deze API kan via de volgende url bevraagd worden: https://maps.google.com/cbk?output=xml&ll=$y,$x waarbij ik $y en $x vervang door de Y en X coördinaten in WGS84 (de volgorde van Y en X is van belang). Door naar die url te gaan, verkrijg ik een XML bestand met daarin de nodige info. Een voorbeeld hiervan kan je hier zien: https://maps.google.com/cbk?output=xml&ll=51.154733,4.445684.

Wat ik doe, is voor elk van de punten in de databank de url van de API bevragen. Hiervoor heb ik een PHP-script gemaakt dat een punt controleert en de informatie per punt opslaat in de MySQL databank. De lat- en lng-gegevens uit het XML-bestand sla ik op in de velden “Xgoogle” en “Ygoogle”. Het gegeven image_date uit het XML-bestand sla ik op in het veld “DatumStreetview”. De huidge datum en tijd bij controle sla ik op in het veld “ControleDatum”. Door te sorteren op het veld “ControleDatum” zorg ik er voor dat steeds het punt gecontroleerd wordt dat al het langst niet meer gecontroleerd werd. Op deze manier kan ik de gegevens steeds up-to-date houden.

Ik beperk het aantal punten per bevraging om te voorkomen dat Google de toegang tot de API blokkeert voor de script die ik gebruik. Omdat het geen officiële API is, is het ook niet duidelijk hoeveel bevragingen je per dag mag doen, voordat je geblokkeerd zou worden. Ik voer de script 24 uur per dag elke minuut uit met behulp van een CRON-job. Met een simpel rekensommetje bereken je dat je op deze manier 1440 punten per dag kan controleren. Voor Edegem bijvoorbeeld heb ik 17074 controlepunten in de databank zitten, dus het duurt met deze opstelling bijna 12 dagen om alle punten te controleren.

Gebruik van de gegevens in GIS

Om de gegevens uit de MySQL databank in te lezen in QGIS zet ik ze om naar geojson met behulp van GeoPHP. In de databank wordt de Streetview per maand opgeslagen, zoals bijvoorbeeld 08-2015, maar op mijn kaart wil ik ze per jaar een kleur geven, daarom wordt het jaartal in de geojson al als apart veld opgenomen. QGIS heeft het voordeel dat het rechtstreeks geojson-bestanden vanop het internet kan inlezen. Hierdoor zal QGIS steeds de meest recente gegevens uit de MySQL databank zien, want nadat alle punten bevraagd zijn bij Google, blijf ik deze controleren omdat Google ook steeds zijn Streetview gegevens blijft updaten. Om in QGIS een geojson-url in te lezen klik je op “Add Vector Layer”/”Vectorlaag toevoegen”. In het menu dat dan opent selecteer je “Protocol”, als type selecteer je “GeoJSON” en in het vakje “URI” vul je de geojson-url in.

In QGIS kleur ik in met behulp van simpele bolletjes die ik per jaar een kleur geef, waarbij ik de oudste jaren roodtinten geef en de meest recente jaren groentinten. In de opmaak van de legende gebruik “Symbol levels”/”Symboollagen” waardoor ik de meest recente jaren steeds bovenaan weergeef. Daarna is het alleen nog een kwestie van de kaart met legende en titels te exporteren. Het resultaat kan je zien op: stuyts.xyz/nederlands/streetview-edegem-1

English version of this article

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *

Deze site gebruikt Akismet om spam te verminderen. Bekijk hoe je reactie-gegevens worden verwerkt.