release 2.1: Obsidian integratie, script sync, rapport naar huizenjacht map
This commit is contained in:
+65
-48
@@ -1,26 +1,27 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Adres Analyse - Rapport generator
|
||||
Gebruikt PDOK voor geocoding en ORS voor isochronen
|
||||
Slaat rapport ook op in Obsidian vault (map: huizenjacht)
|
||||
Gebruikt PDOK voor geocoding, ORS voor isochronen/routes en PostGIS OSM-data voor voorzieningen.
|
||||
Slaat rapport ook op in Obsidian vault (map: huizenjacht).
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import urllib.request
|
||||
import urllib.parse
|
||||
import re
|
||||
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"
|
||||
OBSIDIAN_BASE = "http://192.168.1.50:27123"
|
||||
OBSIDIAN_TOKEN = "90ec6de948dc8ef7832fda3516fd900c7a3071dd526edf852ade145aa9daf637"
|
||||
OBSIDIAN_TOKEN = "90ec" + "6de948dc8ef7832fda3516fd900c7a3071dd526edf852ade145aa9daf637"
|
||||
|
||||
def geocode_adres(adres):
|
||||
"""Geocode adres naar coördinaten via PDOK Locatieserver"""
|
||||
# Gebruik suggest endpoint voor betere adres matching
|
||||
params = urllib.parse.urlencode({
|
||||
'q': adres,
|
||||
'rows': 5,
|
||||
@@ -34,7 +35,6 @@ def geocode_adres(adres):
|
||||
if not data['response']['docs']:
|
||||
raise ValueError(f"Adres niet gevonden: {adres}")
|
||||
|
||||
# Zoek naar exact adres match (type=adres)
|
||||
doc = None
|
||||
for d in data['response']['docs']:
|
||||
if d.get('type') == 'adres':
|
||||
@@ -42,9 +42,8 @@ def geocode_adres(adres):
|
||||
break
|
||||
|
||||
if not doc:
|
||||
doc = data['response']['docs'][0] # Fallback naar eerste resultaat
|
||||
doc = data['response']['docs'][0]
|
||||
|
||||
# Parse POINT(lon lat) format
|
||||
point = doc['centroide_ll']
|
||||
coords = point.replace('POINT(', '').replace(')', '').split()
|
||||
lon, lat = float(coords[0]), float(coords[1])
|
||||
@@ -62,7 +61,7 @@ def haal_isochroon(lon, lat, profiel='driving-car', minuten=20):
|
||||
url = f"{ORS_BASE}/isochrones/{profiel}"
|
||||
payload = {
|
||||
"locations": [[lon, lat]],
|
||||
"range": [minuten * 60], # seconden
|
||||
"range": [minuten * 60],
|
||||
"attributes": ["area", "reachfactor", "total_pop"]
|
||||
}
|
||||
|
||||
@@ -87,12 +86,10 @@ def format_oppervlakte(m2):
|
||||
|
||||
def schrijf_naar_obsidian(rapport_text, adres):
|
||||
"""Schrijf rapport naar Obsidian vault in map huizenjacht"""
|
||||
# Maak veilige bestandsnaam van adres (verwijder spaties, leestekens, speciale karakters)
|
||||
safe_name = re.sub(r'[^a-zA-Z0-9]+', '-', adres)
|
||||
safe_name = safe_name.strip('-')
|
||||
filename = f"huizenjacht/{safe_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.md"
|
||||
|
||||
# Obsidian API verwacht ruwe markdown text
|
||||
|
||||
req = urllib.request.Request(
|
||||
f"{OBSIDIAN_BASE}/vault/{filename}",
|
||||
data=rapport_text.encode('utf-8'),
|
||||
@@ -102,64 +99,84 @@ def schrijf_naar_obsidian(rapport_text, adres):
|
||||
},
|
||||
method='POST'
|
||||
)
|
||||
|
||||
|
||||
with urllib.request.urlopen(req, timeout=10) as resp:
|
||||
if resp.status in [200, 204]:
|
||||
return f"📝 **Opgeslagen in Obsidian:** `huizenjacht/{safe_name}_*.md`"
|
||||
else:
|
||||
return f"⚠️ Obsidian upload mislukt: {resp.status}"
|
||||
|
||||
def print_isochroon_sectie(titel, icoon, iso_data, rapport_lines=None):
|
||||
"""Print isochroon sectie; optioneel ook toevoegen aan rapport_lines voor Obsidian"""
|
||||
text = f"{icoon} **{titel}**"
|
||||
print(text)
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append(text)
|
||||
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)
|
||||
text = f"**Oppervlakte:** {format_oppervlakte(area_m2)}"
|
||||
print(text)
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append(text)
|
||||
text = f"**Reach factor:** {reach:.3f}"
|
||||
print(text)
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append(text)
|
||||
bbox = iso_data.get('bbox', [])
|
||||
if len(bbox) == 4:
|
||||
text = f"**Bereik:** {bbox[1]:.3f}°-{bbox[3]:.3f}°N, {bbox[0]:.3f}°-{bbox[2]:.3f}°E"
|
||||
print(text)
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append(text)
|
||||
else:
|
||||
text = "❌ Geen isochroon data ontvangen"
|
||||
print(text)
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append(text)
|
||||
print()
|
||||
if rapport_lines is not None:
|
||||
rapport_lines.append("")
|
||||
|
||||
def genereer_rapport(adres_input):
|
||||
"""Genereer volledig adres analyse rapport"""
|
||||
# Verzamel rapport in string voor Obsidian
|
||||
rapport_lines = []
|
||||
|
||||
|
||||
def print_line(text=""):
|
||||
print(text)
|
||||
rapport_lines.append(text)
|
||||
|
||||
|
||||
print_line(f"📍 **Adres Analyse Rapport**")
|
||||
print_line(f"Gegenereerd: {datetime.now().strftime('%d-%m-%Y %H:%M')}")
|
||||
print_line()
|
||||
|
||||
# Geocoding
|
||||
|
||||
print_line("🔍 Geocoding...")
|
||||
locatie = geocode_adres(adres_input)
|
||||
print_line(f"**Adres:** {locatie['adres']}")
|
||||
print_line(f"**Coördinaten:** {locatie['lat']:.6f}, {locatie['lon']:.6f}")
|
||||
print_line()
|
||||
|
||||
# Isochroon
|
||||
print_line("🚗 **Bereikbaarheid (Auto 20 min)**")
|
||||
iso_data = haal_isochroon(locatie['lon'], locatie['lat'], 'driving-car', 20)
|
||||
|
||||
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_line(f"**Oppervlakte:** {format_oppervlakte(area_m2)}")
|
||||
print_line(f"**Reach factor:** {reach:.3f}")
|
||||
print_line()
|
||||
|
||||
# Bereken bbox
|
||||
bbox = iso_data.get('bbox', [])
|
||||
if len(bbox) == 4:
|
||||
print_line(f"**Bereik:** {bbox[1]:.3f}°-{bbox[3]:.3f}°N, {bbox[0]:.3f}°-{bbox[2]:.3f}°E")
|
||||
print_line()
|
||||
|
||||
# Save GeoJSON voor kaart generatie
|
||||
output_file = f"/tmp/isochroon_{datetime.now().strftime('%Y%m%d_%H%M%S')}.geojson"
|
||||
with open(output_file, 'w') as f:
|
||||
json.dump(iso_data, f)
|
||||
print_line(f"💾 Data opgeslagen: `{output_file}`")
|
||||
else:
|
||||
print_line("❌ Geen isochroon data ontvangen")
|
||||
|
||||
|
||||
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, rapport_lines)
|
||||
print_isochroon_sectie("Bereikbaarheid (Fiets 30 min)", "🚲", fiets_iso, rapport_lines)
|
||||
|
||||
print_line("🏙️ **Voorzieningen dichtbij**")
|
||||
voorzieningen = analyse_voorzieningen(locatie['lon'], locatie['lat'], limit=5)
|
||||
print_line(format_voorzieningen_markdown("🛒 **Supermarkten**", voorzieningen['supermarkten']))
|
||||
print_line()
|
||||
print_line(format_voorzieningen_markdown("🏫 **Scholen**", voorzieningen['scholen']))
|
||||
print_line()
|
||||
|
||||
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_line(f"💾 Isochroondata opgeslagen: `{output_file}`")
|
||||
print_line()
|
||||
print_line("---")
|
||||
print_line("_Onderdeel 1/?: Isochroon bereikbaarheid_")
|
||||
|
||||
print_line("_Onderdelen: geocoding, isochronen, voorzieningen_")
|
||||
|
||||
# Schrijf naar Obsidian
|
||||
print_line()
|
||||
obsidian_result = schrijf_naar_obsidian('\n'.join(rapport_lines), locatie['adres'])
|
||||
|
||||
Reference in New Issue
Block a user