DHM-API — terræn- og overfladehøjde ved punkt over Dataforsyningen
DHM (Danmarks Højdemodel) er Register #4 i Grundfast: terræn- og overfladehøjde (DTM/DSM) for et koordinat, meter over DVR90, slået op i ét kald — WGS84 ind, intet højdemodel-grid at hoste selv. Det er live nu over Dataforsyningen DHM-WCS’en — demo og datakontrakt kan du teste uden nøgle.
GET /v1/dhm/punktHvad DHM-API’et giver dig
Terræn- og overfladehøjde i ét kald
Både terrænhøjde (DTM, bar jord) og overfladehøjde (DSM, inkl. bygninger og vegetation) for samme koordinat — i ét opslag, meter over DVR90.
Objekthøjde = differensen
Overflade minus terræn giver objekthøjden i punktet — fx en bygnings- eller træhøjde — uden et ekstra opslag eller et eget højdemodel-grid at hoste.
Målt bygningshøjde på hele ejendommen
GET /v1/dhm/bygninger/:bfe måler hver bygning INDE i dens GeoDanmark-fodaftryk — 95-percentilen af overfladen mod medianen af terrænet, så et træ over taget ikke bliver til tag. Ét kald pr. ejendom, ikke ét pr. bygning.
Terrænkoter til situationsplanen
GET /v1/dhm/kote svarer med koten OG sit højdesystem (DVR90), opløsning, metode og usikkerhed — en kote uden system kan kommunen ikke kontrollere. Hjørnerne af en tegnet bygning tages i ét kald med POST /v1/dhm/kote:batch, og faldet over grunden med GET /v1/dhm/profil.
Punktopslag i WGS84
Send lon/lat i WGS84; vi reprojicerer internt til EPSG:25832 og slår op i DHM-griddet. Ingen EPSG-jonglering og intet projektionslag i din kode.
Samme stabile cache/SLA-lag
DHM-WCS’en er vægelsindet. Grundfast lægger det samme cache- og SLA-lag oven på den, som du kender fra BBR og Matriklen — så et punktopslag svarer forudsigeligt.
Kald DHM i din stack
Endpointet er GET /v1/dhm/punkt?lon=&lat= med en gf_live_-nøgle — samme auth og metering som de øvrige registre. Send lon/lat i WGS84; samme punktopslag i cURL, TypeScript og Python:
curl -H "Authorization: Bearer gf_live_…" \ "https://api.grundfast.dk/v1/dhm/punkt?lon=12.5683&lat=55.6761"
Status & datakontrakt
Endpointet er GET /v1/dhm/punkt?lon=&lat= med samme nøgle, auth og metering som BBR og Matriklen — med en burst-grænse pr. nøgle, fordi hvert kald rammer den live DHM-WCS upstream. Et gyldigt punkt uden dækning svarer 200 med null; upstream-fejl svarer 502. Demo-datakontrakten har den endelige form:
# Live nu — Register #4 (Bearer gf_live_…): GET /v1/dhm/punkt?lon=12.5683&lat=55.6761 → 200 { punkt: { lon: 12.5683, lat: 55.6761 }, epsg25832: [725483.12, 6177378.45], terraen_m: 2.41, overflade_m: 14.87, meta: { kilde: "Dataforsyningen DHM via Grundfast", grundfast_version: "0.1.0" } } # objekthøjde = overflade_m − terraen_m ≈ 12.46 m (fx bygning) # Gyldigt punkt uden dækning (fx på havet) → 200 med null: → 200 { …, terraen_m: null, overflade_m: null, … } # Målt højde på hver bygning på en ejendom: GET /v1/dhm/bygninger/5651067 → 200 { bfe_nummer: 5651067, system: "DVR90", metode: { tag: "p95", terraen: "median", hoejde: "tag_m - terraen_m" }, bygninger: [ { bbr_uuid: "0a3f5f2e-…", hoejde_m: 6.2, hoejde_maalt: true, hoejde_kilde: "DHM", tag_m: 18.6, terraen_m: 12.4, terraen_min_m: 12.1, terraen_max_m: 12.9, antal_celler: 742, celle_m: 0.4, aarsag: null } ], ufuldstaendig: false, attribution: "@geodanmark", meta: { … } } # kan en bygning ikke måles: hoejde_m: null + aarsag — aldrig 0 # Terrænkote til en situationsplan — samme svar, dokument-navnet: GET /v1/dhm/kote?lon=12.5683&lat=55.6761 → 200 { …, terraen_m: 2.41, overflade_m: 14.87, system: "DVR90", system_epsg: 5799, oploesning_m: 0.4, metode: "naermeste_celle", usikkerhed_m: 0.05, meta: { … } } # Hjørnerne af en tegnet bygning i ét kald (ét raster, ikke otte opslag): POST /v1/dhm/kote:batch { "punkter": [ { "lon": 12.5683, "lat": 55.6761, "id": "NV" }, … ] } → 200 { punkter: [ { id: "NV", terraen_m: 2.41, system: "DVR90", … } ], fejl: [], forespurgt: 4, besvaret: 4, fejlet: 0, meta: { … } } # et punkt der ikke kunne besvares havner i fejl — aldrig i punkter med null # Faldet over grunden, fx fra vej til skel bagest: GET /v1/dhm/profil?fra=12.5683,55.6761&til=12.5689,55.6761&trin=1 → 200 { laengde_m: 37.6, trin_m: 1, system: "DVR90", punkter: [ { afstand_m: 0, lon: 12.5683, lat: 55.6761, terraen_m: 2.41 }, … ], terraen_min_m: 2.41, terraen_maks_m: 4.21, fald_m: 1.8, oploesning_m: 0.4, usikkerhed_m: 0.05, meta: { … } } # Demo-datakontrakten virker uden nøgle: GET /v1/demo/dhm → 200 { punkt, epsg25832, terraen_m, overflade_m, system, system_epsg, oploesning_m, metode, usikkerhed_m, meta }
/v1/dhm/punkt?lon=&lat=lon/lat i WGS84 → terraen_m og overflade_m i meter over DVR90. Klar at kalde nu.
/v1/dhm/kote?lon=&lat=Samme kote, dokument-navnet — og svaret bærer selv DVR90, opløsning (0,4 m), metode og usikkerhed (0,05 m).
/v1/dhm/kote:batchOp til 50 punkter i ét kald — hjørnerne af en tegnet bygning plus nærmeste skelpunkt. Afregnes pr. punkt, ikke en plan-feature.
/v1/dhm/profil?fra=&til=&trin=Terrænet langs en ret linje med fald_m — hvor meget grunden falder fra vej til skel. Ét raster, ikke ét kald pr. station.
/v1/demo/dhmDemo-datakontrakten i den endelige form — virker uden nøgle.
Kom i gang med DHM
Opret en gf_live_-nøgle i dashboardet og kald /v1/dhm/punkt?lon=12.5683&lat=55.6761. Spørgsmål om dækning eller burst-grænser? Skriv til os.
Se også
Ofte stillede spørgsmål
Kan jeg få terrænkoter til en situationsplan i Byg og Miljø?
Ja. GET /v1/dhm/kote?lon=&lat= giver terrænkoten i DVR90, og svaret bærer selv højdesystemet (system: "DVR90", system_epsg: 5799), griddets opløsning (oploesning_m: 0.4), hvordan værdien er taget ud af rasteret (metode: "naermeste_celle" — cellen koordinatet falder i, ikke interpoleret) og modellens specificerede lodrette nøjagtighed (usikkerhed_m: 0.05 m). Det sidste er produktets landsdækkende tal, ikke en fejlmargin for netop dit punkt: under træer og over vand er terrænet interpoleret over tyndere data, og usikkerheden er reelt større. Skriv derfor koten som vejledende, fra terrænmodellen — det er ikke et landinspektørnivellement. Hjørnerne af en tegnet bygning kan hentes i ét kald med POST /v1/dhm/kote:batch (op til 50 punkter, afregnet pr. dedupliceret punkt, og som det eneste batch-endpoint ikke en plan-feature), og faldet over grunden med GET /v1/dhm/profil?fra=&til=&trin=, der svarer med fald_m. Et punkt uden data er altid null — aldrig 0, for 0 m DVR90 er en helt plausibel kote kystnært, så en fejl der lander som 0 ville være usynlig; kan laget slet ikke nås, får du 502.
Måler I byggeretten eller det skrå højdegrænseplan for mig?
Nej. Vi svarer med terrænet — koten, faldet over grunden, koten ved skellet — og ikke med en dom om, hvorvidt et projekt overholder byggeretten. BR18 måler bygningshøjden fra terræn, og § 177 måler det skrå højdegrænseplan fra terrænet ved skel, men hvilket terræn der er det gældende (naturligt terræn eller et fastlagt niveauplan) afgøres i den konkrete sag af kommunen. Du kender projektet, vi kender terrænet — samme snit som på skovbyggelinjen.
Er DHM-API’et live nu?
Ja. GET /v1/dhm/punkt?lon=&lat= er live som Register #4 — kørt over Dataforsyningen DHM-WCS’en (coverages dhm_terraen + dhm_overflade). Demo (/v1/demo/dhm) virker uden nøgle. Endpointet svarer kun 503, hvis en deployment ikke har DHM-kilden konfigureret — det er ikke tilfældet i prod.
Hvad er forskellen på terraen_m og overflade_m?
terraen_m er terrænhøjden (DTM, den bare jord) i meter over DVR90, og overflade_m er overfladehøjden (DSM), som inkluderer bygninger og vegetation. Differensen overflade_m minus terraen_m svarer til objekthøjden på punktet — fx en bygnings- eller træhøjde — så du får den uden et ekstra opslag.
Hvordan får jeg højden på en bygning frem for på et punkt?
Brug GET /v1/dhm/bygninger/:bfe. Den måler hver bygning på ejendommen inde i dens GeoDanmark-fodaftryk i stedet for i ét punkt: tag_m er 95-percentilen af overflademodellen over fodaftrykket — en percentil, ikke maksimum, så en gren ind over taget ikke trækker højden flere meter op — og terraen_m er medianen af terrænmodellen under de samme celler, med terraen_min_m og terraen_max_m ved siden af, så faldet under en bygning på en skrånende grund kan ses. hoejde_m er forskellen. Alle koter er DVR90, og system og metode står i selve svaret. En højde er enten målt eller null med en aarsag — den er aldrig 0 for “ukendt” og gættes aldrig ud fra BBR’s etageantal. Ét kald dækker hele ejendommen, uanset hvor mange bygninger der står på den.
Hvilke koordinater skal jeg sende, og hvad sker der uden for Danmark?
Send lon/lat i WGS84 (lon ~7–16, lat ~54–58). Mangler en parameter, eller ligger punktet uden for Danmark, svarer endpointet 400. Et gyldigt punkt uden dækning — fx på havet — svarer 200 med terraen_m og overflade_m sat til null. Fejler DHM-WCS’en upstream, får du 502. Vi reprojicerer internt til EPSG:25832, så du selv slipper for EPSG-håndtering.
Hvad koster DHM-opslag?
DHM kører på den fælles selvbetjente prismodel (Free / Starter / Pro / Scale) med samme nøgle og metering som BBR, Matriklen og DAGI. Se priser for kald-inkluderet og overforbrug.
Er Grundfast officielt / tilknyttet SDFI?
Nej. Grundfast er et uafhængigt compatibility-lag — uofficielt, men det virker. DHM-data stammer fra Dataforsyningen / SDFI (CC BY 4.0); vi krediterer kilden.
Højder for hvert punkt i Danmark
Danmarks Højdemodel — terræn- og overfladehøjde ved enhver koordinat i landet, fra det samme datasæt klimatilpasning og forsyning bygger på. Slå en højde op med lon/lat, hvor som helst i Danmark.