Platform bundle: marketing publish, IT ops, packaging, agents mesh.
Volledige Foodlinkk Command Center uitbreiding met social automatisering, reclamefolder filters, Proxmox monitoring en documentatie.
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"""PDOK Locatieserver — postcode geocoding."""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import re
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from typing import Any, Optional
|
||||
|
||||
PDOK_URL = "https://api.pdok.nl/bzk/locatieserver/search/v3_1/free"
|
||||
POSTCODE_RE = re.compile(r"^(\d{4})\s?([A-Za-z]{2})$")
|
||||
|
||||
|
||||
def normalize_postcode(raw: str) -> str:
|
||||
cleaned = (raw or "").strip().upper().replace(" ", "")
|
||||
m = POSTCODE_RE.match(cleaned)
|
||||
if m:
|
||||
return f"{m.group(1)}{m.group(2)}"
|
||||
return cleaned[:6] if cleaned else ""
|
||||
|
||||
|
||||
def _parse_point(value: Optional[str]) -> tuple[Optional[float], Optional[float]]:
|
||||
if not value or "POINT" not in value:
|
||||
return None, None
|
||||
nums = re.findall(r"[-+]?\d*\.?\d+", value)
|
||||
if len(nums) >= 2:
|
||||
return float(nums[1]), float(nums[0]) # lat, lon
|
||||
return None, None
|
||||
|
||||
|
||||
def lookup_postcode(postcode: str) -> Optional[dict[str, Any]]:
|
||||
pc = normalize_postcode(postcode)
|
||||
if len(pc) < 6:
|
||||
return None
|
||||
q = urllib.parse.urlencode({"q": pc, "rows": 1, "fq": "type:postcode"})
|
||||
with urllib.request.urlopen(f"{PDOK_URL}?{q}", timeout=20) as resp:
|
||||
data = json.loads(resp.read().decode())
|
||||
docs = data.get("response", {}).get("docs", [])
|
||||
if not docs:
|
||||
return None
|
||||
doc = docs[0]
|
||||
lat, lon = _parse_point(doc.get("centroide_ll"))
|
||||
gemeente_code = (doc.get("gemeentecode") or "").strip()
|
||||
if gemeente_code and not gemeente_code.startswith("GM"):
|
||||
gemeente_code = f"GM{gemeente_code}"
|
||||
return {
|
||||
"postcode": pc,
|
||||
"city": (doc.get("woonplaatsnaam") or "").strip(),
|
||||
"province": (doc.get("provincienaam") or "").strip(),
|
||||
"province_code": (doc.get("provinciecode") or "").strip(),
|
||||
"municipality": (doc.get("gemeentenaam") or "").strip(),
|
||||
"municipality_code": gemeente_code,
|
||||
"street": (doc.get("straatnaam") or "").strip(),
|
||||
"latitude": lat,
|
||||
"longitude": lon,
|
||||
}
|
||||
Reference in New Issue
Block a user