Een Google Maps mashup van projecten in de buurt
Met ruim 80.000 verhuurbare eenheden is deze woningbouwcorporatie een grote speler aan het firmament. Maar de corporatie doet meer dan woningen verhuren. Zo zijn er tal van buurtprojecten waar ze een rol in speelt — stedelijke vernieuwing, groenprojecten, kunst in de buurt, monumenten en leefbaarheidsprojecten.
Ik bouw een demootje van een Google Maps kaart met bijzondere projecten in de buurt. Momenteel zijn de In de buurt activiteiten al te zien op de corporate website, maar we willen graag een wat ruimer bemeten uitvoering van de kaart bouwen.
De eerste vruchten van mijn noeste arbeid zijn beschikbaar: een schermvullende Google Map mashup met de bijzondere buurtprojecten. Er is nog veel werk aan de winkel, maar ik kan het niet laten er alvast wat over te vertellen.
api · ExtInfoWindow · Labeled Marker · maps · street view · webwerk
Spelen met GPolygon functionaliteit
De Google Maps API voorziet in de mogelijkheid om op basis van een aantal coordinaten een vorm op de kaart te zetten. Met behulp van het GPolygon object kun je bijvoorbeeld een vierkant, een veelhoek of een cirkel in een layer bovenop de kaart tekenen.
Over GPolygon cirkels wil ik het even hebben. An sich heb je aan een cirkeltje op een kaart natuurlijk niks. Maar een praktische toepassing van het GPolygon object is gemakkelijk te verzinnen. In mijn geval denk ik aan het tekenen van een cirkel met een bepaalde radius vanuit een middelpunts-coordinaat. Op basis van de gecreërde cirkel-overlay kun je vervolgens bepalen of een ander punt binnen het oppervlak van deze cirkel valt. Of juist niet.
Kijk, da’s handig om te weten. Voor mijn website met uitjes wil ik deze functionaliteit gebruiken om te bepalen of er in de buurt van een uitje nog meer spannends valt te beleven. Zeg maar een is dit misschien ook interessant voor u? functie. Ook op een nieuwe website van een vastgoedorganisatie komt dit soort functionaliteit – bij het op de kaart zetten van het vastgoedbezit – in de (nabije) toekomst wellicht van pas.
Okay. Genoeg gekletst. Check de demo om een idee te krijgen van waar ik het eigenlijk over heb …
api · GPolygon · location based · maps
Het Google Maps GPolygon object
Leuk. Spelen met de Google Maps API. Gaandeweg word je steeds wijzer.
Voorbeeldje: het GPolygon object in Google Maps stelt je in staat om een vorm op je GMap kaartje te tekenen. Nu is dat niet zo’n probleem als het een vierkant of een andere eenvoudige vorm is. Maar wat als je een overlay wilt maken in de vorm van de provincie Friesland? Ga je dan alle coordinaten die nodig zijn om het polygoon te tekenen handmatig opzoeken? Da’s toch iets te omslachtig.
De oplossing die ik bedacht is de volgende: een polygoon overlay prepareer je vrij eenvoudig door in Google Earth een polygoon overlay te maken, het getekende object als KML bestand op te slaan en vervolgens de coordinaten in het KML bestand te gebruiken om huup huup huup barbatruc (relatief) snel een eigengemaakt XML bestand te brouwen dat een Google Maps polygoon overlay implementeert.
Zoiets als hieronder, waarin een xml-bestand de basis is voor een (vrij ruwe) Gpolygon overlay van de provincie Friesland.
<?xml version=”1.0″ encoding=”UTF-8″?>
<provincies>
<provincie naam=”Friesland”>
<punt lat=”5.6417540301387″ lng=”53.31862537478114″ />
<punt lat=”5.601394272591392″ lng=”53.29722883035308″ />
<punt lat=”5.514664156630218″ lng=”53.25351579038482″ />
<punt lat=”5.436265962100094″ lng=”53.20028996820903″ />
<punt lat=”5.416757798236787″ lng=”53.1510373918212″ />
<punt lat=”5.395750580550342″ lng=”53.09988125925209″ />
<punt lat=”5.379957548464859″ lng=”53.05170159446328″ />
<punt lat=”5.39763038307855″ lng=”53.02456027531464″ />
<punt lat=”5.401958640132307″ lng=”52.98881301736234″ />
<punt lat=”5.408149085717938″ lng=”52.95677879231113″ />
<punt lat=”5.399267798428184″ lng=”52.93447282266515″ />
<punt lat=”5.412958517587612″ lng=”52.91651012360246″ />
<punt lat=”5.380917899485013″ lng=”52.89800152571775″ />
<punt lat=”5.36367928371574″ lng=”52.87372539129518″ />
<punt lat=”5.416175071741861″ lng=”52.85154622296546″ />
<punt lat=”5.491051933326873″ lng=”52.84469950940976″ />
<punt lat=”5.551940503772812″ lng=”52.84088213581107″ />
<punt lat=”5.598639728158858″ lng=”52.84714773291602″ />
<punt lat=”5.636523793034897″ lng=”52.85358018645154″ />
<punt lat=”5.661714108058447″ lng=”52.84324246289889″ />
<punt lat=”5.697648152178303″ lng=”52.84261449445339″ />
<punt lat=”5.749430081155723″ lng=”52.83045122396133″ />
<punt lat=”5.785232690944113″ lng=”52.80754678183364″ />
<punt lat=”5.82964060277358″ lng=”52.80673432868616″ />
<punt lat=”5.880492542198327″ lng=”52.79889359510096″ />
<punt lat=”5.919515645360648″ lng=”52.83011096406028″ />
<punt lat=”5.960191924145264″ lng=”52.83636075248498″ />
<punt lat=”5.984057665880329″ lng=”52.82326561821252″ />
<punt lat=”6.015227775365845″ lng=”52.82125777577868″ />
<punt lat=”6.065867012905827″ lng=”52.8371042553437″ />
<punt lat=”6.11826155321647″ lng=”52.843120486328″ />
<punt lat=”6.210568730071103″ lng=”52.89159646550523″ />
<punt lat=”6.251936444106989″ lng=”52.92319449271693″ />
<punt lat=”6.286614540385401″ lng=”52.92246151728106″ />
<punt lat=”6.331584002418808″ lng=”52.90076425350457″ />
<punt lat=”6.366461450997775″ lng=”52.91479507778703″ />
<punt lat=”6.401967964850272″ lng=”52.93043759610292″ />
<punt lat=”6.425470099821169″ lng=”52.96630735522788″ />
<punt lat=”6.365579100846901″ lng=”53.02684756683307″ />
<punt lat=”6.367040039553033″ lng=”53.06206588410836″ />
<punt lat=”6.320289090776243″ lng=”53.07279684808722″ />
<punt lat=”6.323753840929329″ lng=”53.09401149324337″ />
<punt lat=”6.263968310031288″ lng=”53.10351786451235″ />
<punt lat=”6.185694303123142″ lng=”53.12509837860175″ />
<punt lat=”6.179219235938903″ lng=”53.15391711492647″ />
<punt lat=”6.206240726857743″ lng=”53.19119827794165″ />
<punt lat=”6.224908574241908″ lng=”53.218845366347″ />
<punt lat=”6.237846164792843″ lng=”53.2398940083819″ />
<punt lat=”6.261144497410939″ lng=”53.2791593271518″ />
<punt lat=”6.291200702654109″ lng=”53.30800580725216″ />
<punt lat=”6.280377771892447″ lng=”53.34194945857235″ />
<punt lat=”6.231242919591765″ lng=”53.34862635327323″ />
<punt lat=”6.175961820092312″ lng=”53.37263418102311″ />
<punt lat=”6.188510064022098″ lng=”53.41315211996164″ />
<punt lat=”6.045691180344208″ lng=”53.4022774077747″ />
<punt lat=”5.887686278109897″ lng=”53.37823569581277″ />
<punt lat=”5.742743614816973″ lng=”53.3410559123932″ />
<punt lat=”5.6417540301387″ lng=”53.31862537478114″ />
</provincie>
</provincies>
Dit bestand laadt je vervolgens met een javascript functie in in je Google Maps toepassing. Let op: de lat en lng waarden staan in het KML bestand omgekeerd. Vandaar dat hieronder eerst het lng attribuut wordt uitgelezen en daarna het lat attribuut om ze in de voor Google Maps geschikte volgorde te krijgen. Over quick and dirty gesproken
:
function polyLaden() {
if (xmlhttp) {
var url=”/xml/provincies.xml”;
xmlhttp.open(“GET”,url,false);
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState == 4) {
if (xmlhttp.status == 200) {
var xmldata = GXml.parse(xmlhttp.responseText);
var punten = xmldata.documentElement.getElementsByTagName(“punt”);
var pnts = [];
for (var i = 0; i < punten.length; i++) {
pnts[i] = new GLatLng(parseFloat(punten[i].getAttribute(“lng”)), parseFloat(punten[i].getAttribute(“lat”)));
var poly_friesland = new GPolygon(pnts,”#666666″,1,1,”#ff0000″,0.5,{clickable:true});
}
map.addOverlay(poly_friesland);
GEvent.addListener(poly_friesland,”click”, function() {
alert(“Je klikte op Friesland”);
if (poly_friesland.isHidden()) {
poly_friesland.show();
}
else {
poly_friesland.hide();
}
});
}
else {
alert(“Er was een probleem met het ophalen van xml data voor de kaart.”);
}
}
}
xmlhttp.setRequestHeader(‘Accept’,'message/x-formresult’);
xmlhttp.send(null);
return false;
}
else {
alert(“Het ophalen van kaartinformatie wordt door uw browser niet ondersteund.”);
}
}
Tof. En de performance van de polygoon rendering is behoorlijk te noemen. Ik ben wel benieuwd hoe de performance van een kaart wordt beïnvloed als je er voor elke provincie een overlay overheen zet.
Tot zover het goede nieuws. Wat dan alleen weer een afknapper is … het feit dat het GPolygon object geen mouseover event ondersteunt. Een klik-event kun je wel registreren, maar een mouseover / mouseout — bijvoorbeeld om een opwindend visueel effect te creëren als er iemand overheen muist — helaas (nog) niet. Aaaargh!!!
Update
Bill Chadwick heeft een subclass voor het GPolygon object geschreven waarmee je op een eenvoudige manier mouseover effecten implementeert. Gewoon even die polygon javascript class scoren en you’re good to go.
api · Google Maps · GPolygon · Javascript · location based
Google Maps: een voorbeeld van GDirections in actie
Google Maps. Op het moment van schrijven een paar weken uit de beta fase en via de voorpagina van Google beschikbaar. Zelf heb ik de afgelopen zomer met regelmaat gestoeid met een Google Maps mashup. En er soms over geschreven. Onder andere hier, hier, en hier … — en ja ik ben maar een simpele el uu el anders zou ik die anchor tekst wel wat handiger hebben ingevuld
Of het interesseert me gewoon niet zoveel. Dat kan natuurlijk ook. Toch?
Anyway, met enige regelmaat zie ik zoekmachine referrals terug die gerelateerd zijn aan Google Maps.
Zoals mensen die zochten op GDirections — het stukje code van de Google Maps API die een routebeschrijving op je kaartje zet en de route van A naar B als tekst retourneert. Het is volgens mij common knowledge en allemaal te lezen in de Google Maps documentatie, maar wie was de cabaratier ook alweer die zei hey als er een markt voor is ….
Bij deze dus een voorbeeldje van een implementatie van GDirections uit de Google Maps API:
/*
De routeLaden() functie wordt aangeroepen. Omdat in mijn toepassing de bestemming bekend is bevat de functie een argument: naar. Dit argument bestaat uit een tekenreeks met het doeladres, zoiets als gelrelaan+34+emmeloord+nederland.
*/
function routeLaden(naar) {
/*
In een eerder stadium heeft de gebruiker het punt van vertrek kunnen opgeven: de straat, het huisnummer en de plaats van vertrek. Deze worden samengevoegd in de variable van die later gebruikt zal worden.
*/
var route = document.getElementById(“routebeschrijving”);
var route_van_straat = document.getElementById(“route-straat”).value;
var route_van_nr = document.getElementById(“route-nr”).value;
var route_van_plaats = document.getElementById(“route-plaats”).value;
var van = route_van_straat + ” ” + route_van_nr + ” ” + route_van_plaats + ” Nederland”;
/*
gdir, mijn instantie van het GDirections object, gebruikt als eerste argument het gmap object (je kaartje) en als tweede argument een variabele die verwijst naar het pagina element waarin je de routegegevens wilt tonen. In mijn geval een div met het id routebeschrijving.
*/
gdir = new GDirections(map, route);
/*
de load event handler roept de onGDirectionsLoad() functie aan die wordt uitgevoerd als de routebeschrijving geladen wordt. Met andere woorden, wat moet er allemaal gebeuren als het gdir object geladen is.
*/
GEvent.addListener(gdir, “load”, onGDirectionsLoad);
/*
De error event handler roept de handleErrors() functie aan die wordt uitgevoerd als er problemen optreden bij het laden van de routebeschrijving. Hier is nog wel wat aardigs mee te doen maar ik heb me beperkt tot het vertalen van de standaard Google Maps foutmeldingen op basis van de gegeven constanten en het ophoesten van een alert box.
*/
GEvent.addListener(gdir, “error”, handleErrors);
/*
stel de taal in voor de output van de routebeschrijving. Je output wordt gelokaliseerd. Links af in plaats van turn left. Verander de inhoud van de taal variabele voor de lol maar eens in us_en en bemerk het verschil
*/
var taal = “nl_nl”;
/* GDirections in actie. Het gdir object wordt uitgevoerd met als argumenten het vertrekadres, het doeladres en de locale / taal waarin de routebeschrijving moet worden getoond
*/
gdir.load(“from: ” + van + ” to: ” + naar, { “locale”: taal });
}
/*
In de onGDirectionsLoad functie() doe ik dingen die in mijn situatie van belang zijn. Zoals het positioneren van de container div die de routebeschrijving bevat. Voor het functioneren van de GDirections functionaliteit is dit verder niet van belang.
*/
function onGDirectionsLoad() {
var container_route = document.getElementById(“container-routebeschrijving”);
container = document.getElementById(“container”);
container_route.style.display = “block”;
container_route.style.left = (container.offsetLeft + 6) + “px”;
container_route.style.top = (container.offsetTop + 6) + “px”;
container_route.style.visibility = “visible”;
var sluit = document.getElementById(“sluit-routebeschrijving”);
var iw = map.getInfoWindow();
iw.hide();
}
function handleErrors(){
if (gdir.getStatus().code == G_GEO_UNKNOWN_ADDRESS) {
alert(“De locatie van het opgegeven vertrekadres kon niet worden bepaald.nFoutcode: ” + gdir.getStatus().code);
}
else if (gdir.getStatus().code == G_GEO_SERVER_ERROR) {
alert(“Er is iets misgegaan. Maar het is onduidelijk WAT!n Foutcode: ” + gdir.getStatus().code);
}
else if (gdir.getStatus().code == G_GEO_MISSING_QUERY) {
alert(“Een parameter ontbreekt. Misschien was er geen vertrekpunt ingevoerd.n Foutcode: ” + gdir.getStatus().code);
}
else if (gdir.getStatus().code == G_GEO_BAD_KEY) {
alert(“De Google Maps sleutel is ongeldig of de gebruikte sleutel is niet geldig voor dit domein. n Foutcode: ” + gdir.getStatus().code);
}
else if (gdir.getStatus().code == G_GEO_BAD_REQUEST) {
alert(“De aanvraag voor het plannen van een route is mislukt.n Foutcode: ” + gdir.getStatus().code);
}
else {
alert(“Er is iets misgegaan. Maar het is volstrekt onduidelijk WAT de oorzaak is!”);
}
}
Een werkend voorbeeld van bovenstaande code kom je tegen op de op het programma pagina met tips voor een uitstapje met het hele gezin. Klik op een markertje en klik vervolgens op het route ikoontje in de InfoWindow ballon. Je kunt dan je vertrekadres opgeven om vervolgens de GDirections functie in actie te zien.
Linktip: een veeeeel betere uitleg van de mogelijkheden van Google Maps dan ik met m’n suffe kop kan geven vind je overigens op de Google Maps tutorial website van Mike Williams.
api · demo · GDirections · Google Maps · location based · routebeschrijving
Google Maps startpunten
Wil je zelf spelen met Google Maps? Dan zijn een aantal bronnen van informatie onontbeerlijk. Hieronder zie je de resources die ik zelf met regelmaat gebruik bij het bouwen van mijn kaart met uitjes voor het hele gezin.
Google Maps API documentatie
Natuurlijk is de hele reference guide van de Google Maps API te vinden op de Google website. Om snel wat feeling te krijgen met de Google Maps code is het stoeien met de voorbeelden op Concepts and Examples pagina een goed startpunt. Zelf merkte ik al snel dat ik vragen had die niet 1-2-3 in de Google documentatie zijn terug te vinden.
Mike Williams Google Maps tutorials
Gelukkig zijn er op het internet meer wegen die naar Rome leiden. De voorbeelden die Mike Williams geeft op zijn Google Maps tutorials website zijn bijvoorbeeld compleet, uitgebreid en meer dan nuttig. Meer dan 50 tutorials vind je er. Variërend van basic tot complex. Onmisbaar tijdens het verkennen van de mogelijkheden van Google Maps. Ook onmisbaar: Mike’s onofficiële versie van de documentatie. Hierin worden ook de exotische en niet-gedocumenteerde functies beschreven. Of het verstandig is om deze te gebruiken is natuurlijk een tweede
Inspiratie
En wat heb je verder nodig behalve de zojuist vergaarde technische kennis van de Google Maps API? Juist, inspiratie om iets leuks te knutselen. Die doe je bijvoorbeeld op bij Google Maps Mania. Hier kun je jezelf vergapen aan tal van toepassingen van de populaire Google kaartcode. In Nederland zijn er trouwens nog verrassend weinig websites die zich wagen aan een Maps mashup. Veel websites komen niet verder dan het op de kaart zetten van een aantal prikkertjes. Via Nederkaart kun je er wel een aantal vinden die experimenteren met Maps.
api · documentatie · Tutorials