Map tiles: switch to Esri World Light Gray (OSM 403s file://)

tiles="OpenStreetMap" returned HTTP 403 "referer is required by tile usage
policy" in the target browser — OSM graylists refererless requests and a
karte.html opened via file:// sends no Referer. Esri's Canvas/World_Light_Gray
base + reference layers need neither a key nor a Referer and keep the muted
look. New MAP_TILES / MAP_TILES_LABELS / MAP_TILES_ATTR constants; generate_map
adds them as explicit TileLayers.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 22:37:41 +02:00
parent 5b85596a46
commit 5eb60ec2d3
6 changed files with 62 additions and 30 deletions
+18 -5
View File
@@ -61,9 +61,16 @@ GEOCODE_REGIONS = ["Baden-Württemberg", "Hessen"]
MAP_DEFAULT_CENTER = [49.0, 9.0]
MAP_DEFAULT_ZOOM = 8
#: Kartenkacheln. "OpenStreetMap" braucht keinen API-Schlüssel.
#: (Die früher genutzten "CartoDB positron"-Kacheln verlangen seit 2024 einen Schlüssel.)
MAP_TILES = "OpenStreetMap"
#: Kartenkacheln Esri "World Light Gray" (heller, ruhiger Hintergrund).
#: Braucht keinen API-Schlüssel und keinen Referer (anders als tile.openstreetmap.org,
#: das lokale Dateien mit 403 blockt, und "CartoDB positron", das einen Schlüssel will).
#: Alternativen ohne Schlüssel als Ein-Zeilen-Tausch:
#: Esri Straßenkarte: …/World_Street_Map/MapServer/tile/{z}/{y}/{x}
#: Esri Topo: …/World_Topo_Map/MapServer/tile/{z}/{y}/{x}
_ESRI = "https://server.arcgisonline.com/ArcGIS/rest/services"
MAP_TILES = f"{_ESRI}/Canvas/World_Light_Gray_Base/MapServer/tile/{{z}}/{{y}}/{{x}}"
MAP_TILES_LABELS = f"{_ESRI}/Canvas/World_Light_Gray_Reference/MapServer/tile/{{z}}/{{y}}/{{x}}"
MAP_TILES_ATTR = "Kacheln © Esri"
log = logging.getLogger("arbeitsorte")
@@ -421,9 +428,15 @@ def generate_map(store: DataStore) -> Path:
raise ValueError("Keine Koordinaten vorhanden. Bitte zuerst Einträge speichern.")
m = folium.Map(
location=MAP_DEFAULT_CENTER, zoom_start=MAP_DEFAULT_ZOOM,
tiles=MAP_TILES,
location=MAP_DEFAULT_CENTER, zoom_start=MAP_DEFAULT_ZOOM, tiles=None,
)
folium.TileLayer(
MAP_TILES, attr=MAP_TILES_ATTR, name="Karte", control=False,
).add_to(m)
folium.TileLayer(
MAP_TILES_LABELS, attr=MAP_TILES_ATTR, name="Beschriftung",
control=False, overlay=True,
).add_to(m)
max_count = int(freq["count"].max())
for _, row in freq.iterrows():