Åtgärder

Leaflet i undervisningen

Från Skolbok


Leaflet - Inledning

Ända sedan LPO 94 har GIS funnits med i geografiämnet som något eleverna ska lära sig, utan att de som bestämmer på Skolverket har funderat igenom hur det egentligen ska implementeras i undervisningen. Före 2000-talet gick det helt enkelt inte. Datorerna var för dåliga och lämpliga kartor för svåra att hitta på Internet. Det slutade, i alla fall för mig, att eleverna fick skapa egna koropletkartor för hand, utifrån kopior från existerande kartor som kopierats i gråskala på skolans kopiator.

Sedan kom Google Earth 2001. Från början var det så krävande för datorerna att det var stört omöjligt att flytta runt på jorden utan att det skedde stora fördröjningar, men det var gratis och det gick att använda till GIS. Det gick visserligen inte att lägga in olika lager på varandra, som ett riktigt GIS-program måste kunna, men det gick att skapa separata textfiler med information om punkter, linjer och ytor som sedan kunde sparas till .kml-filer som Google Earth kunde läsa av och visa upp på skärmen. Genom att lägga in data som skulle användas i MS Excel och använda sig av rapportutskriftsmetoden från Excel gick det att göra enkla urval beroende på syfte. Rapporten skrevs ut i samma format som .kml-filerna är uppbyggda i och på det viset gick det att använda GIS i klassrummet. I teorin...

När jag genomförde den typen av lektion i gymnasiets år 3, gick det sisådär. Trots att det var datavana nittonåringar lyckades de ofta kasta om latitud och longitud, blanda ihop komma och punkt eller missa viktiga delar i .kml-filen så att inget syntes på skärmen. Kml-filer är känsliga och vid minsta fel avbryts visningen. Slutuppgiften för eleverna var ett tänkt skridskolopp på havsisen mellan Ljungskile och Uddevalla där de dels skulle rita ut en linje för färdvägen, dels placera ut punkter där stationer för mat och vatten, eller farliga platser där åkarna riskerade att åka vilse, förväntades ligga, och dels en yta vid start- och målområdet. Uppgiften var inte överdrivet svår, men mer än hälften av gymnasieeleverna misslyckades ändå. Vanligaste felet var att de placerade banan i Stilla havet istället.

Denna anekdot är inte med för att visa att elever inte förstår GIS, för det gör de. Istället är det en illustration över att allt som tangerar programmering i skolan både är mycket svårare och tar mycket längre tid att sätta sig in i och förstå,, än vad Skolverket verkar inse.

Ville lärarna använda riktiga GIS-program, som Mapinfo (kom 1986) eller ArcGis (kom 1999) krävdes det licenser för varje enskild användare och kostnaden för ett enda GIS-program kunde snabbt äta upp budgeten för alla läroböcker i samtliga SO-ämnen för flera år. Som en räddare släpptes Qgis 2002. Det var ett gratisprogram med de funktioner Mapinfo och ArcGis också hade. Men Qgis var så långt ifrån användarvänligt det rimligtvis gick att komma vilket gjorde att det krävde lång tid för både lärare och elever att sätta sig in i hur Qgis fungerade. Vilket i sin tur blev en omöjlighet då tidsutrymmet för GIS i grundskolan eller gymnasiet endast ligger på en handfull lektioner. Dessutom krävdes det att eleverna själva hade tillgång till datorer med Windows. Datorer som de inte var spärrade från att installera egna program på. Kort sagt, Qgis var inget alternativ, heller .

När Google släppte sin programsvit med gratis kontorsprogram för alla användare med Googlekonto, följde även ett enkelt kartprogram med, Google My Maps. Det använde sig av samma kartbas som Google Maps, som finns online utan att det krävs en installation, men till skillnad från Google Maps kan My Maps läsa in .kml-filer och har dessutom en lagerfunktion där upp till tio olika lager kan användas. Detta var första, enkla sättet att kunna använda GIS på ett sådant sätt att även elever i högstadiet klarade av att hantera lagrade kartor. Tyvärr har det visat sig att många kommuner inte köpt in My Maps i samband med att skolorna försetts med Chromebooks och Google Classroom, eller så har My Maps spärrats av kommunen med hänvisning till GDPR vilket hänt i bland annat Uddevalla, Sollentuna och Timrå. Många skolor har dessutom valt Microsifts Office 365 som lösning för eleverna och då faller Google My Maps bort fullständigt.

