1 Commits

Author SHA1 Message Date
Hermes Agent d9da2964dd v2.4 - Nummering + directe kaartlink (geen iframe) 2026-06-25 09:03:14 +02:00
2 changed files with 150 additions and 289 deletions
+70 -131
View File
@@ -8,19 +8,13 @@ Slaat rapport en HTML-kaarten op in /root/mkdocs/docs/docs/Huizenjacht/
import json
import sys
import os
import re
import urllib.request
import urllib.parse
import re
import base64
from datetime import datetime
import base64
from io import BytesIO
try:
from playwright.sync_api import sync_playwright
HAS_PLAYWRIGHT = True
except ImportError:
HAS_PLAYWRIGHT = False
try:
from PIL import Image
HAS_PIL = True
@@ -98,12 +92,12 @@ def format_oppervlakte(m2):
else:
return f"{m2:.0f} m²"
def schrijf_naar_mkdocs(content, adres, ext=".md"):
"""Schrijf content naar MkDocs docs map als bestand"""
def schrijf_naar_mkdocs(content, adres, nummer, ext=".md"):
"""Schrijf content naar MkDocs docs map als bestand met oplopend nummer"""
os.makedirs(MKDOCS_DIR, exist_ok=True)
safe_name = re.sub(r'[^a-zA-Z0-9]+', '-', adres)
safe_name = safe_name.strip('-')
filename = f"{safe_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}{ext}"
filename = f"{nummer}-{safe_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}{ext}"
filepath = os.path.join(MKDOCS_DIR, filename)
with open(filepath, 'w', encoding='utf-8') as f:
@@ -119,10 +113,8 @@ def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso):
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Isochroon - {adres_naam}</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
body {{ margin: 0; padding: 0; font-family: system-ui, -apple-system, sans-serif; }}
#map {{ height: 100vh; width: 100vw; }}
@@ -146,7 +138,7 @@ var autoLayer = L.geoJSON(autoGeojson, {{
style: {{ color: '#2563eb', weight: 2, fillColor: '#3b82f6', fillOpacity: 0.2 }},
onEachFeature: function(feature, layer) {{
var props = feature.properties;
layer.bindPopup('<b>Auto 20 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km\\u00b2<br>Reach factor: ' + props.reachfactor.toFixed(3));
layer.bindPopup('<b>Auto 20 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km²<br>Reach factor: ' + props.reachfactor.toFixed(3));
}}
}}).addTo(map);
@@ -154,7 +146,7 @@ var fietsLayer = L.geoJSON(fietsGeojson, {{
style: {{ color: '#16a34a', weight: 2, fillColor: '#22c55e', fillOpacity: 0.2 }},
onEachFeature: function(feature, layer) {{
var props = feature.properties;
layer.bindPopup('<b>Fiets 30 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km\\u00b2<br>Reach factor: ' + props.reachfactor.toFixed(3));
layer.bindPopup('<b>Fiets 30 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km²<br>Reach factor: ' + props.reachfactor.toFixed(3));
}}
}}).addTo(map);
@@ -178,140 +170,87 @@ map.fitBounds(autoLayer.getBounds().extend(fietsLayer.getBounds()));
</html>'''
return html
def maak_isochroon_screenshot(html_content, width=1280, height=900, resize_width=800, quality=70):
"""Genereer een JPEG screenshot van de HTML kaart, retourneer base64 string"""
if not HAS_PLAYWRIGHT:
return None, "Playwright niet geïnstalleerd"
if not HAS_PIL:
return None, "Pillow niet geïnstalleerd"
import tempfile
# Write HTML to temp file
with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f:
f.write(html_content)
html_path = f.name
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={'width': width, 'height': height})
page.goto(f'file://{html_path}')
page.wait_for_timeout(2500) # Wait for tiles
png_bytes = page.screenshot(full_page=False)
browser.close()
except Exception as e:
os.unlink(html_path)
return None, f"Screenshot fout: {e}"
finally:
os.unlink(html_path)
# Compress to JPEG
img = Image.open(BytesIO(png_bytes))
ratio = resize_width / img.width
resize_height = int(img.height * ratio)
img = img.resize((resize_width, resize_height), Image.Resampling.LANCZOS)
buf = BytesIO()
img.save(buf, format='JPEG', quality=quality, optimize=True)
jpeg_bytes = buf.getvalue()
b64 = base64.b64encode(jpeg_bytes).decode('ascii')
return b64, None
def print_isochroon_sectie(titel, icoon, iso_data, rapport_lines=None):
"""Print isochroon sectie; optioneel ook toevoegen aan rapport_lines"""
text = f"{icoon} **{titel}**"
print(text)
if rapport_lines is not None:
rapport_lines.append(text)
def print_isochroon_sectie(titel, icoon, iso_data):
"""Genereer isochroon sectie als tekst"""
lines = []
lines.append(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)
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)
lines.append(f"**Oppervlakte:** {format_oppervlakte(area_m2)}")
lines.append(f"**Reach factor:** {reach:.3f}")
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)
lines.append(f"**Bereik:** {bbox[1]:.3f}°-{bbox[3]:.3f}°N, {bbox[0]:.3f}°-{bbox[2]:.3f}°E")
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("")
lines.append("❌ Geen isochroon data ontvangen")
lines.append("")
return "\n".join(lines)
def genereer_rapport(adres_input):
"""Genereer volledig adres analyse rapport"""
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()
print_line("🔍 Geocoding...")
lines = []
# Tel bestaande genummerde rapporten voor oplopend nummer
# Alleen bestanden die beginnen met cijfer-dash (bv. "1-Griendvelden...")
alle_files = os.listdir(MKDOCS_DIR) if os.path.exists(MKDOCS_DIR) else []
genummerde_files = [f for f in alle_files if f.endswith('.md') and re.match(r'^\d+-', f)]
nummer = len(genummerde_files) + 1
lines.append(f"# {nummer}. {adres_input}")
lines.append(f"*Gegenereerd: {datetime.now().strftime('%d-%m-%Y %H:%M')}*")
lines.append("")
lines.append("## 🔍 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()
lines.append(f"**Adres:** {locatie['adres']}")
lines.append(f"**Coördinaten:** {locatie['lat']:.6f}, {locatie['lon']:.6f}")
lines.append("")
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**")
lines.append("## 🚗 Bereikbaarheid")
lines.append(print_isochroon_sectie("Auto (20 min)", "🚗", auto_iso))
lines.append(print_isochroon_sectie("Fiets (30 min)", "🚲", fiets_iso))
lines.append("## 🏙️ 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()
# Genereer interactieve HTML kaart en sla op in MkDocs.map
lines.append(format_voorzieningen_markdown("🛒 **Supermarkten**", voorzieningen['supermarkten']))
lines.append("")
lines.append(format_voorzieningen_markdown("🏫 **Scholen**", voorzieningen['scholen']))
lines.append("")
# Genereer interactieve HTML kaart en sla op in MkDocs
html_content = genereer_isochroon_html(
locatie['adres'], locatie['lat'], locatie['lon'], auto_iso, fiets_iso
)
html_filepath, html_filename = schrijf_naar_mkdocs(html_content, locatie['adres'], ext=".html")
print_line(f"🗺️ **Interactieve kaart opgeslagen:** `{html_filepath}`")
# Genereer screenshot en embed in markdown
b64_img, err = maak_isochroon_screenshot(html_content)
if b64_img:
print_line("")
print_line("**🗺️ Isochroon kaart (auto + fiets):**")
img_md = f"![Isochroon kaart](data:image/jpeg;base64,{b64_img})"
print_line(img_md)
else:
print_line(f"⚠️ Kon geen screenshot maken: {err}")
# Sla ook ruwe geojson op
html_filepath, html_filename = schrijf_naar_mkdocs(html_content, locatie['adres'], nummer, ext=".html")
# Voeg link toe aan markdown rapport (betrouwbaar via directe link)
lines.append("## 🗺️ Interactieve kaart")
lines.append(f"")
lines.append(f"**[📍 Bekijk interactieve isochroon kaart]({html_filename})**{{:target=\"_blank\"}}")
lines.append("")
lines.append("*Klik op de link om de kaart in een nieuw tabblad te openen. Hier kun je zoomen, pannen en de isochronen bekijken.*")
lines.append("")
# Ruwe geojson
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"💾 Ruwe isochroondata: `{output_file}`")
print_line()
print_line("---")
print_line("_Onderdelen: geocoding, isochronen, voorzieningen_")
# Schrijf rapport naar MkDocs map
print_line()
md_filepath, md_filename = schrijf_naar_mkdocs('\n'.join(rapport_lines), locatie['adres'], ext=".md")
print_line(f"📝 **Rapport opgeslagen:** `{md_filepath}`")
lines.append("---")
lines.append("*Onderdelen: geocoding, isochronen, voorzieningen, interactieve kaart*")
rapport_text = "\n".join(lines)
# Print naar stdout
print(rapport_text)
# Sla op in MkDocs
md_filepath, md_filename = schrijf_naar_mkdocs(rapport_text, adres_input, nummer, ext=".md")
print(f"\n📝 Rapport opgeslagen: {md_filepath}")
if __name__ == '__main__':
adres = sys.argv[1] if len(sys.argv) > 1 else "Griendvelden 14 Best"
+80 -158
View File
@@ -2,24 +2,19 @@
"""
Adres Analyse - Rapport generator
Gebruikt PDOK voor geocoding, ORS voor isochronen/routes en PostGIS OSM-data voor voorzieningen.
Slaat rapport ook op in Obsidian vault (map: huizenjacht).
Slaat rapport en HTML-kaarten op in /root/mkdocs/docs/docs/Huizenjacht/
"""
import json
import sys
import os
import re
import urllib.request
import urllib.parse
import re
import base64
from datetime import datetime
import base64
from io import BytesIO
try:
from playwright.sync_api import sync_playwright
HAS_PLAYWRIGHT = True
except ImportError:
HAS_PLAYWRIGHT = False
try:
from PIL import Image
HAS_PIL = True
@@ -31,8 +26,7 @@ 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 = "90ec" + "6de948dc8ef7832fda3516fd900c7a3071dd526edf852ade145aa9daf637"
MKDOCS_DIR = "/root/mkdocs/docs/docs/Huizenjacht"
def geocode_adres(adres):
"""Geocode adres naar coördinaten via PDOK Locatieserver"""
@@ -98,28 +92,18 @@ def format_oppervlakte(m2):
else:
return f"{m2:.0f} m²"
def schrijf_naar_obsidian(rapport_text, adres, subpath="huizenjacht", ext=".md"):
"""Schrijf rapport naar Obsidian vault"""
def schrijf_naar_mkdocs(content, adres, nummer, ext=".md"):
"""Schrijf content naar MkDocs docs map als bestand met oplopend nummer"""
os.makedirs(MKDOCS_DIR, exist_ok=True)
safe_name = re.sub(r'[^a-zA-Z0-9]+', '-', adres)
safe_name = safe_name.strip('-')
filename = f"{subpath}/{safe_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}{ext}"
content_type = "text/html" if ext == ".html" else "text/markdown"
req = urllib.request.Request(
f"{OBSIDIAN_BASE}/vault/{filename}",
data=rapport_text.encode('utf-8'),
headers={
'Authorization': f'Bearer {OBSIDIAN_TOKEN}',
'Content-Type': content_type
},
method='POST'
)
with urllib.request.urlopen(req, timeout=10) as resp:
if resp.status in [200, 204]:
return filename
else:
return None
filename = f"{nummer}-{safe_name}_{datetime.now().strftime('%Y%m%d_%H%M%S')}{ext}"
filepath = os.path.join(MKDOCS_DIR, filename)
with open(filepath, 'w', encoding='utf-8') as f:
f.write(content)
return filepath, filename
def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso):
"""Genereer een zelf-contained HTML kaart met Leaflet"""
@@ -129,10 +113,8 @@ def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso):
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Isochroon - {adres_naam}</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css"
integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin="" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"
integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" />
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js"></script>
<style>
body {{ margin: 0; padding: 0; font-family: system-ui, -apple-system, sans-serif; }}
#map {{ height: 100vh; width: 100vw; }}
@@ -156,7 +138,7 @@ var autoLayer = L.geoJSON(autoGeojson, {{
style: {{ color: '#2563eb', weight: 2, fillColor: '#3b82f6', fillOpacity: 0.2 }},
onEachFeature: function(feature, layer) {{
var props = feature.properties;
layer.bindPopup('<b>Auto 20 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km\u00b2<br>Reach factor: ' + props.reachfactor.toFixed(3));
layer.bindPopup('<b>Auto 20 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km²<br>Reach factor: ' + props.reachfactor.toFixed(3));
}}
}}).addTo(map);
@@ -164,7 +146,7 @@ var fietsLayer = L.geoJSON(fietsGeojson, {{
style: {{ color: '#16a34a', weight: 2, fillColor: '#22c55e', fillOpacity: 0.2 }},
onEachFeature: function(feature, layer) {{
var props = feature.properties;
layer.bindPopup('<b>Fiets 30 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km\u00b2<br>Reach factor: ' + props.reachfactor.toFixed(3));
layer.bindPopup('<b>Fiets 30 min</b><br>Oppervlakte: ' + (props.area/1000000).toFixed(1) + ' km²<br>Reach factor: ' + props.reachfactor.toFixed(3));
}}
}}).addTo(map);
@@ -188,147 +170,87 @@ map.fitBounds(autoLayer.getBounds().extend(fietsLayer.getBounds()));
</html>'''
return html
def maak_isochroon_screenshot(html_content, width=1280, height=900, resize_width=800, quality=70):
"""Genereer een JPEG screenshot van de HTML kaart, retourneer base64 string"""
if not HAS_PLAYWRIGHT:
return None, "Playwright niet geïnstalleerd"
if not HAS_PIL:
return None, "Pillow niet geïnstalleerd"
import tempfile
import os
# Write HTML to temp file
with tempfile.NamedTemporaryFile(mode='w', suffix='.html', delete=False, encoding='utf-8') as f:
f.write(html_content)
html_path = f.name
try:
with sync_playwright() as p:
browser = p.chromium.launch(headless=True)
page = browser.new_page(viewport={'width': width, 'height': height})
page.goto(f'file://{html_path}')
page.wait_for_timeout(2500) # Wait for tiles
png_bytes = page.screenshot(full_page=False)
browser.close()
except Exception as e:
os.unlink(html_path)
return None, f"Screenshot fout: {e}"
finally:
os.unlink(html_path)
# Compress to JPEG
img = Image.open(BytesIO(png_bytes))
ratio = resize_width / img.width
resize_height = int(img.height * ratio)
img = img.resize((resize_width, resize_height), Image.Resampling.LANCZOS)
buf = BytesIO()
img.save(buf, format='JPEG', quality=quality, optimize=True)
jpeg_bytes = buf.getvalue()
b64 = base64.b64encode(jpeg_bytes).decode('ascii')
return b64, None
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)
def print_isochroon_sectie(titel, icoon, iso_data):
"""Genereer isochroon sectie als tekst"""
lines = []
lines.append(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)
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)
lines.append(f"**Oppervlakte:** {format_oppervlakte(area_m2)}")
lines.append(f"**Reach factor:** {reach:.3f}")
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)
lines.append(f"**Bereik:** {bbox[1]:.3f}°-{bbox[3]:.3f}°N, {bbox[0]:.3f}°-{bbox[2]:.3f}°E")
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("")
lines.append("❌ Geen isochroon data ontvangen")
lines.append("")
return "\n".join(lines)
def genereer_rapport(adres_input):
"""Genereer volledig adres analyse rapport"""
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()
print_line("🔍 Geocoding...")
lines = []
# Tel bestaande genummerde rapporten voor oplopend nummer
# Alleen bestanden die beginnen met cijfer-dash (bv. "1-Griendvelden...")
alle_files = os.listdir(MKDOCS_DIR) if os.path.exists(MKDOCS_DIR) else []
genummerde_files = [f for f in alle_files if f.endswith('.md') and re.match(r'^\d+-', f)]
nummer = len(genummerde_files) + 1
lines.append(f"# {nummer}. {adres_input}")
lines.append(f"*Gegenereerd: {datetime.now().strftime('%d-%m-%Y %H:%M')}*")
lines.append("")
lines.append("## 🔍 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()
lines.append(f"**Adres:** {locatie['adres']}")
lines.append(f"**Coördinaten:** {locatie['lat']:.6f}, {locatie['lon']:.6f}")
lines.append("")
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**")
lines.append("## 🚗 Bereikbaarheid")
lines.append(print_isochroon_sectie("Auto (20 min)", "🚗", auto_iso))
lines.append(print_isochroon_sectie("Fiets (30 min)", "🚲", fiets_iso))
lines.append("## 🏙️ 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()
# Genereer interactieve HTML kaart en upload naar Obsidian
lines.append(format_voorzieningen_markdown("🛒 **Supermarkten**", voorzieningen['supermarkten']))
lines.append("")
lines.append(format_voorzieningen_markdown("🏫 **Scholen**", voorzieningen['scholen']))
lines.append("")
# Genereer interactieve HTML kaart en sla op in MkDocs
html_content = genereer_isochroon_html(
locatie['adres'], locatie['lat'], locatie['lon'], auto_iso, fiets_iso
)
html_path = schrijf_naar_obsidian(html_content, locatie['adres'], subpath="huizenjacht", ext=".html")
if html_path:
print_line(f"🗺️ **[Bekijk interactieve isochroon kaart]({html_path})**")
else:
print_line("⚠️ Kon interactieve kaart niet opslaan in Obsidian")
# Genereer screenshot en embed in markdown
b64_img, err = maak_isochroon_screenshot(html_content)
if b64_img:
print_line("")
print_line("**🗺️ Isochroon kaart (auto + fiets):**")
img_md = f"![Isochroon kaart](data:image/jpeg;base64,{b64_img})"
print_line(img_md)
else:
print_line(f"⚠️ Kon geen screenshot maken: {err}")
# Sla ook ruwe geojson op (lokaal, niet in Obsidian)
html_filepath, html_filename = schrijf_naar_mkdocs(html_content, locatie['adres'], nummer, ext=".html")
# Voeg link toe aan markdown rapport (betrouwbaar via directe link)
lines.append("## 🗺️ Interactieve kaart")
lines.append(f"")
lines.append(f"**[📍 Bekijk interactieve isochroon kaart]({html_filename})**{{:target=\"_blank\"}}")
lines.append("")
lines.append("*Klik op de link om de kaart in een nieuw tabblad te openen. Hier kun je zoomen, pannen en de isochronen bekijken.*")
lines.append("")
# Ruwe geojson
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"💾 Ruwe isochroondata: `{output_file}`")
print_line()
print_line("---")
print_line("_Onderdelen: geocoding, isochronen, voorzieningen_")
# Schrijf rapport naar Obsidian
print_line()
md_path = schrijf_naar_obsidian('\n'.join(rapport_lines), locatie['adres'])
if md_path:
print_line(f"📝 **Opgeslagen in Obsidian:** `{md_path}`")
else:
print_line("⚠️ Obsidian upload mislukt")
lines.append("---")
lines.append("*Onderdelen: geocoding, isochronen, voorzieningen, interactieve kaart*")
rapport_text = "\n".join(lines)
# Print naar stdout
print(rapport_text)
# Sla op in MkDocs
md_filepath, md_filename = schrijf_naar_mkdocs(rapport_text, adres_input, nummer, ext=".md")
print(f"\n📝 Rapport opgeslagen: {md_filepath}")
if __name__ == '__main__':
adres = sys.argv[1] if len(sys.argv) > 1 else "Griendvelden 14 Best"