Geopositionering i PHP och Javascript
Geopositionering
Geopositionering (från engelskans ”geo location” eller ”geo tracking”) har de senaste åren blivit allt populärare i takt med att våra datorvanor blivit allt mer mobila. Mer eller mindre alla stora sidor använder någon form av geopositionering för att bestämma var användaren kommer från för att på så vis kunna anpassa innehållet, språket eller marknadsföringen efter det. Även utan att anpassa din sida efter besökarens geografiska position kan det förstås vara intressant att se var dina besökare kommer ifrån.
Det finns i grunden två typer av geopositionering; Antingen gör man det på serversidan med hjälp av besökarens IP-adress och en databas som länkar IP-adresser med geografiska positioner. Det andra alternativet är att göra det i din besökares webbläsare genom Javascript. Följande artikel ger en snabb inblick i båda metoder.
Geopositionering baserat på IP-adress
Fördelen med denna metoden är att du alltid har tillgång till dina besökares IP-adress, varför inte använda den till något? Nackdelen med att geopositionera efter IP-nummer är att metoden är minst sagt opålitlig. Informationen är normalt inte mer exakt än t.ex. vilken stad besökaren finns i. Det finns dessutom ingen som helst garanti för att den informationen du får är korrekt då databasen som mappar IP-nummer till geografisk position kan vara både utdaterad eller direkt felaktig.
Det finns både fria och kommersiella databaser att tillgå för detta ändamål, där de som kostar pengar rimligtvis bör ge något exaktare resultat(?), men fortfarande utan garantier. Å andra sidan är det ju också rätt skönt att ens position inte går att spåra exakt på ens IP-adress, eller hur? Syftet med geopositionering är förstås inte att ta reda på vilken exakt fysisk position din besökare finns på utan mer att kunna se större trender och mönster baserat på dina besökares geografiska plats. Kommer t.ex. 95% av besökarna till din webbshop från Stockholmsområdet är det kanske inte i Göteborg du ska öppna din första fysiska butik!
Geopositionering från webbläsaren
Geopositionering från webbläsaren används flitigt av framförallt sociala medier så som Twitter, Google+ m.fl. När du använder geopositionering från webbläsaren är det användaren själv som väljer huruvida den vill dela med sig sin geografiska position eller inte, normalt sett genom en liten ruta som dyker upp och berättar att webbsidan vill använda din geografiska position och ber dig godkänna eller avslå denna begäran. Detta är helt enligt specifikationerna för Javascripts Geolocation API och är inget som normalt kan åsidosättas.
”Nackdelen” är således självklart att du inte kan tvinga dina besökare att ange sin fysiska position. Fördelen är att metoden är betydligt mer exakt än positionering baserat på IP-nummer! Då metoden använder sig av både WiFi-positionering och GPS (om tillgängligt) går det oftast att få geografiskt position så exakt som adress och trappuppgång. Viktigt är förstås att denna information används på ett sätt som användaren är informerad om. De flesta hade förmodligen blivit ganska irriterade om det började dyka upp reklam i brevlådan efter att de angett sin geografiska position på din sida! Geopositionering från webbläsaren ska alltså främst ses som något som förbättrar upplevelsen för dina besökare.
Nedan tar vi en titt på hur båda metoder implementeras i praktiken.
Geopositionering från IP-adress på serversidan med PHP
Det finns lite olika metoder att använda i PHP när det kommer till att geopositionera besökare baserat på deras IP-adress. Metoden vi använder här baserar sig på paketet GeoIP som är enkelt att hämta i de flesta linuxdistributioners pakethanterare. I Fedora heter paketet php-pecl-geoip. Du behöver dessutom installera C-biblioteket GeoIP. Använder du inte Linux finns installationsinstruktioner här.
Paketet bygger på en öppen databas som tillhandahålls av företaget MaxMind. Det går även att betala för en komersiell databas och fler funktioner. Nåväl, så fort installationen är klar kan du börja använda de inkluderade funktionerna för geopositionering. De flesta funktioner tar ett värdnamn eller ip-nummer som argument, vilket är enkelt fixat med den globala variabeln $_SERVER['REMOTE_ADDR']. I koden nedan använder vi sedan ip-numret i funktionen geoip_record_by_name, som returnerar en vektor med samlad information om ip-numrets geoposition:
$ip = $_SERVER['REMOTE_ADDR']; $geodata = geoip_record_by_name($ip); print_r($geodata);
Här stöter jag dock på patrull i form av en varning: Databasen GeoIPCity.dat verkar inte finnas tillgänglig. Nåväl, efter lite sökande hittar vi instruktioner för att hämta hem den:
wget -N -q http://geolite.maxmind.com/download/geoip/database/GeoLiteCity.dat.gz gunzip GeoLiteCity.dat.gz mv GeoLiteCity.dat /usr/share/GeoIP/GeoIPCity.dat
Nu har vi laddat hem databasen och flyttat den till rätt plats. Nu skriver ovanstående kod ut något i stil med vektorn nedan, förstås beroende av var ip-numret härstammar:
Array ( [continent_code] => EU [country_code] => SE [country_code3] => SWE [country_name] => Sweden [region] => 26 [city] => Stockholm [postal_code] => [latitude] => 59.333301544189 [longitude] => 18.049999237061 [dma_code] => 0 [area_code] => 0 )
Som synes har vi en hel del användbar information endast baserat på IP-adressen. Det är lätt att tänka att latitud/longitud-kordinaterna ger en exakt position. Det handlar dock bara om uppskattningar, så ta dem med en nypa salt. Testa gärna med din egen IP-adress för att se hur exakt resultat du får! Vill du bara testa funktionen utan att skriva kod finns en demo online här.
Geopositionering från webbläsaren med Javascript
För att kunna använda geopositionering från webbläsaren måste vi börja med att kontrollera att webbläsaren har stöd för detta. Det gör vi genom att kolla efter navigator.geolocation:
if (navigator.geolocation)
{
...
}
Såvida du inte använder en antik webbläsare bör det inte vara några problem. När vi väl bestämt att vår användare har tillgång till Javascripts Geolocation API är det primärt tre funktioner vi använder för att spåra geografisk position:
- getCurrentPosition
- watchPosition
- clearWatch
getCurrentPosition gör precis vad namnet antyder. Funktionen tar tre parametrar varav den första är en s.k. callback-funktion som kommer att anropas om funktionen lyckades. Den andra parametern är en motsvarande funktion om du vill hantera vad som händer om funktionen inte lyckas. Den tredje parametern använder vi om vi vill ställa in exakt hur positionen ska mätas. I det här exemplet kommer jag att förutsätta att funktionen lyckas med vad den ska och därför endast använda den första parametern, som alltså är ett anrop till en annan funktion, i mitt fall funktionen showPosition:
if (navigator.geolocation) {
navigator.geolocation.getCurrentPosition(showPosition);
}
function showPosition(position) {
console.log('latitude: ' + position.coords.latitude + ' ');
console.log('longitude: ' + position.coords.longitude);
}
Ovan anropar vi alltså funktionen getCurrentPosition och vid lyckat resultat anropar vi funktionen showPosition. Callbackfunktionen som anropas av getCurrentPosition blir automatiskt tildelad ett positionsobjekt som vi sedan kan använda oss av inuti vår funktion. Vår funktion, här döpt showPosition gör som ni ser inte mer än att skriva ut koordinaterna för latitud och longitud i webbläsarens javascriptkonsol. Ett populärt användningsområde är förstås att koppla ihop resultatet med ett yttre API, t.ex. Google Maps. Det sparar vi till ett senare inlägg!
Återstår gör då de två andra funktionerna, watchPosition och clearWatch. watchPosition fungerar på samma sätt som Javascripts inbyggda timerfunktion setInterval, och uppdaterar med jämna mellanrum den geografiska positionen. Detta används dels för att det kan behövas fler försök att exakt bestämma någons position men också för att användaren ju kan röra på sig under tiden den besöker din sida! Precis som watchPosition används som Javascripts inbyggda setInterval används clearWatch precis som Javascripts inbyggda clearInterval. I övrigt fungerar funktionen watchPosition på samma vis som getCurrentPosition:
if (navigator.geolocation) {
positionT = navigator.geolocation.watchPosition(showPosition);
}
function showPosition(position) {
console.log('updated latitude: ' + position.coords.latitude + ' ');
console.log('updated longitude: ' + position.coords.longitude);
}
Nu har vi förhoppningsvis uppnått en lyckad positionering och avslutar med att stänga av timern för positionering:
navigator.geolocation.clearWatch(positionT);
Sammanfattning
Som förhoppningsvis framgått av den här korta introduktionen krävs det ingen större ansträngning för att använda geopositionering varken på serversidan eller i webbläsaren. Hur man sedan väljer att använda resultatet är förstås det som är viktigast, och där finns det gott om möjligheter. Jag tänkte i ett kommande inlägg koppla ihop vår geopositionering med Google Maps API, vilket är ett vanligt användningsområde. Har du idéer eller tips om roliga användningsområden så skriv gärna en kommentar!
