Viden ·
Læg danske ortofotos ind i Leaflet, MapLibre og OpenLayers
Billederne er gratis, landsdækkende og ligger i EPSG:25832. Dit kortbibliotek vil formentlig hellere have EPSG:3857. Her er de tre veje igennem, hvad hver af dem koster dig, og den ene begrænsning der afgør valget, før du begynder at skrive kode.
Vi tilbyder ikke API'et i dag, og vi har ingen dato for det. Billederne henter og leverer vi som opgave — ring på +45 42 72 45 10.
Konflikten, i én sætning
De nationale ortofotos er produceret i EPSG:25832 — ETRS89 / UTM zone 32N. Det er ikke et valg, Dataforsyningen har truffet for at genere nogen; det er det koordinatsystem, Danmark opmåles i, og alt andet indebærer en reprojektion.
Slippy maps — den slags kort, man kan trække rundt i og zoome på — er derimod født i EPSG:3857, Web Mercator. Det er det, fliseskemaet {z}/{x}/{y} betyder, og det er det, langt de fleste baggrundskort, du vil lægge ved siden af, ligger i.
Hele artiklen her handler om den sætning. Du kan møde den tre steder — i serveren, i biblioteket eller slet ikke — og de tre steder er de tre veje nedenfor.
Først: hvad dit bibliotek faktisk kan
Det her er det spørgsmål, der skal besvares før alt andet, fordi det ene af svarene fjerner to af de tre veje. De tre biblioteker er ikke lige fleksible, og forskellen er ikke en smagssag.
Vælger du MapLibre, fordi kortet skal være vektorbaseret og køre på GPU'en, har du samtidig valgt Web Mercator. Det er ikke en mangel ved biblioteket — det er en konsekvens af, at hele dets flise- og kameramodel er bygget om én projektion.
| Bibliotek | Kan arbejde i EPSG:25832? | Hvad det betyder for dig |
|---|---|---|
| OpenLayers | Ja, indbygget via proj4 | Det eneste af de tre, hvor du kan vise billederne i deres eget koordinatsystem uden omveje |
| Leaflet | Kun med en udvidelse | Kernen kender én projektion. En plugin kan give den flere, men du skal selv definere opløsningstrinnene |
| MapLibre GL JS | Nej | Rasterkilder skal være Web Mercator. Reprojektionen skal ske et andet sted — det er ikke til forhandling |
Vej 1 — lad serveren om reprojektionen (WMS)
Den korteste vej, og den der virker i alle tre biblioteker: bed WMS-tjenesten om billedet i EPSG:3857, og lad den om omregningen. Du får et billede tilbage, der passer direkte ind i et almindeligt webkort.
Prisen er en resampling. Pixlerne er blevet genberegnet fra deres oprindelige gitter til et nyt, og det er ikke gratis for skarpheden — særligt ikke på kanter og tynde linjer. Til et oversigtskort er det ligegyldigt. Til en opmåling er det ikke.
Den anden pris er driftsmæssig: hvert kald får serveren til at rendere et billede på bestilling. Det er dyrere for dem end at udlevere en flise, der allerede ligger færdig — og det er værd at have i baghovedet over for en tjeneste, der er gratis og ikke giver nogen driftsgaranti.
// Leaflet — kernen er i EPSG:3857, så serveren må levere i 3857
L.tileLayer.wms('https://api.dataforsyningen.dk/orto_foraar', {
layers: 'orto_foraar',
format: 'image/jpeg',
version: '1.3.0',
token: 'DIN_TOKEN',
attribution: '© Klimadatastyrelsen / GeoDanmark — CC BY 4.0'
}).addTo(map);
// OpenLayers — samme idé, samme projektion
new ol.layer.Tile({
source: new ol.source.TileWMS({
url: 'https://api.dataforsyningen.dk/orto_foraar',
params: { LAYERS: 'orto_foraar', FORMAT: 'image/jpeg', VERSION: '1.3.0', token: 'DIN_TOKEN' },
attributions: '© Klimadatastyrelsen / GeoDanmark — CC BY 4.0'
})
});
Servicenavnet og lagnavnet her er dem, man typisk møder. Slå dem op i tjenestens eget GetCapabilities-svar frem for i et blogindlæg — de skifter med årgangene, og det er den hyppigste grund til, at et kald, der virkede sidste år, holder op.
Vej 2 — hent fliser, der allerede ligger færdige (WMTS)
Dataforsyningen udstiller ikke kun WMS. Der findes også WMTS — forhåndsskårne fliser — og blandt varianterne er der en i Web Mercator. Er det den, du rammer, sker der ingen reprojektion nogen steder: fliserne ligger allerede i det gitter, dit kort beder om.
Det er den billigste vej for alle parter, og det er den, du skal foretrække til et baggrundskort, som mange mennesker skal kigge på. Den er også den eneste af de tre, hvor et almindeligt XYZ-lag er nok — ingen WMS-parametre, ingen bbox, bare en URL med {z}/{x}/{y} i.
Den ene ting, du skal gøre selv: hente de faktiske navne. En WMTS har et navngivet *tile matrix set*, og navnet afgør, hvilken projektion du får. Læs det ud af tjenestens GetCapabilities i stedet for at gætte — et forkert matrix set giver ikke en fejl, det giver et kort, der ligger forskudt.
- Hvorfor står min token i URL'en her, når den ellers skal i en header?
Fordi et fliselag ikke kan sende headere. Du afleverer en URL-skabelon til biblioteket, og det henter selv fliserne — der er ikke noget sted at hænge en header op.
Det er den ene legitime grund til at bruge URL-parameteren, og den gælder kun fliser. Alt andet — capabilities, enkeltkald, batchjob — skal stadig bruge headeren. En token i en URL ender i adgangslogs, browserhistorik og referrers; en token i en header gør ikke.
- Kan jeg så ikke bare lægge min token direkte i frontend-koden?
Du kan, og så er den offentlig. Enhver, der åbner netværksfanen, kan læse den og bruge den til alt andet, kontoen kan.
Den praktiske løsning er en proxy: din egen server står mellem kortet og Dataforsyningen, lægger tokenen på, og cacher svaret. Det giver dig samtidig cachen, som du skal have alligevel.
- Hvor længe må jeg cache fliserne?
Så længe du vil. Et ortofoto for en given årgang ændrer sig ikke bagefter, så en flise, du hentede i går, er den samme i morgen.
Der er ingen offentliggjort kvote på webtjenesterne. Det er ikke det samme som, at du må hamre løs: risikoen er ikke juridisk, men driftsmæssig, og en proxy uden cache er præcis den slags, der får en token spærret.
- Skal jeg bruge forårs- eller sommerserien som baggrundskort?
Til et baggrundskort er forårsserien næsten altid den rigtige: den er fløjet uden løv, så veje, bygninger, dræn og befæstede arealer er synlige frem for skjult under trækroner.
Vælger du sommerserien, så gør det bevidst og af en grund, der har med vegetation at gøre. Der er en artikel om netop det valg linket nederst.
Vej 3 — vis billederne i deres eget koordinatsystem
Den sidste vej er den, der ikke reprojicerer noget som helst: du lader kortet arbejde i EPSG:25832. Det er den rigtige, hvis dine øvrige data også er i 25832 — matrikler, ledningsnet, opmålinger — og du vil kunne måle i kortet uden at tænke over, hvilket gitter du måler i.
I OpenLayers er det en indbygget mulighed. Du registrerer projektionen med proj4, giver visningen den, og resten af biblioteket følger med.
I Leaflet kræver det en udvidelse, der kan give kernen en anden CRS, og du skal selv aflevere opløsningstrinnene — ét tal per zoomniveau, i meter per pixel. Dem skal du hente fra tjenestens eget tile matrix set og ikke regne ud i hånden.
I MapLibre kan det ikke lade sig gøre. Hvis kortet skal være i 25832, er MapLibre det forkerte værktøj til opgaven — og det er bedre at vide på dag ét end på dag ti.
import proj4 from 'proj4';
import { register } from 'ol/proj/proj4';
import { get as getProjection } from 'ol/proj';
proj4.defs(
'EPSG:25832',
'+proj=utm +zone=32 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs'
);
register(proj4);
const map = new ol.Map({
target: 'map',
view: new ol.View({
projection: getProjection('EPSG:25832'),
center: [725000, 6175000], // meter, ikke grader
zoom: 12
})
});
Bemærk centerkoordinaten: i EPSG:25832 er enheden meter, og tallene er sekscifrede. Taster du et par grader ind, får du ikke en fejl — du får et kort over Atlanterhavet. Det er den fejl, der koster flest minutter første gang.
Vælg vejen ud fra opgaven, ikke ud fra vanen
| Opgaven | Vejen | Hvorfor |
|---|---|---|
| Baggrundskort til mange brugere | Vej 2 — WMTS i Web Mercator | Forhåndsskårne fliser, ingen reprojektion, billigst for alle |
| Et hurtigt internt kort | Vej 1 — WMS i EPSG:3857 | Færrest linjer kode, virker i alle tre biblioteker |
| Kort oven på danske fagdata | Vej 3 — EPSG:25832 | Ingen omregning mellem dine lag; du kan måle direkte |
| Vektorkort på GPU | Vej 1 eller 2, aldrig 3 | MapLibre kan kun Web Mercator |
Kildeangivelse hører til i kortet, ikke i en fodnote
De nationale ortofotos er frie data under CC BY 4.0. Du må kopiere dem, ændre dem, sammensætte dem med andet og bruge dem kommercielt. Til gengæld skal du kreditere kilden, og det er et vilkår, ikke en høflighed: overtræder du det, bortfalder licensen automatisk.
Alle tre biblioteker har et attribution-felt på selve laget, og det er det rigtige sted. Det følger laget rundt, det står i kortet frem for i bunden af en side, ingen kan glemme det ved næste redesign, og det forsvinder af sig selv, hvis laget bliver slukket.
Den tekst, vi selv bruger, står nederst på hver side her, og licensnavnet i den er et link til licensteksten. Den samme tekst hører hjemme i dit kort. Og ændrer du billederne — det gør du, når du reprojicerer, skærer dem om eller komprimerer dem igen — skal det også fremgå, at materialet er ændret.
Når kortet ikke er det, du egentlig skulle bygge
Opsummeret er arbejdet her: en konto, en token, en proxy så tokenen ikke står i browseren, en cache så du ikke belaster en gratis tjeneste, det rigtige matrix set, de rigtige lagnavne for den årgang du vil have, og en kildeangivelse der overlever næste redesign. Det er en dags arbejde første gang og en halv dag igen, hver gang noget af det skifter.
Det er netop det stykke, et API hos os ville fjerne: fliser i Web Mercator, der falder direkte ind i alle tre biblioteker, med kildeangivelsen i svaret. Vi tilbyder det ikke i dag — til gengæld leverer vi udsnittet i det koordinatsystem, I arbejder i, og den vej er den tabsfri.
Skal du derimod bruge ét baggrundskort i ét internt værktøj én gang, så brug fremgangsmåden ovenfor. Den er gratis, og den er bygget til netop det.
Kilder og videre læsning
- Dataforsyningen — kom i gang med webservices Hvilke servicetyper der findes — WMS, WMTS, WFS, WCS og OGC API Features — og hvordan den enkelte tjeneste adresseres.
- Dataforsyningen — log ind og token Konto og selvbetjent token, headeren kontra URL-parameteren, og kravet om HTTPS med TLS 1.2.
- GeoDanmark Ortofoto Produktet selv: hvem der laver det, hvad det dækker, og hvilke serier der findes.
- Sådan henter du et dansk ortofoto over WMS i EPSG:25832 Selve GetMap-kaldet bag vej 1, og de tre fejl der ligner en serverfejl men er dine egne.
- EPSG:25832 eller EPSG:4326? Hvilket koordinatsystem du skal gemme i, og akserækkefølgen der vender om mellem WMS-versionerne.
- Dataforsyningen-token: opret, navngiv, forny Hvorfor kortets token skal være sin egen, og hvad du gør den dag den udløber midt i et kort.
- Forår eller sommer? Vælg den rigtige ortofotoserie Hvilken af de to serier dit baggrundskort skal ligge på, og hvornår valget ændrer konklusionen.
Telefonen er den hurtigste vej — ring, så henter vi billederne for dig.