Een landkaart op je site? Kijk eens naar VirtualEarth

Tegenwoordig heeft het toepassen van geografische informatie voor user
interfaces een grote vlucht genomen. Terwijl enkele jaren gelden nog enorm
geïnvesteerd moest worden voor een GIS systeem, is dit tegenwoordig met tooling van oa. Miscrosoft en Google voor iedereen beschikbaar gekomen.

VirtualEarth voorbeeld

Als je hierbij optelt dat met de komst van GPS in allerlei producten
(lees: mobieltjes) er ook enorm veel informatie “location-aware” is geworden,
kunnen er hele leuke toepassingen rond landkaarten gebouwd worden.

Voor mijn huidige klant heb ik ook een representatie van data gebouwd op
basis van VirtualEarth 6. Ik ben door http://www.nerddinner.com/ , het perfecte startpunt om Asp.Net Mvc2 te ontdekken, met deze oplossing in aanraking gekomen. Dit is overigens niet de nieuwste versie (ik gebruik namelijk versie 6.2) maar ik pas deze graag toe. Want dit control wordt gewoon door JavaScript (lees jQuery) aangeroepen en voorzien van data. En de representatie ziet er prima uit, zowel in Internet Explorer (..), Opera als Firefox. Maar het grootste voordeel is dat ik geen API-key via een registratie moet aanvragen en dit is dus goed overdraagbaar op langere termijn. Een eenvoudige verwijzing via script is voldoende om deze te gebruiken.

De basis is altijd hetzelfde: eerst stel je een html DIV vast als container voor de map. Let er op dat de style op position:relative wordt gezet anders geeft de positionering vreemd gedrag.

Vervolgens moet de map ingesteld en getoond worden, en er valt echt veel
in te stellen. Denk hierbij aan het menu op de kaart, de soort representatie,
zoomfactor, mogelijkheid tot herschalen etc. Ik heb in dit voorbeeld het
inzoomen uitgezet. Daardoor is ook de ‘dashboard’ niet getoond. Verander de
‘true’ in ‘false’ in de map.LoadMap() om zoomen weer te activeren. Kijk voor
meer uitleg op http://msdn.microsoft.com/en-us/library/bb412546.aspx

We hebben nu dus al een aardige landkaart. Maar om echt indruk te maken
op je baas, moet je iets tonen op de landkaart. Er zijn verschillende
mogelijkheden, van punten via eenvoudige lijnen tot complete routenavigatie. In
deze blog beperk ik mij tot ‘PushPins’, kleine iconen die een locatie aanduiden.
Hoewel in later versies van VirtualEarth de pushpin overtroffen wordt door de
Shape, voldoet de PushPin vaak al voldoende.

Voordat ik de PushPin demonstreer, wil ik nog even op layers wijzen.
Hoewel ik hier geen gebruik van een layer maak, alle PushPins kunnen al direct
op de map geplaatst worden, kan dit een welkome aanvulling zijn. Met layers
kunnen PushPins gegroepeerd worden en als groep zichtbaar of onzichtbaar gemaakt worden. Let hierbij op dat PushPins en layers die onzichtbaar zijn, zich nog wel degelijk in het geheugen bevinden. Layers en PushPins hebben ook een unieke identificatie en het aanmaken van een layer of pin met een al bestaande
identificatie resulteert in een foutmelding.

Een PushPin wordt op een bepaalde positie geplaatst door het opgeven van
een latitude en longitude. De standaard icoon van een PushPin kan vervangen
worden door een ander icoontje door de url op te geven. In mijn voorbeeld geef
ik ook een titel en details op welke getoond worden bij een “Mouse-over”. De
details kunnen uit html bestaan. Hierin kunnen ook images en links opgenomen
worden. Zie http://msdn.microsoft.com/en-us/library/aa737188(msdn.10).aspx
voor meer informatie over de constructie van een PushPin.

Helaas weet ik in vaak niet de coördinaten van de te plaatsen PushPin,
maar wel de bijbehorende adresgegevens. Uiteindelijk komt het er dus op aan hoe we aan de locatie van het adres, land of plaats komen. Hiervoor gebruik ik de
functie map.Find(). In mijn voorbeeld achterhaal ik de positie van “Nederland”.
Dit had bv. ook “broadstreet, new york” kunnen zijn. Aangezien er van beide
mogelijkheden maar één locatie op de wereld aanwezig zal zijn, beperk ik mijn
gewenste selectie tot slecht één locatie.

Uiteindelijk krijg ik in de callback functie ‘processResults’ een
‘places’ parameter mee. Van de eerste positie vraag ik de LatLong op welke bij
de PushPin laat invullen. Zie voor meer uitleg over de de Find functie: http://msdn.microsoft.com/en-us/library/bb429645.aspx

Dit geeft uiteindelijk:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Virtual Earth demo</title>
</head>
<body onload="getMap();">
<script
src="http://dev.virtualearth.net/mapcontrol/mapcontrol.ashx?v=6.2"
type="text/javascript"></script>
<script type="text/javascript">
  var map = null;
  function getMap() {
    map = new VEMap('divMap');
    map.SetDashboardSize(VEDashboardSize.Small);
    var veCenterLocation = new VELatLong(30,
      0, 0, VEAltitudeMode.RelativeToGround);
    map.LoadMap(veCenterLocation, 2, VEMapStyle.Hybrid, true, 1);
    showPins();
  }

  function showPins() {
    try {
      map.DeleteAllPushpins();
      map.Find(null, "Netherlands", null, null, 0, 1, true, true,
        true, false, processResults);
    }
    catch (e) {
      alert("showPins message: " + e.message);
    }
  }

  function processResults(layer, resultsArray, places, hasMore,
      veErrorMessage) {
    try {
      var pin = new VEPushpin(1, places[0].LatLong,
        "htt p://www.112kampen.nl/icon/television.png",
        places[0].Name,
        '<table><tr><td>Header<ul><li>Field
         1</li><li>Field
         2</li></ul></td></tr></table>', 1);
      map.AddPushpin(pin);
      if (veErrorMessage != null) {
        alert("process error: " + veErrorMessage);
      }
    }
    catch (e) {
      alert("processResults message: " + e.message);
    }
  }
</script>

    <h2 id="h2">Virtual Earth demo</h2>

    <div id="divMap" style="position:relative; width:1000px;
        height:550px;"></div>
  </body>
</html>

Natuurlijk is dit slecht een vogelvlucht langs enkele mogelijkheden maar
hiermee is al een hele leuke interactieve interface te bouwen. Zie voor meer
demo’s van VirtualEarth ook http://www.microsoft.com/maps/isdk/ajax/