Det som behövs är därför en enkel applikation som fungerar i alla miljöer oavsett om eleverna hanterar Chromebooks, macdatorer eller PC, som inte kostar pengar, som inte behöver installeras som program, som är lätt för elever att lära sig hur den fungerar och som ändå uppfyller kraven på hur GIS kan användas som underlag för t.ex. samhällsplanering.

Som tur är finns det en sådan applikation - möt Leaflet.

Läs gärna texten här på Grundskoleboken, men den måste kompletteras med kartorna i hemsidorna som hör till varje moment för att du ska förstå hur Leaflet ska användas..


Leaflet 1 - Första kartan

Leaflet är ett bibliotek med javascript som används för att ladda in kartor från fristående databaser. Leaflet har inga egna kartor, det är ett vanligt nybörjarfel att tro det, utan varje karta som visas upp länkas in från någon annan plats på Internet. Någonting som gör att användningen inte kräver egna lagringsplatser för kartor och bilder och som dessutom gör användningen extra flexibel. Den vanligaste kartbasen är OSM, eller Open Street Maps. En konkurrent till Google Earth, men som till skillnad från Google Earth är helt fri att använda i alla former av applikationer eller hemsidor, så länge det finns en Copyrightsymbol och en text som hänvisar till OSM.

Pseudokod är hur en programmerare tänker sig att en kod ska fungera i ett dataprogram, utan att skriva kod för ett specifikt programmeringsspråk. Pseudokod kommer att användas flitigt i texten om Leaflet. Pseudokoden för första kartan är:

Skapa en hemsida.
I den lägger du till koden för Leaflet, först CSS-koden och sedan Javascript-koden. Ordningsföljden är viktig.
Dessutom förklarar du för Leaflet varifrån kartan ska tas.
Du beskriver hur stort fönster på hemsidan som kartan ska ta upp.
Slutligen lägger du in kod som ritar ut kartan på sidan.


Vill du se hur det ser ut när den första kartan är utlagd, är resultatet inlagt på en hemsida i Google Sites, på samma sätt som du eller dina elever kan göra om ni använder Google Classroom eller Google Workspace. Det ser ut så här: https://sites.google.com/view/leaflet-ingemar-1/startsida.

Hur du och eleverna får fram sidor med kartor kan vara ett problem, men det behöver inte vara det. Egentligen finns det tre olika sätt.

1: Du använder Google Sites som i exemplet. Det enda du behöver göra är att lägga in en ruta med först "Bädda in" och sedan "Bädda in kod" på sidan för att sedan lägga i koden i rutan som visar sig. Nackdelen med kodrutorna i Google är att de är så förtvivlat små.

2: Du skapar ett "Google Apps Script", även det Google Workspace. Då har du mer utrymme att koda på. Resultatet blir relativt likvärdigt. Då skapar du ett App Script i samma eny som en Google Sites skapas. Börja med att klicka på + tecknet i övre vänstra kanten och välj att du vill höra en HTML-fil. Radera all kod Google skapat och skriv in din egen html-kod. Spara i ett unikt namn. Fyll sedan i följande i kodfönstret med namnet kod.gs

function doGet() {
 return HtmlService.createHtmlOutputFromFile('Leaflet_1_ karta.html');
}

Här står namnet på min fil Leaflet_1_ karta.html och det byter du ut till namnet på din egen fil. Spara och välj att "Implementera" så får du upp en himla lång länk, till exempel. https://script.google.com/macros/s/AKfycbznijwXm93S1j9rvAAhxC-0dUIrb05VOXFxW0NyefA/exec (se till att länken slutar på exec och inte dev).

Den stora fördelen med att skapa sidorna som Web Appar är att du har så mycket större yta att programmera på.

3: Du skaffar en hemsideplats någonstans på Internet. Hittar du ingen annan plats finns alltid https://wordpress.org/. Den lösningen ger mest möjligheter oh frihet, samtidigt som det är lättast att bryta mot GDPR av misstag.

Leaflet 2 - Markörer

