Afstand mellem to adresser

Beregn afstanden i luftlinje mellem to adresser med afstands-endpointet, eller regn den selv ud fra koordinaterne med haversine eller UTM32.

3 min Niveau: Begynder ✓ Kode testet

Kørselstillæg ud fra afstanden til kunden, et leveringsområde på 15 km fra lageret, eller den nærmeste butik til en adresse: alt sammen starter med afstanden mellem to punkter.

API'et har et endpoint, der beregner afstanden mellem to adresser. Skal du beregne mange afstande, er det hurtigere at hente koordinaterne én gang og regne selv. Begge dele er afstand i luftlinje. Ingen af dem tager højde for veje, broer eller færger.

Afstands-endpointet

GET /api/v1/enrich/distance?from={id}&to={id} tager to adgangsadresse-id'er:

Shell#distance-curl
curl -s "https://api.danadresse.dk/api/v1/enrich/distance?from=0a3f507c-0624-32b8-e044-0003ba298018&to=0a3f507a-ec01-32b8-e044-0003ba298018" \
  -H "X-Api-Key: $DANADRESSE_API_KEY"
JSON#distance-svar
{
  "from": { "id": "0a3f507c-0624-32b8-e044-0003ba298018", "vejnavn": "Strandvejen", "husnr": "100",
            "postnr": "2900", "lat": 55.7326, "lon": 12.5757 },
  "to":   { "id": "0a3f507a-ec01-32b8-e044-0003ba298018", "vejnavn": "Rådhuspladsen", "husnr": "1",
            "postnr": "1550", "lat": 55.6756, "lon": 12.5696 },
  "distance": { "km": 6.3496, "m": 6349.6, "miles": 3.9455 },
  "bearing": { "degrees": 183.45, "compass": "S" }
}
FeltIndhold
distance.km, distance.m, distance.milesAfstanden i luftlinje (storcirkel)
bearing.degreesRetningen fra from mod to ved start, 0 = nord, 90 = øst
bearing.compassSamme som kompasretning i 16 trin, f.eks. S eller NNE
from, toDe to adresser med vejnavn, husnummer, postnummer og koordinater

Fejl, du skal håndtere:

StatusKodeÅrsag
400params_requiredfrom eller to mangler
404not_foundEt id findes ikke som adgangsadresse. error.missing lister hvilke
422missing_coordsEn af adresserne har ingen koordinater
403sandbox_scope / browser_key_scopeTest- eller browsernøgle. Brug en almindelig live-nøgle fra serveren

Afstands-endpointet tager kun adgangsadresse-id'er. Et adresse-id med etage og dør giver 404. Brug adgangsadresseid, som du får fra autocomplete, datavask eller GET /adresser/{id}.

Regn selv: haversine

Har du koordinaterne, er afstanden en formel. Haversine regner storcirkelafstanden på en kugle og er præcis nok til alt inden for Danmark. Eksemplet henter to adresser i ét kald og regner afstanden lokalt:

Python#haversine-python
import math
import os
import requests

def haversine_km(lat1, lon1, lat2, lon2):
    r = 6371.0088
    p1, p2 = math.radians(lat1), math.radians(lat2)
    dp, dl = p2 - p1, math.radians(lon2 - lon1)
    a = math.sin(dp / 2) ** 2 + math.cos(p1) * math.cos(p2) * math.sin(dl / 2) ** 2
    return 2 * r * math.asin(math.sqrt(a))

ids = ["0a3f507c-0624-32b8-e044-0003ba298018", "0a3f507a-ec01-32b8-e044-0003ba298018"]
r = requests.get(
    "https://api.danadresse.dk/adgangsadresser",
    params={"id": "|".join(ids), "struktur": "mini"},
    headers={"X-Api-Key": os.environ["DANADRESSE_API_KEY"]},
    timeout=10,
)
r.raise_for_status()
punkt = {a["id"]: (a["y"], a["x"]) for a in r.json()}   # (lat, lon)
a, b = punkt[ids[0]], punkt[ids[1]]
print(f"{haversine_km(*a, *b):.2f} km")

Regn selv: UTM32 i meter

Med srid=25832 er koordinaterne i meter på et fladt net. Inden for Danmark er afstanden så bare Pythagoras, og du slipper for at omregne grader til meter. WGS84-koordinaterne har otte decimaler, så haversine og UTM32 giver det samme resultat inden for få centimeter. Brug UTM32, når du vil regne i meter direkte:

JavaScript#utm-node
const ids = ["0a3f507c-0624-32b8-e044-0003ba298018", "0a3f507a-ec01-32b8-e044-0003ba298018"];
const url = new URL("https://api.danadresse.dk/adgangsadresser");
url.searchParams.set("id", ids.join("|"));
url.searchParams.set("struktur", "mini");
url.searchParams.set("srid", "25832");

const res = await fetch(url, { headers: { "X-Api-Key": process.env.DANADRESSE_API_KEY } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const punkt = Object.fromEntries((await res.json()).map((a) => [a.id, [a.x, a.y]]));
const [x1, y1] = punkt[ids[0]];
const [x2, y2] = punkt[ids[1]];
const meter = Math.hypot(x2 - x1, y2 - y1);
console.log(`${(meter / 1000).toFixed(3)} km (${Math.round(meter)} m)`);

Hvornår bruger du hvad?

OpgaveBrug
Én afstand vist for en brugerAfstands-endpointet. Ét kald, retning med i købet
Mange afstande, f.eks. alle kunder mod fem lagreHent koordinaterne én gang, gem dem, og regn lokalt
"Alle adresser inden for X km"cirkel på /adgangsadresser (se Adresser i en radius eller et polygon)
Afstand fra en GPS-positionRegn med haversine fra positionen til adressens koordinater (se Find adressen ud fra en GPS-position)

Gemmer du adgangsadresse-id'et og koordinaterne på dine kunder, kan du regne alle afstande uden at kalde API'et igen.

Kanttilfælde

  • Luftlinje er kortere end vejen. Køreafstanden er altid længere, og over vand eller langs en fjord kan forskellen være stor. Brug en ruteplanlægger, hvis du afregner efter kørte kilometer.
  • Samme bygning. To lejligheder i samme opgang har samme adgangsadresse og afstanden 0.
  • Store grunde. Adressepunktet ligger ved indgangen. På en gård eller et industriområde kan bygningerne ligge et godt stykke fra punktet.

Næste skridt

Relaterede guides

Markdown-kilde Fejl i guiden? Skriv til os API-reference (Swagger)

Prøv det med en gratis nøgle

2 000 kald/måned på gratisplanen. Intet kreditkort.

Opret konto →