Al enige tijd was ik bezig met het weergeven van gegeven in Google Maps en Earth, maar nog nooit door directe gebruikersdata mee te nemen. Dit postje stond al een tijd in concept maar onlangs uit de kast gehaald om de wijde wereld in te trekken! Met gebruik van gegevens van derden ‘of’ het invoeren van bijv plaatsnamen door een gebruiker kun je eenvoudig zaken weer gaan geven op maps. Het idee is om snel plaatsen op de kaart te kunnen zetten en daarbij ook nog een overlay te maken zodat je makkelijk kunt zien wat de spreiding is (zie plaatje).
Uiteraard kan er nog veel meer, maar dat mogen geïnteresseerden zelf uitvinden! Ik heb gebruik gemaakt van een databestand met alle plaatsnamen (en postcodes, al gebruik ik die niet) van Nederland wat je kunt vinden bij D-Centralize.nl en verder wat home-made PHP scriptjes.
Klik door om te kijken wat er onder de motorkap zit! De truc zit hem namelijk met name in om je polygoon zodanig te krijgen dat hij de punten ‘buitenom’ pakt. Daarnaast was voor mij nog even de uitdaging dat ik de ingevoerde gegevens nergens wil bewaren, toegegeven de plaatsnamen met coordinaten zitten in een database, maar door de gebruiker ingevoerde data wordt nergens opgeslagen op het systeem tot aan de KML files. Die worden aangemaakt op verzoek van de gebruiker die daarna direct naar Google Maps verwezen wordt om het resultaat te bekijken, de KML sourcefile wordt vervolgens binnen 2 minuten verwijderd van het systeem zodat er geen ‘restjes’ achterblijven.
Naast de al genoemde database van D-Centralize gebruik ik ook nog wat nuttige informatie van Google zelf, waaronder hun Tutorial en Reference. Uiteindelijk heb ik een simpel form scriptje wat zorgt voor invoer van de plaatsnamen.
Verder wordt de output van het KML bestand gewoon via de manier van de tutorial van Google gedaan, een beetje spelen met de variabelen hier en daar kan geen kwaad!
De hele rompslomp zit hem in het juist adresseren van de coordinaten, ik heb het mezelf makkelijk gemaakt en een punt midden in Nederland gepakt, maar als je alleen maar noordelijke punten pakt en een of twee zuidelijke (als voorbeeld) zul je zien dat dit niet het gewenste resultaat oplevert. Beter is om te bepalen wat de buitenste 4 punten zijn en daar middenin te gaan zitten (hoewel dat ook niet altijd zal werken).
Voor de wiskundigen onder ons, we maken gebruik van de berekening voor afstand en hoek tussen twee punten zoals uitgelegd onder de code! De code die je nodig hebt om de punten netjes uit te lijnen maakt gebruik van de PHP-code van een forum-gebruiker en de processing ziet er dan als volgt uit:
# Let op, mijn coordinaten staan nu in "lon,lat,hoogte\n" geconcatenate in een string! $homelat="52.09"; # Je eigen '0' plaatsmarkering $homelon="5.10"; $R="6372.795477598"; # Straal van ons bolletje foreach ( split("\n",$coords) as $value ) { list($lon,$lat,$junk)=split(",",$value); list($miles,$kms,$bearing,$bearingWR)=GML_distance($homelat,$homelon,$lat,$lon); $points[] = array("lat"=>$lat, "lon"=>$lon, "distance"=>$kms, "bearing"=>$bearing); }
$sortArray = array(); foreach($points as $point){ foreach($point as $key=>$value){ if(!isset($sortArray[$key])){ $sortArray[$key] = array(); } $sortArray[$key][] = $value; } } $orderby = "kms"; array_multisort($sortArray[$orderby],SORT_DESC,$points); $orderby = "bearing"; array_multisort($sortArray[$orderby],SORT_DESC,$points);
$coords=""; $counter=0; foreach ($points as $point) { $lon=0; $lat=0; foreach ($point as $key=>$value) { if ( $key == "lat" ) { $lat = $value; } if ( $key == "lon" ) { $lon = $value; } } if ($lon > 0 ) { $coords.="$lon,$lat,100\n"; } if ( !$counter ) { $firstlon=$lon; $firstlat=$lat; } } $coords.="$firstlon,$firstlat,100"; # Vergeet niet om je coordinaten 'rond' te laten lopen :)
Calculating the distance between two geographical points (from SunEarthTools)
The formula used to determine the shortest distance between two points on the land (geodesic), approximates the geoid to a sphere of radius R = 6372.795477598 km (radius quadric medium), so the calculation could have a distance error of 0.3%, particularly in the polar extremes, and for long distances through various parallel. Given two points A and B on the sphere expressed by latitude (lat) and longitude (lon) you will have:
distance (A, B) = R * arccos (sin(latA) * sin(latB) + cos(latA) * cos(latB) * cos(lonA-lonB))
The angles used are expressed in radians, converting between degrees and radians is obtained by multiplying the angle by pi and dividing by 180
Calculation of direction between two geographical points (from SunEarthTools)
To determine the direction from the starting point between two points on the earth, use the following formula:
Δφ = ln( tan( latB / 2 + π / 4 ) / tan( latA / 2 + π / 4) )
Δlon = abs( lonA – lonB )
bearing : θ = atan2( Δlon , Δφ )
Note: 1) ln = natural log 2) if Δlon > 180° then Δlon = Δlon (mod 180).