En stor fördel med att själv kunna skapa kartor är ju att man samtidigt vill kunna lägga in markörer för platser där du som lärare vill att eleverna ska titta en extra gång, eller som stationer vid till exempel en orientering eller en enkel tipspromenad. Detta finns inbyggt i Leaflet. Det som däremot inte är så lätt är att få fram andra färger på markören, eller att använda andra ikoner. Det är inte omöjligt, bara extra krångligt, men det kommer en beskrivning på det med, längre fram.

I mitt exempel ska eleverna gå en tipspromenad runt skolan. Det finns fem markörer utlagda och när de klickar på dem i mobilen eller för musen över dem i datorn, kommer en liten text upp så att eleverna ser i vilken ordning de ska besöka frågorna. https://sites.google.com/view/leaflet-ingemar-2/startsida

Pseudokden är enkel:

Ta reda på koordinaterna i latitud och longitud där frågorna sitter. En punkt har bara ett Y och ett X värde.
Utgå från förra uppgiftens kod och fyll i de nya punkterna på rätt ställe i koden.

Koden till sidan finns under kartan, precis som i förra exemplet. Den kod som är ny är röd. Det som är viktigt att komma ihåg är:

  • Markörerna måste ritas ut efter att kartan ritats upp, annars hamnar de "under" kartan och blir osynliga för användarna.
  • Har du fler en än markör på samma karta måste varje markör ha ett eget, unikt namn.

Koden för att placera ut fem markörer runt skolan, med tillhörande etikettexter, är:


var marker = L.marker([58.0637858,11.8367184 ]).addTo(map)
marker.bindTooltip("Kristinedalskolan, start").openTooltip(); 


var marker1 = L.marker([58.063935,11.838604 ]).addTo(map)
marker1.bindTooltip("Andra").openTooltip();


var marker2 = L.marker([58.062971,11.838044 ]).addTo(map)
marker2.bindTooltip("Tredje").openTooltip();


var marker3 = L.marker([58.063085,11.834621 ]).addTo(map)
marker3.bindTooltip("Fjärde").openTooltip();


var marker4 = L.marker([58.063724,11.834559 ]).addTo(map)
marker4.bindTooltip("Femte, slut").openTooltip();


När det är så här många markörer på så liten yta är det bäst att öka förstoringen ytterligare. På exempelsidan i Google har den ökats från 15 till 16.


Leaflet 3 - Cirklar

Det finns andra sätt att markera platser på en karta. Orienteringskartor använder vanligtvis cirklar eftersom det är en dålig idé att täcka över terrängen med en kartmarkör. Cirklar används till mycket annat också. Ett klassiskt sätt är att markera folkmängden i städer med olika stora cirklar. Ett annat sätt är att använda cirklar med olika färger för att visa olika saker, till exempel vilka som röstat på olika partier i ett val.

Pseudokoden blir:

Byt ut punktmarkörerna mot cirklar.
Byt färg och storlek på cirklarna, för att det ska bli lite snyggare.

Så hur ritar man cirklar? Grundkoden är:

L.circle([lat,lng], radius).addTo(map);

radius är cirkelns radie i meter på kartan. För att ffå en cirkel utritad istället för en platsmarkör skriver du till exempel:

var marker = L.circle([58.063724,11.834559], 10).addTo(map);

Koordinaterna motsvarar cirkelns mittpunkt.

Standardfärgen är samma blå färg som platsmarkörerna, men till skillnad från platsmarkörerna är det enkelt att byta färg, både på själva cirkeln och inuti cirklarna. Precis som med hemsidor kan du välja mellan att skriva ut färgens namn 'red' eller skriva färgkoden hexadecimalt '#ff0000'. Vill du att cirkeln ska vara röd istället för blå skriver du:

marker.setStyle({color: 'red'});

Vill du däremot ha den mörkgul i mitten, en färg som inte går att skriva med ord, skriver du till exempel:

marker.setStyle({fillColor: '#ffcc66'});

Kodexempel: https://sites.google.com/view/leaflet-ingemar-3/startsida men koden som förändrats finns här nedanför:


var marker = L.circle([58.0637858,11.8367184], 50).addTo(map)
marker.setStyle({fillColor: 'orange'});
marker.setStyle({color: 'orange'});
marker.bindTooltip("Kristinedalskolan, start").openTooltip();


