Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 3edea47e88 |
+69
-5
@@ -21,7 +21,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
HAS_PIL = False
|
HAS_PIL = False
|
||||||
|
|
||||||
from voorzieningen import analyse_voorzieningen, format_voorzieningen_markdown
|
from voorzieningen import analyse_voorzieningen, format_voorzieningen_markdown, format_afstand, format_duur
|
||||||
|
|
||||||
# Config
|
# Config
|
||||||
ORS_BASE = "http://192.168.1.71:9080/ors/v2"
|
ORS_BASE = "http://192.168.1.71:9080/ors/v2"
|
||||||
@@ -105,8 +105,25 @@ def schrijf_naar_mkdocs(content, adres, nummer, ext=".md"):
|
|||||||
|
|
||||||
return filepath, filename
|
return filepath, filename
|
||||||
|
|
||||||
def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso):
|
def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso, voorzieningen=None):
|
||||||
"""Genereer een zelf-contained HTML kaart met Leaflet"""
|
"""Genereer een zelf-contained HTML kaart met Leaflet + POI markers"""
|
||||||
|
# Bouw JSON voor POI markers
|
||||||
|
poi_json = {"supermarkten": [], "scholen": []}
|
||||||
|
if voorzieningen:
|
||||||
|
for s in voorzieningen.get("supermarkten", []):
|
||||||
|
poi_json["supermarkten"].append({
|
||||||
|
"naam": s.naam, "lat": s.lat, "lon": s.lon,
|
||||||
|
"hemelsbreed": round(s.hemelsbreed_m),
|
||||||
|
"fiets": f"{format_afstand(s.fiets_afstand_m)} / {format_duur(s.fiets_duur_s)}" if s.fiets_afstand_m else "n.b.",
|
||||||
|
"auto": f"{format_afstand(s.auto_afstand_m)} / {format_duur(s.auto_duur_s)}" if s.auto_afstand_m else "n.b.",
|
||||||
|
})
|
||||||
|
for s in voorzieningen.get("scholen", []):
|
||||||
|
poi_json["scholen"].append({
|
||||||
|
"naam": s.naam, "lat": s.lat, "lon": s.lon,
|
||||||
|
"hemelsbreed": round(s.hemelsbreed_m),
|
||||||
|
"fiets": f"{format_afstand(s.fiets_afstand_m)} / {format_duur(s.fiets_duur_s)}" if s.fiets_afstand_m else "n.b.",
|
||||||
|
"auto": f"{format_afstand(s.auto_afstand_m)} / {format_duur(s.auto_duur_s)}" if s.auto_afstand_m else "n.b.",
|
||||||
|
})
|
||||||
html = f'''<!DOCTYPE html>
|
html = f'''<!DOCTYPE html>
|
||||||
<html lang="nl">
|
<html lang="nl">
|
||||||
<head>
|
<head>
|
||||||
@@ -127,6 +144,7 @@ def genereer_isochroon_html(adres_naam, lat, lon, auto_iso, fiets_iso):
|
|||||||
<script>
|
<script>
|
||||||
var autoGeojson = {json.dumps(auto_iso, ensure_ascii=False)};
|
var autoGeojson = {json.dumps(auto_iso, ensure_ascii=False)};
|
||||||
var fietsGeojson = {json.dumps(fiets_iso, ensure_ascii=False)};
|
var fietsGeojson = {json.dumps(fiets_iso, ensure_ascii=False)};
|
||||||
|
var voorzieningen = {json.dumps(poi_json, ensure_ascii=False)};
|
||||||
|
|
||||||
var map = L.map('map').setView([{lat}, {lon}], 11);
|
var map = L.map('map').setView([{lat}, {lon}], 11);
|
||||||
|
|
||||||
@@ -150,16 +168,61 @@ var fietsLayer = L.geoJSON(fietsGeojson, {{
|
|||||||
}}
|
}}
|
||||||
}}).addTo(map);
|
}}).addTo(map);
|
||||||
|
|
||||||
|
// Adres marker
|
||||||
L.marker([{lat}, {lon}]).addTo(map)
|
L.marker([{lat}, {lon}]).addTo(map)
|
||||||
.bindPopup('<b>{adres_naam}</b>').openPopup();
|
.bindPopup('<b>{adres_naam}</b>').openPopup();
|
||||||
|
|
||||||
|
// POI markers
|
||||||
|
var supermarktIcon = L.divIcon({{
|
||||||
|
className: 'poi-marker-supermarkt',
|
||||||
|
html: '<div style="background:#2563eb;color:white;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;border:2px solid white;box-shadow:0 1px 4px rgba(0,0,0,0.3)">S</div>',
|
||||||
|
iconSize: [24, 24],
|
||||||
|
iconAnchor: [12, 12],
|
||||||
|
popupAnchor: [0, -14]
|
||||||
|
}});
|
||||||
|
var schoolIcon = L.divIcon({{
|
||||||
|
className: 'poi-marker-school',
|
||||||
|
html: '<div style="background:#ea580c;color:white;width:24px;height:24px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:14px;font-weight:bold;border:2px solid white;box-shadow:0 1px 4px rgba(0,0,0,0.3)">S</div>',
|
||||||
|
iconSize: [24, 24],
|
||||||
|
iconAnchor: [12, 12],
|
||||||
|
popupAnchor: [0, -14]
|
||||||
|
}});
|
||||||
|
|
||||||
|
// Supermarkten
|
||||||
|
if (voorzieningen.supermarkten) {{
|
||||||
|
voorzieningen.supermarkten.forEach(function(p) {{
|
||||||
|
L.marker([p.lat, p.lon], {{icon: supermarktIcon}}).addTo(map)
|
||||||
|
.bindPopup(
|
||||||
|
'<b>🛒 ' + p.naam + '</b><br>' +
|
||||||
|
'Hemelsbreed: ' + p.hemelsbreed + ' m<br>' +
|
||||||
|
'Fiets: ' + p.fiets + '<br>' +
|
||||||
|
'Auto: ' + p.auto
|
||||||
|
);
|
||||||
|
}});
|
||||||
|
}}
|
||||||
|
|
||||||
|
// Scholen
|
||||||
|
if (voorzieningen.scholen) {{
|
||||||
|
voorzieningen.scholen.forEach(function(p) {{
|
||||||
|
L.marker([p.lat, p.lon], {{icon: schoolIcon}}).addTo(map)
|
||||||
|
.bindPopup(
|
||||||
|
'<b>🏫 ' + p.naam + '</b><br>' +
|
||||||
|
'Hemelsbreed: ' + p.hemelsbreed + ' m<br>' +
|
||||||
|
'Fiets: ' + p.fiets + '<br>' +
|
||||||
|
'Auto: ' + p.auto
|
||||||
|
);
|
||||||
|
}});
|
||||||
|
}}
|
||||||
|
|
||||||
var legend = L.control({{position: 'bottomright'}});
|
var legend = L.control({{position: 'bottomright'}});
|
||||||
legend.onAdd = function(map) {{
|
legend.onAdd = function(map) {{
|
||||||
var div = L.DomUtil.create('div', 'legend');
|
var div = L.DomUtil.create('div', 'legend');
|
||||||
div.innerHTML += '<h4 style="margin:0 0 5px 0">Isochronen</h4>';
|
div.innerHTML += '<h4 style="margin:0 0 5px 0">Isochronen</h4>';
|
||||||
div.innerHTML += '<i style="background:#3b82f6"></i> Auto 20 min<br>';
|
div.innerHTML += '<i style="background:#3b82f6"></i> Auto 20 min<br>';
|
||||||
div.innerHTML += '<i style="background:#22c55e"></i> Fiets 30 min<br>';
|
div.innerHTML += '<i style="background:#22c55e"></i> Fiets 30 min<br>';
|
||||||
div.innerHTML += '<i style="background:#ef4444"></i> Adres';
|
div.innerHTML += '<i style="background:#ef4444"></i> Adres<br>';
|
||||||
|
div.innerHTML += '<i style="background:#2563eb;border-radius:50%;width:12px;height:12px;border:1px solid #999"></i> Supermarkt<br>';
|
||||||
|
div.innerHTML += '<i style="background:#ea580c;border-radius:50%;width:12px;height:12px;border:1px solid #999"></i> School';
|
||||||
return div;
|
return div;
|
||||||
}};
|
}};
|
||||||
legend.addTo(map);
|
legend.addTo(map);
|
||||||
@@ -224,7 +287,8 @@ def genereer_rapport(adres_input):
|
|||||||
|
|
||||||
# Genereer interactieve HTML kaart en sla op in MkDocs
|
# Genereer interactieve HTML kaart en sla op in MkDocs
|
||||||
html_content = genereer_isochroon_html(
|
html_content = genereer_isochroon_html(
|
||||||
locatie['adres'], locatie['lat'], locatie['lon'], auto_iso, fiets_iso
|
locatie['adres'], locatie['lat'], locatie['lon'], auto_iso, fiets_iso,
|
||||||
|
voorzieningen=voorzieningen
|
||||||
)
|
)
|
||||||
html_filepath, html_filename = schrijf_naar_mkdocs(html_content, locatie['adres'], nummer, ext=".html")
|
html_filepath, html_filename = schrijf_naar_mkdocs(html_content, locatie['adres'], nummer, ext=".html")
|
||||||
|
|
||||||
|
|||||||
+7
-7
@@ -136,13 +136,13 @@ def format_voorzieningen_markdown(titel, pois):
|
|||||||
if not pois:
|
if not pois:
|
||||||
lines.append("Geen voorzieningen gevonden in zoekradius.")
|
lines.append("Geen voorzieningen gevonden in zoekradius.")
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
for i, p in enumerate(pois, 1):
|
for p in pois:
|
||||||
lines.extend([
|
lines.append(
|
||||||
f"{i}. **{p.naam}**",
|
f"• **{p.naam}** — "
|
||||||
f" Hemelsbreed: {format_afstand(p.hemelsbreed_m)}",
|
f"Hemelsbreed: {format_afstand(p.hemelsbreed_m)} | "
|
||||||
f" Fiets: {format_afstand(p.fiets_afstand_m)} / {format_duur(p.fiets_duur_s)}",
|
f"Fiets: {format_afstand(p.fiets_afstand_m)} / {format_duur(p.fiets_duur_s)} | "
|
||||||
f" Auto: {format_afstand(p.auto_afstand_m)} / {format_duur(p.auto_duur_s)}",
|
f"Auto: {format_afstand(p.auto_afstand_m)} / {format_duur(p.auto_duur_s)}"
|
||||||
])
|
)
|
||||||
return "\n".join(lines)
|
return "\n".join(lines)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user