Automated identification and visualization of 30 km/h (Tempo 30 / 20 mph) zones based on OpenStreetMap (OSM) data and PostGIS analysis. A Node.js proxy is included to bypass CORS restrictions between the browser and GeoServer.
Source Code: This project’s source code (scripts, SQL, proxy, and frontend) is licensed under the MIT License.
Data: This project uses OpenStreetMap data © OpenStreetMap contributors.The data is licensed under the Open Database License (ODbL) 1.0.https://www.openstreetmap.org/copyright
Basemap: Satellite imagery is provided by Esri World Imagery and is used for visualization purposes only.
This project integrates several tools for importing, analyzing, and serving geospatial data:
| Component | Layer | Purpose |
|---|---|---|
| osm2pgsql | Data | Imports OSM data into PostgreSQL. |
| PostGIS | Data | Stores OSM geometries and performs spatial analysis. |
| GeoServer | Service | Exposes analysis results as a WFS. |
| Express.js | Service | Provides a CORS-bypassing proxy for WFS requests. |
| MapLibre | Presentation | Displays the identified Tempo-30 segments on a web map. |
- Select eligible roads: Only primary, secondary, tertiary, and residential roads not already tagged as 30 km/h zones are considered; living streets are excluded.
- Buffer trigger objects: Social facilities, schools, care facilities, playgrounds, and zebra crossings are buffered by 50 m; residential buildings by 5 m (noise protection applies only to primary roads).
- Identify affected road segments: Roads intersecting the buffered objects are flagged as candidates.
- Extend zones: Segments are buffered by 150 m to ensure minimum 300 m zone length.
- Close gaps: Morphological operations fill gaps smaller than 500 m.
- Finalize selection: Only segments with the same name or within 1 m of a candidate are retained to ensure that unrelated roads are excluded.
git clone https://github.com/HKA-OSGIS/ZoneScope30
Navigate in the repo folder and run the setup script to install all dependencies:
cd ZoneScope30
bash setup.shNavigate in the repo folder and run the start.sh to start the application:
bash start.shThe classification of road segments follows a multi-stage spatial logic based directly on OSM tagging and neighborhood analysis.
Only roads meeting all of the following criteria are evaluated:
- Road class in:
highway=primary,highway=secondary, andhighway=tertiary. - Not a living street:
highway!=living_street - No existing valid 30-zone tagging. Ignored cases include:
- Numeric
maxspeed > 30 - Non-numeric
maxspeednot in:DE:zone:30
- Numeric
A road segment becomes a Tempo 30 candidate if at least one of the following applies:
- Residential roads:
All
highway=residentialsegments are automatically classified as Tempo 30.
Applies to highway=primary, highway=secondary, and highway=tertiary.
A segment qualifies if it lies within 50 m of one or more of the following:
- Schools:
amenity=school - Kindergartens:
amenity=kindergarten,amenity=childcare - Senior & care facilities:
nursing_home,hospital,social_facilitywithsocial_facility:for=senior - Playgrounds:
leisure=playground - Pedestrian crossings:
highway=crossingwithcrossing=zebraorcrossing_ref=zebra
Applies to highway=primary only.
A segment qualifies if it lies within 5 m of residential buildings:
building=residentialbuilding=apartmentsbuilding=housebuilding=terrace
After primary segments are determined, zones are extended for consistency:
-
Protected zone length: Identified segments are treated as 300 m protected corridors.
-
Gap filling: If two Tempo-30 corridors are less than 500 m apart, the intermediate road segment is also classified as Tempo 30.
This produces continuous, real-world-aligned Tempo-30 areas instead of isolated fragments.
