Routing mit pgRouting und Spring Boot implementieren
02.08.2025
Sobald deine Anwendung räumliche Daten mit PostGIS bereitstellen kann, ist der nächste logische Schritt die Implementierung von Routing. Dies ist essenziell für Anwendungen wie Logistik, Zustellung, Smart Mobility oder städteplanerische Werkzeuge.
In diesem Tutorial lernst du:
- Routing-Daten aus OpenStreetMap vorzubereiten
- Mit pgRouting (eine Erweiterung von PostGIS) kürzeste Wege zu berechnen
- Ein REST-Endpoint in Spring Boot zu erstellen, das GeoJSON oder Polylinien-Routen zurückgibt
Was ist pgRouting?
pgRouting ist eine Erweiterung für PostGIS, die Routing-Funktionen hinzufügt, darunter:
- Kürzester Weg (Dijkstra, A*)
- Abbiegebeschränkungen
- Fahrdistanzen
- Alternative Routen
Es arbeitet auf einer Graphdarstellung des Straßennetzes, das in PostgreSQL gespeichert ist.
Import und Vorbereitung der Routing-Daten
Verwende osm2pgrouting anstelle von osm2pgsql:
sudo apt install osm2pgrouting osm2pgrouting -f serbia-latest.osm.pbf -d routingdb -U postgres -W geheim -p 5432
Dadurch wird eine ways-Tabelle mit Straßensegmenten und Attributen erzeugt.
Erstellen des Straßennetz-Graphen
pgRouting erwartet bestimmte Spalten wie source, target, cost und Geometrie:
SELECT id, source, target, cost, reverse_cost, x1, y1, x2, y2 FROM ways;
Achte darauf, dass die Kosten realistisch sind (z. B. auf Basis von Länge / Geschwindigkeit):
ALTER TABLE ways ADD COLUMN cost DOUBLE PRECISION; UPDATE ways SET cost = length / 50.0; -- Durchschnittsgeschwindigkeit: 50 km/h
pgRouting in PostgreSQL einrichten
Aktiviere die Erweiterung:
CREATE EXTENSION pgrouting;
Analysiere das Netzwerk:
SELECT pgr_analyzeGraph('ways', 0.0001, 'geometry', 'id');
Dijkstra-SQL-Abfrage schreiben
Finde die nächstgelegenen Start- und Zielknoten und berechne die Route:
WITH start_node AS ( SELECT source FROM ways ORDER BY geometry <-> ST_SetSRID(ST_MakePoint(:lng1, :lat1), 4326) LIMIT 1 ), end_node AS ( SELECT target FROM ways ORDER BY geometry <-> ST_SetSRID(ST_MakePoint(:lng2, :lat2), 4326) LIMIT 1 ) SELECT w.id, w.geometry FROM pgr_dijkstra( 'SELECT id, source, target, cost FROM ways', (SELECT source FROM start_node), (SELECT target FROM end_node), false ) AS r JOIN ways w ON r.edge = w.id;
Integration des Routings in Spring Boot
Im Repository:
@Query(value = "...obige SQL-Abfrage...", nativeQuery = true) List<RouteSegment> findRoute(@Param("lng1") double lng1, @Param("lat1") double lat1, @Param("lng2") double lng2, @Param("lat2") double lat2);
Erstelle einen Controller:
@RestController @RequestMapping("/api/route") public class RoutingController { @Autowired private RoutingRepository routingRepository; @GetMapping public List<RouteSegment> route(@RequestParam double fromLat, @RequestParam double fromLng, @RequestParam double toLat, @RequestParam double toLng) { return routingRepository.findRoute(fromLng, fromLat, toLng, toLat); } }
GeoJSON oder kodierte Polylines zurückgeben
Nutze GeoTools, Jackson oder eigene Serialisierung, um GeoJSON auszugeben.
Beispiel:
ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new JtsModule()); // aus Jackson-datatype-jts return mapper.writeValueAsString(routeSegments);
Alternativ kann die Route auch als Polyline kodiert werden:
PolylineEncoder.encode(routeGeometry);
Performance-Tipps und Indexierung
- Erstelle einen räumlichen Index:
CREATE INDEX ways_geom_idx ON ways USING GIST (geometry);
- Berechne Bounding Boxes vorab zur schnelleren Filterung
- Beliebte Routen in Redis oder Materialized Views cachen
Fazit
Du hast nun ein vollständig funktionierendes Routing-Backend mit OpenStreetMap, pgRouting, PostGIS und Spring Boot. Damit legst du den Grundstein für Anwendungen in Navigation, Logistikplanung oder Zustelloptimierung.
Mögliche nächste Schritte:
- Anpassung der Kosten auf Basis von Verkehrsdaten
- Höhenprofil in die Berechnung integrieren
- Multimodales Routing (Fuß + ÖPNV)