Jeg har brukt kartbiblioteket maplibre for å representere skipstrafikk på kart i mobil-apper og webløsninger og blir stadig mer begeistret for hvor elegant det er å sette opp visning av kart med maplibre.
Deklarative kart
Deklarative kart er litt som deklarativ UI. Istedenfor å imperativt si hvordan kartet skal bygges opp så kan vi beskrive hvordan kartet skal se ut og oppføre seg. Koden blir lettere å lese og beskrivelsen av kartet blir til en funksjon der du putter inn data og får ut et pent kart.
For å vise dette i praksis skal vi vise ulike fargemarkører for båtposisjoner på et kart og navn på båtene som dukker opp når vi zoomer inn.
Layers og sources
Layers i maplibre er på en måte funksjonen, eller beskrivelsen, som bestemmer hvordan kartet skal se ut. Layers inneholder f.eks informasjon om hvor stor en prikk skal være, fargen den skal ha og eventuelt hvordan tekst skal formatteres.
Vi starter med å bare lage et enkelt layer som viser alle båter som grå sirkler på kartet, her illustrert i typescript:
mapController.addLayer({
id: "boat-layer",
type: "circle",
source: "boat-source",
paint: {
"circle-color": '#888888',
"circle-radius": 5,
},
});
Alle layers trenger en data-kilde som den kan bruke for å vise noe.
Datakilden, eller source
på nynorsk, er selve dataene vi skal vise frem. Datakilden inneholder typisk informasjon om posisjoner, hva slags geo-type dette er (punkt, område, linje etc.) og de metadata vi synes er viktige å vise på et kart.
Siden layeret over refererer til datakilden boat-source
, lager vi denne med informasjon om at dette er punkt-data på geojson-format og litt metadata som vi dytter inn i properties
-mappet:
function boatSourceData(shipList: ShipPosition[]): maplibregl.SourceSpecification {
return {
type: "geojson",
data: {
type: "FeatureCollection",
features: shipList.map((ship: ShipPosition) => ({
type: "Feature",
properties: {
shipName: atob(ship.name),
shiptype: ship.type,
},
geometry: {
type: "Point",
coordinates: [ship.lon, ship.lat],
},
})),
},
};
}
Resultatet blir et kart med grå prikker:
Betingelser, grå båter er kjedelige
Men grå båter er kjedelige. Vi vil ha masse farger! Heldigvis har vi puttet skipstypen inn i properties-mappet, så vi kan ganske enkelt endre boat-layer
til å velge farge basert på skipstypen:
mapController.addLayer({
id: "boat-layer",
type: "circle",
source: "boat-source",
paint: {
"circle-color": [
"match",
["get", "shiptype"],
"50", "#00FF00", // grønn hvis type 50, fiskebåter
"55", "#0000FF", // kystvakten er blå
"30", "#FF0000", // passasjerbåter er røde
"35", "#FFA500", // oljetankere er oransje
//... det finnes mange kategorier for båter!
"#888888", // grå som standard farge
],
"circle-radius": 5,
},
});
I dette eksempelet har jeg brukt match
-operatoren for å sjekke skipstypen, men det er mange avanserte operatorer tilgjengelig hvis man har andre typer kriterier man vil bruke.


Grå båter blir til fargerike båter 🔵🟡🟢🔴🟠
Zoom for mer info
Det er gjerne sånn at vi vil vise mere informasjon om båtene hvis vi zoomer nærmere. Navnet på båtene trenger vi for eksempel ikke å vise før vi har zoomet et godt stykke ned i kartet. Et norges-kart med navn på alle båtene synlig ville unektelig blitt ganske rotete.
For å legge til visning av navn på båtene lager vi et nytt layer med samme datasource som tidligere. Og så sier vi fra at navn på båtene bare skal vises når vi har zoomet godt inn på kartet (zoom-nivå 9 til 20):
mapController.addLayer({
id: "boat-names",
type: "symbol",
source: "boat-source",
minzoom: 9,
maxzoom: 20,
layout: {
"text-field": ["get", "shipName"],
"text-anchor": "center",
"text-offset": [0, 0.6],
},
paint: {
"text-color": "black",
},
Datakilden kan altså gjenbrukes til å lage så mange ulike typer layers vi måtte ønske.


Navnet på båtene kommer til syne når vi zoomer inn på kartet til høyre
Web og mobil
Maplibre har biblioteker til både web, Android og iOS og apiene er veldig like på tvers av plattformene.
Hvis du vil se hva jeg bruker kartene til kan du jo laste ned Farvann-appen for iOS og Android eller titte på web-versjonen som er under arbeid 🏗️.
Maplibre og mapbox
Maplibre er en opensource-fork av mapbox og bygger videre på den siste versjonen av mapbox som var opensource. Apiet er så og si likt mellom maplibre og mapbox, med unntak av noen kommersielle funksjoner i mapbox.
Verdien av deklarative kart
Det er mye å holde styr på når man skal kode visning av kart. Og det er her verdien av deklarative kart gjør seg gjeldende ved å gjøre representasjonen av kartet til en funksjon der vi kan dytte data inn og få et pent kart ut. Med et klart skille mellom kart-representasjonen og kart-data blir koden lettere å forstå og resonnere rundt. Maplibre gjør dette mulig ved å skille mellom layers som beskriver hvordan ting skal vises og sources som definerer data som skal vises.