var marker1 = L.circle([58.063935,11.838604], 40).addTo(map)
marker1.setStyle({fillColor: 'grey'});
marker1.setStyle({color: 'grey'});
marker1.bindTooltip("Andra").openTooltip();


var marker2 = L.circle([58.062971,11.838044], 30).addTo(map)
marker2.setStyle({fillColor: 'pink'});
marker2.setStyle({color: 'pink'});
marker2.bindTooltip("Tredje").openTooltip();


var marker3 = L.circle([58.063085,11.834621], 20).addTo(map)
marker3.setStyle({fillColor: 'yellow'});
marker3.setStyle({color: 'yellow'});
marker3.bindTooltip("Fjärde").openTooltip();


var marker4 = L.circle([58.063724,11.834559], 10).addTo(map);
marker4.setStyle({fillColor: 'red'});
marker4.setStyle({color: 'red'});
marker4.bindTooltip("Femte, slut").openTooltip();


Leaflet 4 - Rektanglar och polygoner

Ett alternativ till cirklar är rektanglar och kvadrater, som bara är ett specialfall av rektangel. Även dessa används ofta för att visa storlekskillnader, till exempel hur många som bor i en stad, eller skillnader i färg av olika anledningar. Det är enkelt att placera ut rektanglar där alla hörnen är 90 grader. Det räcker med att markera ut var det övre västra hörnet ska vara på kartan, och sedan det nedre högra hörnet. Två X- och Y-koordinater, och sedan vilken färg rektangeln ska vara. Den enda skillnaden, egentligen mot cirklarna är att koordinaterna för en cirkel visar cirkelns mittpunkt, medan koordinaterna för en rektangel visar dess yttre hörn.

Nu är livet inte bara rektanglar med hörn i 90 graders vinkel. Ofta finns istället fyrkanter där hörnen har lite större eller mindre grader, som gräsmattor ofta har. Eller så har ytan någon annan form, som en triangel eller ett parallellogram. Leaflet har funktioner för att rita ut dessa också, på ungefär samma sätt som fyrkanter. Skillnaden är att de då kallas "polygoner" och att samtliga hörns koordinater måste ritas ut.

Anta att du vill rita ut var alla parkeringsplatser finns runt skolan. Rektorns parkeringsplats blir röd för där får bara hon stå. Parkeringsplatser som kräver tillstånd blir gula och övriga blir gröna, då blir pseudokoden:

Kontrollera vilka parkeringsplatser som är helt fyrkantiga med hörn i 90 grader och botten i öst-västlig riktning
Ta fram koordinaterna för övre vänstra hörnet och nedre högra hörnet för samtliga rektanglar
Lägg in rektanglar med rätt färg och de koordinater du tagit fram.
Kontrollera sedan vilka övriga parkeringsplatser det finns runt skolan och ta fram koordinaterna för samtliga hörn på parkeringsplatserna.
Använd de koordinaterna och rita in dem som polygoner.
Ge även polygonerna rätt färg.

En kartmarkör eller en cirkel har bara en enda koordinat. Alla andra former på kartan har fler än en koordinat. Då är det lättast att felsöka om koordinaterna läggs i en egen variabel först, och den variabeln läggs sedan till den form som ska ritas ut. Du kan själv se hur koden ser ut här:

https://sites.google.com/view/leaflet-ingemar-4/startsida

I den koden ser du att en rektangel beskrivs:

var rektor_koordinat= [
[58.06386905803055, 11.836379821966387], 
[58.06382362331538, 11.836526525278202]
];
//Skriv ut
var rektor1 = L.rectangle(rektor_koordinat, {color: 'red', fillColor: 'red'}).addTo(map);


Medan en polygon med fyra hörn istället skrivs:

var fritt_koordinat= [
[58.06439076572815, 11.834103038229207], 
[58.06414275253572, 11.834660681784703], 
[58.063924119592606, 11.834294489156258], 
[58.06415449292313, 11.83377615202827]
];
//Skriv ut
var fritt = L.polygon(fritt_koordinat, {color: 'green', fillColor: 'green'}).addTo(map);


Leaflet 5 - Linjer

GIS bygger på tre grundformer: punkt yta och linje. Nu är vi framme vid den sista grundformen. Redan med de här få kunskaperna kan du skapa ganska avancerade GIS-projekt.

