Pimpa Göteborgs Postens skolkarta

Pimpa Göteborgs Postens skolkarta
december 13, 2012 Fredrik Corneliusson

OBS! Nedanstående kod fungerar när jag skriver detta (2012-12-13), om GP ändrar sin kod så kommer det antagligen inte funka så skyll inte på mig 😉

När man har barn i skolåldern så känns Göteborgs Postens karta över skolors resultat väldigt relevant. Det är ett utmärkt initiativ men eftersom jag är lat och ville få en bättre överblick snabbt så saknade jag färgkodning av skolorna direkt på kartan så man slapp klicka på varje skola för att se den.Så vad gör en lat nörd? Klickar runt manuellt i 5 minuter eller lägger en timme på att koda ett ful-hack istället? Jag tror ni kan gissa.

Jag har alltid tyckt att bookmarklets varit hur fantastiskt som helst men har fram tills nu inte funnit nått nyttigt användningsområde. Bookmarklets är bokmärken som i stället för länkar innehåller Javascript-kod som körs på den sida som är aktiv i webbläsaren när man klickar på bokmärket. Det som är så trevligt med detta är att koden i skriptet kan modifiera den aktiva sidan hur fanken den vill.

För den som bara vill se en trevligare version av GP:s skolkarta är det bara att dra följande länk:Pimpa GP Skolkarta” till bokmärkesfältet, surfa in på skolkartan och klicka på bokmärket.

Om man inte kan eller vill installera genom att dra och släppa länken så gör en länk manuellt genom skapa ett bokmärke och ange denna text som ”Adress”:

javascript:(function(){function%20pimp(){var%20e={IG:"http://www.google.com/intl/en_us/mapfiles/ms/icons/red-dot.png",G:"http://www.google.com/intl/en_us/mapfiles/ms/icons/yellow-dot.png",VG:"http://www.google.com/intl/en_us/mapfiles/ms/icons/blue-dot.png",MVG:"http://www.google.com/intl/en_us/mapfiles/ms/icons/green-dot.png"};var%20t={};var%20n=null;var%20r=null;var%20i=setInterval(function(){s()},300);var%20s=function(){if(o()){clearInterval(i);u();l(n)}};var%20o=function(){if(mktmp.spots_ready===1&&!!mktmp.mgr&&!!mktmp.mgr[0].markers){n=mktmp.mgr[0].markers;r=mktmp.spots[0].spots;return%20n.length===r.length}};var%20u=function(){for(var%20e=0,t=r.length;e

Skolkartan innan att skriptet körts.

Skolkartan innan att skriptet körts.

Skolkarta efter att skriptet körts

Skolkartan efter att skriptet körts

För er som eventuellt vill veta mer om hur det går till rent tekniskt så läs vidare.

För att utveckla koden installerade jag Firefox och pluginen Greasemonkey som gör det lätt att köra egna Javascript på andras sidor. När de väl fungerar med Greasemonkey är det lätt att konvertera koden till bookmarklet. Men innan jag kunde börja koda behövde jag gräva i GP:s DOM träd för att se hur jag kunde få tag på Google kartan som de använde. För detta använde jag gamla hederliga Firefox pluginen Firebug. GP har en hel del kod på sidorna som inte var relevant för mig och namnen de använder på DOM-noder och Javascript variabler är inte självklara så det var det som var det bökigaste med hela projektet. Men efter lite grävande så kom jag fram till att kartan låg i en div med namnet "mkmap" och Javascript objektet "mktmp" samt att skolorna kallades "spots".

Nu var det bara att skriva koden (se nedan) som ändra markörerna på kartan i olika färger beroende på skolans betyg. De använder Googles karta och som tur är hade jag hade lekt lite med Google maps API innan vilket underlättade väsentligt.

Ett problem som uppkommer när man hackar in kod på en redan initierad sida på detta sätt är att veta när alla skolor var laddade och kartan är redo att moddas. En timer som körs med 300ms mellanrum används för att kolla när skolorna laddats och alla kartmarkörerna har skapats.
// start periodic check for when map is ready
var timer_id_check_map_ready = setInterval(function() {
waitForMapReady()
}, 300);
var waitForMapReady = function() {
if (isMapReady()) {
// turn off timer event
clearInterval(timer_id_check_map_ready);
...
}
};
var isMapReady = function() {
if (mktmp.spots_ready === 1 && !!mktmp.mgr && !!mktmp.mgr[0].markers) {
markers = mktmp.mgr[0].markers;
schools = mktmp.spots[0].spots;
return markers.length === schools.length;
}
};

Kartmarkörerna hade ingen referens till skolobjekt så det fanns inget lätt sätt att para ihop dem för att uppdatera markörikon efter skolans betyg, men både skolobjekten och markörerna har samma geo-position så jag använde mig av detta för att lista ut vilken skola en markör representerar.
var addGeoPosition2SchoolMapping = function(school) {
var latitudeAndLongitudeOne = new google.maps.LatLng(school.latitude, school.longitude);
var pos_string_val = latitudeAndLongitudeOne.toUrlValue();
geo_position_to_school_mapping[pos_string_val] = school;

};
var getSchoolForMarker = function(marker) {
// use the markers geoposition to get the school
return geo_position_to_school_mapping[marker.getPosition().toUrlValue()];
};

För att ta reda på betyget på skolan söker jag bara i skolobjektets "summary" information (ett fulhack men hittade inte betyget någon annan stans).
Nu var det bara att iterera över alla markörer och sätta färg beroende på betyg.
var updateMarkerIcons = function(markers) {
markers.each(function(marker) {
var school = getSchoolForMarker(marker);
var grade = getGrade(school);
var icon = icons[grade];
marker.setIcon(icon);
});
};

Det var det hela, ett bräckligt litet hack men det var kul att leka lite. Hoppas det inspirerar er till egna fantastiska bookmarklets!

Hela koden:

0 Kommentarer

Lämna ett svar

E-postadressen publiceras inte. Obligatoriska fält är märkta *

*

Denna webbplats använder Akismet för att förhindra skräppost. Lär sig hur dina kommentardata behandlas.