A MapProxy configuration that groups layers by WMS endpoint/service URL for better organization and maintainability.
mapproxy-config/
├── config.yml # Main configuration (loads all source modules)
├── config_layers.yml # All layer definitions (loaded first)
├── sources/ # One file per WMS endpoint (caches & sources only)
│ ├── shared-alkis.yaml # �️ Shared ALKIS background cache
│ ├── fbinter-alkis.yaml # 🗺️ ALKIS cadastral data
│ ├── fbinter-senstadt.yaml # 🛰️ Aerial imagery (2015, 2016 CIR)
│ ├── fbinter-oeffbeleucht.yaml # 💡 Public lighting
│ ├── gdi-bdom.yaml # 🏔️ Digital elevation model
│ ├── gdi-strassenbefahrung.yaml # 🛣️ Street survey 2014
│ ├── gdi-baumbestand.yaml # 🌳 Tree inventory (all variants)
│ ├── gdi-tempolimits.yaml # 🚦 Speed limits
│ ├── gdi-fussgaengernetz.yaml # 🚶 Pedestrian network
│ ├── gdi-postleitzahlen.yaml # 📮 Postal codes
│ ├── gdi-abstell-mikromob.yaml # 🛴 Micromobility parking
│ └── gdi-fahrradreparatur.yaml # 🔧 Bicycle repair stations
├── demo_links/ # Demo URLs for all available layers
└── docker-compose.yml # Local development environment
# Start MapProxy locally with Docker
docker-compose up -d
# View demo with all layers
open http://localhost:8080/demo/
# View generated demo links
open http://localhost:3001/
🗺 A list of all available maps with demo and editing urls …
- luftbilder.berlin.codefor.de showcases aerial images from different years Github
- maps.berlin.codefor.de showcases all kind of maps Github
- github.com/codeforberlin/tilestache-config is the config for serving aerial imagery from file (config)
This MapProxy setup uses a modular architecture that separates concerns:
config_layers.yml
: Contains ALL layer definitions (must be first in base array)sources/
: Individual files per data source containing only caches & sourcesconfig.yml
: Main config that includes all modules viabase
directive
layers:
section, so all layers must be defined in config_layers.yml
.
-
Add layer definition to
config_layers.yml
:layers: - name: my_new_layer sources: [my_new_cache] title: "My New Layer"
-
Add cache and source to the appropriate
sources/xxx.yaml
file:caches: my_new_cache: grids: [mercator] sources: [my_new_source] sources: my_new_source: type: wms req: url: https://gdi.berlin.de/services/wms/my_service layers: my_layer
-
Use https://gdi.berlin.de/viewer/main/ to inspect network requests
-
Add documentation in
layer_docs/
if helpful
- Create
sources/new-service.yaml
with caches and sources - Add layer definitions to
config_layers.yml
- Include the new file in
config.yml
base section:base: - config_layers.yml # Must be first! # ... existing files - sources/new-service.yaml
python3 -m venv env
source env/bin/activate
pip install -r requirements.txt
mapproxy-util serve-develop config.yml
# creates the wsgi.py script
mapproxy-util create -t wsgi-app -f config.yml wsgi.py
Note: We don't use make_wsgi_app(…, reloader=True)
but restart the server manually. The auto reloading would only restart if the config is valid, which would hide a broken edit. The manual reload will make the error visible.
Create a systemd service script in /etc/systemd/system/mapproxy.service
.
[Unit]
Description=Mapproxy gunicorn daemon
After=network.target
[Service]
User=tiles
Group=tiles
WorkingDirectory=/srv/tiles/proxy
ExecStart=/srv/tiles/proxy/env/bin/gunicorn --access-logfile /var/log/mapproxy/access.log --error-logfile /var/log/mapproxy/error.log --bind unix:/tmp/mapproxy.sock --workers 9 wsgi:application
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl start mapproxy
Add to nginx configuration:
location /proxy/ {
proxy_pass http://unix:/tmp/mapproxy.sock;
proxy_set_header Host $http_host;
proxy_set_header X-Script-Name /proxy;
}
nginx -t
systemctl start nginx
Use the Mapproxy Debug Page. It lists all layers that are avaliable based on the config. However, there is an issue with the projection, so the previews do not work.
Check that log.ini "active" (not commented out); if needed, change and restart.
Use cat mapproxy-config/mapproxy_log/source-requests.log
to see the requested URLs.
Copy one of those URLs and fiddle with the URL params the browser until the right image is shown.
ls mapproxy-config/cache_data/
shows all layer that have cached images. Remove the folder to trigger a cache refresh, eg rm -rf mapproxy-config/cache_data/alkis_30_cache_EPSG900913
Even with a fresh file system cache, images might still be cached in the browser. Unfortunately, iD Editor does not allow hard reloads to refresh this data. One workaround is, to zoom and pan the map so new images are requested.
Use URLs like https://fbinter.stadt-berlin.de/fb/wms/senstadt/wmsk_alkis?service=WMS&request=GetCapabilities&version=1.3.0
to create a list of layer IDs with description. Examples are [layer_alkis_berlin.md] and [layer_strassenbefahrung_berlin.md].
You can also try https://mybinder.org/v2/gh/rbuffat/eli-helper/master (GitHub) with the fbintern URL from above to get a list of avaliable layers.
- https://mapproxy.github.io/mapproxy/latest/index.html
- https://mapproxy.github.io/mapproxy/latest/configuration_examples.html#merge-multiple-layers how to merge layers
To see the installed version of mapproxy:
cd mapproxy-config
source env/bin/activate
mapproxy-util --version
# MapProxy 1.13.2
?service=WMS&request=GetCapabilities&version=1.3.0
?format=image%2Fpng&height=512&bbox=388800.010065,5818137.195276,393794.488433,5821374.047744&layers=0&srs=ESPG:25833&style=default&service=WMS&request=GetMap&width=512&version=1.3.0
?width=512&height=512&bbox=388800,5818137,393794,5821374&layers=0&srs=EPSG:4326&styles=default&format=image/png&service=WMS&request=GetMap&version=1.3.0