Linjer fungerar exakt på samma sätt som en polygon, som du lärde dig om i moment 4. Enda skillnaden är att de två sista punkterna i polygonens serie inte sitter ihop. Eftersom de inte sitter ihop går det inte heller att fylla det en linje snurrar runt med någon färg. Däremot går det att ange linjens färg och tjocklek. Däremot blir linjen som standard heldragen. Det är krångligt att ändra detta så att den blir streckad, prickig eller heldragen osv.

Hur skillnaden blir mellan polygon och linje är uppenbart om du använder samma koordinater till en linje som i polygonen för gratisparkeringen:

var linje_koordinat= [
[58.06439076572815, 11.834103038229207], 
[58.06414275253572, 11.834660681784703], 
[58.063924119592606, 11.834294489156258], 
[58.06415449292313, 11.83377615202827]
];
var polyline = L.polyline(linje_koordinat, {color: 'red'}).addTo(map);


Då får du en linje i U-form där sista strecket till statpunkten saknas. Här är strecket rött för extra tydlighet.

Så, anta att eleverna i nian ska gå till kommunens enda gymnasieeskola, Nösnäsgymnasiet. Det ligger på gångavstånd, men alla har inte besökt skolan. Därför är det bra med en karta där gångvägen är utritad.Då blir pseudokoden:

Ta fram punkten där eleverna ska samlas utanför Kristinedallskolan
Ta fram koordinaterna för varenda punkt längs vägen där elevernas väg byter riktning.
Ta fram punkten där de ska samlas innan de går in i Nösnäsgymnasiet.
Välj lämplig färg och form på linjen och rita ut den på kartan.
Rita eventuellt ut kartmarkeringar vid start och slut, men gör det efter linjen ritats ut så att markörerna täcker linjen istället för tvärtom.
Rita eventuellt ut en varning där eleverna passerar stora vägen, som är hårt trafikerad.

Observera att ursprungsformen på kartan inte fungerar när de ska gå så långt. Därför har höjden på kartan i exemplet ökats till 800px och centrerar mitt emellan skolorna.

var gymnasiet_koordinat= [
[58.063660583123266, 11.836286234924978],
[58.06378303149182, 11.83593430631026],
[58.063707493569886, 11.834551534735061],
[58.0625600316872, 11.834951631880843],
[58.062379167533116, 11.834122784589399],
[58.06209801056336, 11.834170134085513],
[58.06144047414001, 11.832523808869736],
[58.06079552438438, 11.833059188661965],
[58.06024327618596, 11.832388839953092],
[58.05954838579759, 11.833029782677682],
[58.05829521084645, 11.829339055318455],
[58.058075716090705, 11.828094676346707],
[58.05660054064898, 11.827459196350913],
[58.05607329885935, 11.828221813558484]
]
var polyline = L.polyline(gymnasiet_koordinat, {color: 'blue'}).addTo(map);

Exempelkod:

https://sites.google.com/view/leaflet-ingemar-5/startsida


Leaflet 6 - GIS

Nu har vi slutligen lärt oss hantera en baskarta i olika storlekar som centreras på olika vis. Vi har lärt ss placera ut kartmarkörer, cirklar, rektanglar, polygoner och linjer. Med detta kan vi skapa tjusiga kartor, men det är fortfarande inte ett GIS-system.

Ska vi vara helt ärliga går det att skapa samma sorts kartor som vi gjort nu genom att ta en kopia, eller en skärmdump, på en karta från Open Street Maps och sedan rita in markörer, cirklar, rektanglar och linjer i ett bildbehandlingsprogram. Men då blir kartan statisk. Den går inte att ändra på när den är klar. Det som utmärker GIS-kartor är att de är dynamiska. Det går att ändra innehållet beroende på användarens val. Så hur ändrar vi Leaflet så att det går att göra olika val. So tur är finns de funktionerna inbyggda i Leaflet så även om det kräver lite kodning i javascript är det inte särskilt avancerat.


Baskartan

