
I sommer laget jeg denne oversikten over GSM-basestasjonene til Telenor, som ble publisert på NRKs nettsider.
Jeg legger inn noen linjer om hvordan jeg jobbet med Brennpunkts kart over Telenors basestasjoner. Kanskje noen har innspill til andre og bedre måter å løse ting på i fremtidige prosjekter?
1 Innhenting av data
Rådataene kommer fra Telenor, men utleveringen skjedde ikke frivillig. Vi begjærte innsyn i dataene med hjemmel i miljøinformasjonsloven.
Innsynsbegjæringen ble avslått, men miljøklagenemnda ga oss medhold, og påla teleselskapet å utlevere dataene.
Vi har i skrivende stund en tilsvarende klagesak gående mot NetCom, som også motsetter seg utlevering av informasjon om basestasjonenes plassering.
2 Konvertering av data
Dataene fra Telenor kom som en Excel-fil, med felter for kommune, navn, type, og desimalgrad. Denne konverterte jeg til en sql-fil for databaseimport.
3 Databasen
Jeg brukte MySQLs geospatial indexing for koordinatene til basestasjonene. Denne delen av MySQL er imidlertid svært mangelfull. PostgreSQL gir langt bedre muligheter dersom man tar i bruk PostGIS.
Mange av GIS-funksjonene i MySQL er ennå ikke implementert, for eksempel funksjonen for å regne ut avstand mellom to punkter, noe jeg trengte for å plukke ut nærmeste basestasjoner i forhold et gitt kartpunkt, samt geografisk avstand i kilometer mellom hver av dem.
Jeg fant denne presentasjonen, som beskriver en veldig hårete spørring for å returnere avstanden mellom to punkter i MySQL. Funker som bare det J
http://www.scribd.com/doc/2569355/Geo-Distance-Search-with-MySQL
4 XML-feeden
Et PHP-skript genererer en XML-feed med informasjon om basestasjonene innenfor et kartutsnitt. Klienten (flashapplikasjonen) rapporterer valgt kartutsnitt til PHP-skriptet, som returnerer et cachet utsnitt tilpasset området brukeren vil titte på.
Eksempel:
http://www.nrk.no/basestasjoner/list.php?bounds=18.80,69.70,19.12,69.60&z=9
Skriptet normaliserer (kvantiserer) det bestilte utsnittet, slik at de returnerte dataene alltid dekker et større område enn det utsnittet (viewport) brukeren ser på i øyeblikket. Dette for å begrense nettverkstrafikken og for å gjøre caching praktisk mulig.
Jeg har forsøkt å begrense størrelsen på individuelle XML-filer til under 300K. De fleste ligger nok på godt under 100K.
Klienten gjør en ny spørring mot databasen bare dersom brukeren har dratt kartet utenfor den leverte rammen.
5 Clustring av kartpunkter
I områder med stor tetthet av kartpunkter blir punktene samlet i klynger. Dette skjer server-side, i PHP-skriptet. Klienten rapporterer zoomnivået, noe som gjør det mulig å regne ut avstand i absolutte piksler mellom hvert punkt.
Punkter slås sammen dersom avstanden mellom dem er mindre enn 70 piksler. Informasjon om hvordan gjøre dette fant jeg et eksempel på her:
http://www.appelsiini.net/2008/11/introduction-to-marker-clustering-with-google-maps
Clustringen skjer altså server-side for å avlaste klientene. Dette er en tung rutine som drar fordel av server-side cacing. Client side clustering av kartpunktene ville ført til ulidelig treg responstid på lave zoomnivåer.
6 Caching
Bruker Zend Cache, hvor man enkelt kan swappe mellom memcached og file cache. Produksjonsmiljøet kjører med memcached og nyter godt av gode responstider, selv når trafikken er høy.
7 Google Maps for flash
Veldokumentert API her:
http://code.google.com/intl/no/apis/maps/documentation/flash/reference.html
Har ingenting i mot AJAX, men det blir for kronglete å styre med JS i publiseringsverktøyet vårt, som er Polopoly — derfor ble det Flash.
Bruker for øvrig Googles geocoding-tjeneste (ClientGeocoder-objektet) til stedsnavn-søket. Informasjonsknappen som søker opp basestasjoner rundt et gitt kartpunkt bruker dessuten Googles reverse geocoding-funksjon for å returnere stedsnavn fra et gitt koordinat.
8 Grafikk
Animerte kartikoner er laget i LightWave 3D. Ikke veldig utfordrende å lage noe som ligner på de rektangulære GSM-antenneboksene til Telenor.
Animasjonen ble lagt inn i en egen (bitte liten) flash-fil og kompilert til en frittstående swf som jeg deretter embeddet i hoved-flashen.
Størrelsen på den ferdige swf-en er 228 kB. Den inkluderer alt av grafikk, animasjoner og fonter. Flashappen bruker ikke andre eksterne ressurser enn Google Maps API-et samt XML-feeden fra vår egen MySQL-database.