Switch map tiles from CartoDB positron to OpenStreetMap (no API key)
CartoDB's positron basemap now renders an "API KEY REQUIRED" watermark. Use tiles="OpenStreetMap" via a new MAP_TILES constant instead. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -58,6 +58,10 @@ GEOCODE_REGIONS = ["Baden-Württemberg", "Hessen"]
|
|||||||
MAP_DEFAULT_CENTER = [49.0, 9.0]
|
MAP_DEFAULT_CENTER = [49.0, 9.0]
|
||||||
MAP_DEFAULT_ZOOM = 8
|
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"
|
||||||
|
|
||||||
log = logging.getLogger("arbeitsorte")
|
log = logging.getLogger("arbeitsorte")
|
||||||
|
|
||||||
|
|
||||||
@@ -415,7 +419,7 @@ def generate_map(store: DataStore) -> Path:
|
|||||||
|
|
||||||
m = folium.Map(
|
m = folium.Map(
|
||||||
location=MAP_DEFAULT_CENTER, zoom_start=MAP_DEFAULT_ZOOM,
|
location=MAP_DEFAULT_CENTER, zoom_start=MAP_DEFAULT_ZOOM,
|
||||||
tiles="CartoDB positron",
|
tiles=MAP_TILES,
|
||||||
)
|
)
|
||||||
max_count = int(freq["count"].max())
|
max_count = int(freq["count"].max())
|
||||||
|
|
||||||
|
|||||||
@@ -84,6 +84,6 @@ This is the file to ask for when diagnosing a problem on the user's laptop.
|
|||||||
|------------|-----------|-------------------|
|
|------------|-----------|-------------------|
|
||||||
| Nominatim (OSM) | geocoding new/edited entries | entries save with blank coords, shown as `⚠ nicht gefunden` |
|
| Nominatim (OSM) | geocoding new/edited entries | entries save with blank coords, shown as `⚠ nicht gefunden` |
|
||||||
| CDN (jsdelivr, jquery, cloudflare) | rendering `karte.html` | map page loads blank / unstyled |
|
| CDN (jsdelivr, jquery, cloudflare) | rendering `karte.html` | map page loads blank / unstyled |
|
||||||
| CartoDB tiles | map background | grey tiles |
|
| OpenStreetMap tiles (`tile.openstreetmap.org`) | map background | blank/grey tiles |
|
||||||
|
|
||||||
Existing entries that already have coordinates do **not** need the network.
|
Existing entries that already have coordinates do **not** need the network.
|
||||||
|
|||||||
@@ -2,6 +2,14 @@
|
|||||||
|
|
||||||
Notable changes to the app. Newest first.
|
Notable changes to the app. Newest first.
|
||||||
|
|
||||||
|
## 2026-09-07 — map tiles switched to OpenStreetMap
|
||||||
|
|
||||||
|
`folium.Map(tiles="CartoDB positron")` began showing an "API KEY REQUIRED"
|
||||||
|
watermark (Carto moved its basemaps behind a key). Switched to
|
||||||
|
`tiles="OpenStreetMap"` via a new `MAP_TILES` constant — no key required. OSM
|
||||||
|
standard tiles are more colourful than positron was; `MAP_TILES` makes swapping
|
||||||
|
the provider a one-line change.
|
||||||
|
|
||||||
## 2026-09-07 — UI/UX pass
|
## 2026-09-07 — UI/UX pass
|
||||||
|
|
||||||
A round of usability improvements aimed at the non-technical user
|
A round of usability improvements aimed at the non-technical user
|
||||||
|
|||||||
@@ -36,6 +36,20 @@ Numeric parsing is deliberately deferred to `get_map_data` (`pd.to_numeric(...,
|
|||||||
errors="coerce")`). Don't "fix" columns to float on load — blank coordinates and
|
errors="coerce")`). Don't "fix" columns to float on load — blank coordinates and
|
||||||
leading-zero PLZ both depend on the string representation.
|
leading-zero PLZ both depend on the string representation.
|
||||||
|
|
||||||
|
## CartoDB "positron" tiles now require an API key (2026-09-07)
|
||||||
|
|
||||||
|
The original `folium.Map(tiles="CartoDB positron")` started rendering an
|
||||||
|
"API KEY REQUIRED / carto.com/basemaps/apikey" watermark – Carto moved its
|
||||||
|
basemaps behind a key. Switched to `tiles="OpenStreetMap"` (constant
|
||||||
|
`MAP_TILES`), which needs no key. Trade-off: OSM standard tiles are more
|
||||||
|
colourful than positron's muted grey. Other no-key options if a lighter look is
|
||||||
|
wanted: OSM Germany (`tile.openstreetmap.de`), OSM France Hot
|
||||||
|
(`{s}.tile.openstreetmap.fr/hot`) – both still colourful. Truly muted
|
||||||
|
key-free basemaps are hard to find now.
|
||||||
|
|
||||||
|
Don't assume a "free" third-party tile source stays free – pin the provider in
|
||||||
|
one constant so swapping it is a one-line change.
|
||||||
|
|
||||||
## Nominatim query order matters
|
## Nominatim query order matters
|
||||||
|
|
||||||
`geocode_city` returns the **first** hit, trying PLZ-qualified first, then each
|
`geocode_city` returns the **first** hit, trying PLZ-qualified first, then each
|
||||||
|
|||||||
@@ -168,11 +168,12 @@ or at least skip exact duplicates by default.
|
|||||||
|
|
||||||
## 9. Offline map 🟢
|
## 9. Offline map 🟢
|
||||||
|
|
||||||
`karte.html` loads Leaflet/jQuery/Bootstrap from CDNs and tiles from CartoDB, so
|
`karte.html` loads Leaflet/jQuery/Bootstrap from CDNs and tiles from
|
||||||
the map is blank without internet even though all the data is local. If offline
|
`tile.openstreetmap.org` (`MAP_TILES`; switched away from CartoDB positron, which
|
||||||
use matters, vendor the Leaflet JS/CSS into `data/` and post-process the Folium
|
now needs an API key). The map is blank without internet even though all the
|
||||||
output to point at local files (tiles would still need caching or an offline
|
data is local. If offline use matters, vendor the Leaflet JS/CSS into `data/`
|
||||||
tile pack — larger effort).
|
and post-process the Folium output to point at local files (tiles would still
|
||||||
|
need caching or an offline tile pack — larger effort).
|
||||||
|
|
||||||
## 10. Small code-quality items 🟢 — partly done
|
## 10. Small code-quality items 🟢 — partly done
|
||||||
|
|
||||||
|
|||||||
+9
-4
@@ -62,8 +62,9 @@ A table view of everything in `orte.csv`.
|
|||||||
|
|
||||||
Generated by `generate_map()`:
|
Generated by `generate_map()`:
|
||||||
|
|
||||||
- Base layer: `CartoDB positron`, initial view centred on `[49.0, 9.0]`,
|
- Base layer: **OpenStreetMap** standard tiles (`MAP_TILES`) – no API key.
|
||||||
zoom 8 (roughly Baden-Württemberg).
|
Initial view centred on `[49.0, 9.0]`, zoom 8 (roughly Baden-Württemberg);
|
||||||
|
the view auto-fits to the markers when there is more than one.
|
||||||
- One **`CircleMarker`** per unique `(city, lat, lon)` group. Radius scales
|
- One **`CircleMarker`** per unique `(city, lat, lon)` group. Radius scales
|
||||||
linearly with the visit count for that location
|
linearly with the visit count for that location
|
||||||
(`5 + count / max_count * 20` px), colour is DRK red (`#CC0000`).
|
(`5 + count / max_count * 20` px), colour is DRK red (`#CC0000`).
|
||||||
@@ -72,8 +73,12 @@ Generated by `generate_map()`:
|
|||||||
- If there are no usable coordinates at all, a dialog says so (and the status
|
- If there are no usable coordinates at all, a dialog says so (and the status
|
||||||
bar shows a warning).
|
bar shows a warning).
|
||||||
|
|
||||||
> The generated HTML pulls Leaflet, jQuery and Bootstrap from CDNs, so the map
|
> The generated HTML pulls Leaflet, jQuery and Bootstrap from CDNs, and the map
|
||||||
> needs an internet connection to render even though the data is local.
|
> tiles from `tile.openstreetmap.org`, so the map needs an internet connection to
|
||||||
|
> render even though the data is local. To change the look, set `MAP_TILES` near
|
||||||
|
> the top of `app.py` to another no-key provider Folium knows
|
||||||
|
> (`"OpenStreetMap"`, `"CartoDB positron"` *now needs a key*, or a custom
|
||||||
|
> `folium.TileLayer` URL such as OSM Germany / OSM France).
|
||||||
|
|
||||||
## Geocoding behaviour
|
## Geocoding behaviour
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user