GeoJSON naar een kaart: geldige getallen bewijzen de coördinaatvolgorde niet
De kern
Valideer het gekozen formaat en geef coördinaten namen. Een bereikcontrole kan niet bewijzen welke locatie de bron bedoelde.
Een getallenpaar is nog geen plaatsbewijs
Een kaartadapter kan zonder foutmelding een punt op de verkeerde plek tekenen. Vooral een paar waarvan beide waarden binnen het breedtegraadbereik liggen, biedt geen handige numerieke alarmbel. Het nuttige doel is daarom niet “automatisch de goede plek raden”, maar de interpretatie zichtbaar maken en de grens van de controle demonstreren.
RFC 7946 zet longitude vóór latitude en staat een extra hoogtecomponent toe.[4] Onze voorbeeldadapter accepteert bewust alleen tweedimensionale Point-objecten. Het weigeren van hoogte is dus onze beperkte adapterscope, niet een bewering dat een geldig GeoJSON-punt nooit hoogte kan bevatten.
Leg de grens tussen bron en kaart vast
- Bronvorm: een GeoJSON Point met coordinates als lijst.
- Adapteruitvoer: aparte sleutels longitude en latitude.
- Kaartinvoer: controleer daarna de gedocumenteerde conventie van de gekozen kaartbibliotheek; die wordt hier niet verondersteld.
- Onbekende herkomst of een ander coördinatenstelsel: houd de overdracht vast in plaats van de waarden te wisselen tot het beeld aannemelijk lijkt.
Bewijs ook wat de validator niet weet
De onderstaande verzonnen coördinaten [4.3, 52.1] worden gelabeld, niet geografisch opgezocht. De omgekeerde invoer [52.1, 4.3] slaagt eveneens. Dat tegenvoorbeeld is de hoofdtest: een nette uitvoermapping maakt foutieve bronintentie niet vanzelf herkenbaar. Gebruik nooit een plausibel kaartbeeld als vervanging voor de bronafspraak.
Gebruik Kopieer code om alle code exact te kopiëren. Handmatig selecteren kan de laatste regelovergang weglaten.
import json
import math
from operator import le
def point_to_named(point):
if type(point) is not dict or point.get("type") != "Point":
raise ValueError("expected Point")
c = point.get("coordinates")
if type(c) is not list or len(c) != 2:
raise ValueError("this adapter accepts two dimensions only")
if any(type(x) not in (int, float) or not math.isfinite(x) for x in c):
raise ValueError("expected finite numbers, not booleans")
lon, lat = c
if not (le(abs(lon), 180) and le(abs(lat), 90)):
raise ValueError("outside this adapter's range")
return {"longitude": lon, "latitude": lat}
# Invented coordinates; not a location lookup or surveyed point.
normal = point_to_named({"type": "Point", "coordinates": [4.3, 52.1]})
swapped = point_to_named({"type": "Point", "coordinates": [52.1, 4.3]})
assert normal["longitude"] == 4.3 and normal["latitude"] == 52.1
assert swapped["longitude"] == 52.1 # Still in range: cannot detect intent.
bad = [[True, 52], [4, float("nan")], [4, 91], [4, 52, 3], [181, 52]]
for c in bad:
try:
point_to_named({"type": "Point", "coordinates": c})
except ValueError:
pass
else:
raise AssertionError("invalid coordinates accepted")
print(json.dumps({"named": normal, "swapped_also_passes": swapped, "rejected": len(bad)}, sort_keys=True))
{"named": {"latitude": 52.1, "longitude": 4.3}, "rejected": 5, "swapped_also_passes": {"latitude": 4.3, "longitude": 52.1}}
De vijf negatieve fixtures weigeren een boolean, NaN, een breedtegraad buiten het gekozen bereik, een derde dimensie en een lengtegraad buiten het gekozen bereik. De typecheck sluit True expliciet uit, ook al behandelt Python booleans in sommige numerieke contexten als getallen. De uitvoer is een echt lokaal resultaat over verzonnen invoer, niet een geopositie of providerobservatie.
Draag onzekerheid mee naar de gebruiker
Een geschikte overdrachtskaart bewaart formaat, bronveld, volgorde, eenheid, bekende conversie en de partij die de betekenis bevestigt. Als een upstreamsysteem al een benoemde latitude en longitude levert, zet die via een expliciete adapter om; hergebruik niet blind een arrayfunctie. Een omwisseling om een marker dichter bij de verwachte stad te krijgen is geen validatiemethode.
Deze proef toetst geen FeatureCollection, geometriecollectie, bbox, antimeridiaan, projectieconversie, nauwkeurigheid of kaartweergave. Hij valideert geen adres en selecteert geen administratieve kandidaat. Een echte integratie heeft representatieve, toegestane brondata en tests tegen de gekozen kaart nodig. Alleen de gedocumenteerde formaatlezing en de lokale fixtures zijn uitgevoerd; rechten en onafhankelijke review blijven open.
Bronnen & onderbouwing
- Oorspronkelijke brontitel: RFC 7946 — The GeoJSON Format
Geraadpleegd: 2026-10-18T22:58:30.816185+00:00