Leaflet har ingen egen karta, men det finns mängder med olika kartor som går att använda. Hittills har vi använt OSM, eftersom den är gratis, utan copyright och bra i de flesta situationer man kan tänka sig. Men det finns en uppsjö baskartor. Många täcker bara ett visst land, men många täcker in hela världen. Du har ett axplock av baskartor här. Tyvärr är sidan inte uppdaterad på rätt länge så många kartor är "grå" och kan inte användas längre: https://leaflet-extras.github.io/leaflet-providers/preview/ sedan finns det många fler än dessa. Med lite trixande går det att få in Googles kartor och satellitbilder i Leaflet och även svenska Lantmäteriets kartbas går att koppla in, med lite extra arbete.


Täckbladen

Ovanpå baskartan ligger osynliga täckblad som markörer, cirklar, kvadrater och liknande ritas ut på. Det går att tänka sig att det är genomskinliga plastbald som ligger på varandra som en kortlek, och sedan väljer du vilka blad du vill lägga ut de olika komponenterna på, beroende på vad du vill visa. Vill du visa var alla eleve i en klass bor kan du dela upp det så att alla flickor ritas ut på ett blad och alla pojkar på ett annat. Vill du rita snabbaste vägen till kiosken kanske du använder en karta på sommaren när det inte är snö, men en annan på vintern.


Tematiska kartor

Längre fram ska vi gå igenom tematiska kartor, där olika teman påverkar kartans utséende, och då behöver det också finnas möjlighet att välja ut de delar som ska visas, och gömma undan det som är onödigt och förvirrande att visa upp.

Hela det här temat bygger på Leaflets eget exempel, som du kanske tycker kan hjälpa dig om du kär fast i min beskrivning: https://leafletjs.com/examples/layers-control/

Pseudokoden blir:

Skapa innehållet på första lagret, på samma sätt som du brukar lägga ut innehåll, men tänk på att allt på ett lager bör ha något med varandra att göra. Det kan till exempel vara skolor på en ort.
Lägg till två kartor så användaren kan välja vilken av dessa två bakgrunskartor han eller hon vill använda.
Skriv ut kartmenyn längst upp till höger i kartan. Kontrollera att namnen på lagren är korta så inte menyn blir alldeles för bred efter klickande på den.
Lägg till nya lager, men observera att det är en annan procedur att lägga till nya lager efter att kartmenyn skrivits ut
Lägg slutligen till fler bakgrunskartor om du vill, eller har behov av dem. Det är samma procedur att lägga in fler bakgrundsartor trots att kartmenyn skrivits ut på kartan


Anta att vi vill visa var alla skolor finns i Stenungsund. För att kunna stänga av och slå på visningen måste vi skaffa en hållare, ett genomskinligt plastark, som vi lägger ut markörerna för skolorna på: I Leaflet kallas ett sånt genomskinligt lager för ".layerGroup". Vilket är opedagogist när den bara ska visa ett lager, men grupper av kontroller på det lagret. Vi kan kalla det för "skolor". var skolor= L.layerGroup();

Observera att Leaflet vill att du skapar det första lagret som automatiskt visas upp när sidan först visas på ett speciellt sätt. Där skapas först lagergruppen och sedan kontrollerna som kopplas till lagret. Ska du lägga till nya lager sker det tvärtom. Då skapar du kontrollerna först och sedan kopplar du det till en lagergroup (se exempel på hemsidan https://sites.google.com/view/leaflet-ingemar-6/startsida ).

Skapa också minst en baskarta, som vanligt, som kontrollerna ska vila på.

Skapa sedan kartmenyn. Den som ser ut som en hög papper som ligger på varandra uppe till höger på kartan med kommandot:

var layerControl = L.control.layers(baseLayers, overlays).addTo(map);


För att underlätta förståelsen av koden har den exempelkartan från USA utökats med en svensk karta som innehåller fler baskartor och fler lagergrupper, för att det ska bli enklare att förstå hur kartmenyn är uppbyggd genom att läsa kommentarerna i koden. Den svenska versionen hittar du här: https://sites.google.com/view/leaflet-ingemar-6/svenskt-exempel

Det enda du måste tänka på är:

  • att de olika lagren med kontroller skapas i omvänd ordning efter att kartmenyn skrivits ut
  • att namnen på de olika lagren ska vara korta för att inte kartmenyn ska bli enorm när användare klickar på den
  • att kartan bör ha minst två bakgrundskartor, annars kan märkliga fel uppstå, men lägg gärna in fler olika bakgrundskartor


Källor

https://leafletjs.com/

https://leanpub.com/leaflet-tips-and-tricks/read