133 lines
4.4 KiB
Python
133 lines
4.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Adres Analyse - Rapport generator
|
|
Gebruikt PDOK voor geocoding, ORS voor isochronen/routes en PostGIS OSM-data voor voorzieningen.
|
|
"""
|
|
|
|
import json
|
|
import sys
|
|
import urllib.request
|
|
import urllib.parse
|
|
from datetime import datetime
|
|
|
|
from voorzieningen import analyse_voorzieningen, format_voorzieningen_markdown
|
|
|
|
# Config
|
|
ORS_BASE = "http://192.168.1.71:9080/ors/v2"
|
|
PDOK_BASE = "https://api.pdok.nl/bzk/locatieserver/search/v3_1"
|
|
|
|
def geocode_adres(adres):
|
|
"""Geocode adres naar coördinaten via PDOK Locatieserver"""
|
|
params = urllib.parse.urlencode({
|
|
'q': adres,
|
|
'rows': 5,
|
|
'fl': 'centroide_ll,weergavenaam,postcode,woonplaatsnaam,type,huisnummer'
|
|
})
|
|
|
|
url = f"{PDOK_BASE}/free?{params}"
|
|
with urllib.request.urlopen(url, timeout=10) as resp:
|
|
data = json.loads(resp.read())
|
|
|
|
if not data['response']['docs']:
|
|
raise ValueError(f"Adres niet gevonden: {adres}")
|
|
|
|
doc = None
|
|
for d in data['response']['docs']:
|
|
if d.get('type') == 'adres':
|
|
doc = d
|
|
break
|
|
|
|
if not doc:
|
|
doc = data['response']['docs'][0]
|
|
|
|
point = doc['centroide_ll']
|
|
coords = point.replace('POINT(', '').replace(')', '').split()
|
|
lon, lat = float(coords[0]), float(coords[1])
|
|
|
|
return {
|
|
'adres': doc.get('weergavenaam', adres),
|
|
'postcode': doc.get('postcode', ''),
|
|
'woonplaats': doc.get('woonplaatsnaam', ''),
|
|
'lat': lat,
|
|
'lon': lon
|
|
}
|
|
|
|
def haal_isochroon(lon, lat, profiel='driving-car', minuten=20):
|
|
"""Haal isochroon op van ORS"""
|
|
url = f"{ORS_BASE}/isochrones/{profiel}"
|
|
payload = {
|
|
"locations": [[lon, lat]],
|
|
"range": [minuten * 60],
|
|
"attributes": ["area", "reachfactor", "total_pop"]
|
|
}
|
|
|
|
req = urllib.request.Request(
|
|
url,
|
|
data=json.dumps(payload).encode(),
|
|
headers={'Content-Type': 'application/json'},
|
|
method='POST'
|
|
)
|
|
|
|
with urllib.request.urlopen(req, timeout=30) as resp:
|
|
return json.loads(resp.read())
|
|
|
|
def format_oppervlakte(m2):
|
|
"""Converteer m² naar leesbaar formaat"""
|
|
if m2 >= 1_000_000:
|
|
return f"{m2/1_000_000:.1f} km²"
|
|
elif m2 >= 10_000:
|
|
return f"{m2/10_000:.1f} ha"
|
|
else:
|
|
return f"{m2:.0f} m²"
|
|
|
|
def print_isochroon_sectie(titel, icoon, iso_data):
|
|
print(f"{icoon} **{titel}**")
|
|
if 'features' in iso_data and iso_data['features']:
|
|
props = iso_data['features'][0]['properties']
|
|
area_m2 = props.get('area', 0)
|
|
reach = props.get('reachfactor', 0)
|
|
print(f"**Oppervlakte:** {format_oppervlakte(area_m2)}")
|
|
print(f"**Reach factor:** {reach:.3f}")
|
|
bbox = iso_data.get('bbox', [])
|
|
if len(bbox) == 4:
|
|
print(f"**Bereik:** {bbox[1]:.3f}°-{bbox[3]:.3f}°N, {bbox[0]:.3f}°-{bbox[2]:.3f}°E")
|
|
else:
|
|
print("❌ Geen isochroon data ontvangen")
|
|
print()
|
|
|
|
def genereer_rapport(adres_input):
|
|
"""Genereer volledig adres analyse rapport"""
|
|
print(f"📍 **Adres Analyse Rapport**")
|
|
print(f"Gegenereerd: {datetime.now().strftime('%d-%m-%Y %H:%M')}")
|
|
print()
|
|
|
|
print("🔍 Geocoding...")
|
|
locatie = geocode_adres(adres_input)
|
|
print(f"**Adres:** {locatie['adres']}")
|
|
print(f"**Coördinaten:** {locatie['lat']:.6f}, {locatie['lon']:.6f}")
|
|
print()
|
|
|
|
auto_iso = haal_isochroon(locatie['lon'], locatie['lat'], 'driving-car', 20)
|
|
fiets_iso = haal_isochroon(locatie['lon'], locatie['lat'], 'cycling-regular', 30)
|
|
print_isochroon_sectie("Bereikbaarheid (Auto 20 min)", "🚗", auto_iso)
|
|
print_isochroon_sectie("Bereikbaarheid (Fiets 30 min)", "🚲", fiets_iso)
|
|
|
|
print("🏙️ **Voorzieningen dichtbij**")
|
|
voorzieningen = analyse_voorzieningen(locatie['lon'], locatie['lat'], limit=5)
|
|
print(format_voorzieningen_markdown("🛒 **Supermarkten**", voorzieningen['supermarkten']))
|
|
print()
|
|
print(format_voorzieningen_markdown("🏫 **Scholen**", voorzieningen['scholen']))
|
|
print()
|
|
|
|
output_file = f"/tmp/isochronen_{datetime.now().strftime('%Y%m%d_%H%M%S')}.geojson"
|
|
with open(output_file, 'w') as f:
|
|
json.dump({'auto_20_min': auto_iso, 'fiets_30_min': fiets_iso}, f)
|
|
print(f"💾 Isochroondata opgeslagen: `{output_file}`")
|
|
print()
|
|
print("---")
|
|
print("_Onderdelen: geocoding, isochronen, voorzieningen_")
|
|
|
|
if __name__ == '__main__':
|
|
adres = sys.argv[1] if len(sys.argv) > 1 else "Griendvelden 14 Best"
|
|
genereer_rapport(adres)
|