diff --git a/Dockerfile b/Dockerfile index 832fcce..916ce37 100644 --- a/Dockerfile +++ b/Dockerfile @@ -15,6 +15,7 @@ RUN apt-get update \ python3 python3-distutils \ postgresql-server-dev-15 \ curl unzip \ + postgresql-15-pgrouting \ && rm -rf /var/lib/apt/lists/* RUN wget https://luarocks.org/releases/luarocks-3.9.1.tar.gz \ diff --git a/docs/src/dc-example-route-start-end-vertices.png b/docs/src/dc-example-route-start-end-vertices.png index 3986ed5..d9050fe 100644 Binary files a/docs/src/dc-example-route-start-end-vertices.png and b/docs/src/dc-example-route-start-end-vertices.png differ diff --git a/docs/src/dc-route-not-respecting-one-way.png b/docs/src/dc-route-not-respecting-one-way.png new file mode 100644 index 0000000..9668483 Binary files /dev/null and b/docs/src/dc-route-not-respecting-one-way.png differ diff --git a/docs/src/dc-route-respecting-one-way.png b/docs/src/dc-route-respecting-one-way.png new file mode 100644 index 0000000..7b38410 Binary files /dev/null and b/docs/src/dc-route-respecting-one-way.png differ diff --git a/docs/src/routing.md b/docs/src/routing.md index cd68a67..ac6f165 100644 --- a/docs/src/routing.md +++ b/docs/src/routing.md @@ -96,24 +96,59 @@ ALTER TABLE routing.road_line_noded ## Start/end points -Picked vertex IDs `11322` and `7653`, they span a particular segment +The following query identifies the vertex IDs for a start and end point to use +for later queries. Use the `start_id` and `end_id` values from this query +in subsequent queries. + + +```sql +WITH s_point AS ( +SELECT v.id AS start_id + FROM routing.road_line_noded_vertices_pgr v + INNER JOIN (SELECT + ST_Transform(ST_SetSRID(ST_MakePoint(-77.0211, 38.92245), 4326), 3857) + AS geom + ) p ON v.the_geom <-> geom < 10 + ORDER BY v.the_geom <-> geom + LIMIT 1 +), e_point AS ( +SELECT v.id AS end_id + FROM routing.road_line_noded_vertices_pgr v + INNER JOIN (SELECT + ST_Transform(ST_SetSRID(ST_MakePoint(-77.0183, 38.9227), 4326), 3857) + AS geom + ) p ON v.the_geom <-> geom < 10 + ORDER BY v.the_geom <-> geom + LIMIT 1 +) +SELECT s_point.start_id, e_point.end_id + FROM s_point, e_point +; +``` + +``` +┌──────────┬────────┐ +│ start_id │ end_id │ +╞══════════╪════════╡ +│ 14630 │ 14686 │ +└──────────┴────────┘ +``` + +Picked vertex IDs `14630` and `14686`, they span a particular segment of road that is tagged as `highway=residential` and `access=private`. This was picked to illustrate how the calculated access control columns, `route_motor`, `route_cycle` and `route_foot`, can influence route selection. > Note: The vertex IDs in my test database will not necessary match the vertex IDs in your database! -```bash -Name |Value | ---------+----------------------+ -osm_id |6062791 | -osm_type|residential | -name |Howard Place Northwest| -access |private | +```sql +SELECT * + FROM osm.road_line + WHERE osm_id = 6062791 +; ``` - -![Screenshot from QGIS showing two labeled points, 11322 and 7653. The road between the two points is shown with a light gray dash indicating the access tag indicates non-public travel.](dc-example-route-start-end-vertices.png) +![Screenshot from QGIS showing two labeled points, 14630 and 14686. The road between the two points is shown with a light gray dash indicating the access tag indicates non-public travel.](dc-example-route-start-end-vertices.png) > See `flex-config/helpers.lua` functions (e.g. `routable_motor()`) for logic behind access control columns. @@ -132,8 +167,9 @@ SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom FROM pgr_dijkstra( 'SELECT id, source, target, cost_length AS cost, geom - FROM routing.road_line_noded', - 11322, 7653, directed := False + FROM routing.road_line_noded + ', + 14630, 14686, directed := False ) d INNER JOIN routing.road_line_noded_vertices_pgr n ON d.node = n.id LEFT JOIN routing.road_line_noded e ON d.edge = e.id @@ -146,9 +182,8 @@ SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom ## Route motorized The following query modifies the query passed in to `pgr_dijkstra()` -to join to `osm.road_line`. The join clause includes `route_motor` -which ensures sidewalks aren't chosen, as well as enforces simple -access control. +to join to `osm.road_line`. The join clause includes a filter on +the `route_motor` column. ```sql @@ -157,10 +192,10 @@ SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom 'SELECT n.id, n.source, n.target, n.cost_length AS cost, n.geom FROM routing.road_line_noded n - INNER JOIN osm.road_line r - ON n.old_id = r.osm_id - AND route_motor', - 11322, 7653, directed := False + INNER JOIN routing.road_line r ON n.old_id = r.id + AND r.route_motor + ', + 14630, 14686, directed := False ) d INNER JOIN routing.road_line_noded_vertices_pgr n ON d.node = n.id LEFT JOIN routing.road_line_noded e ON d.edge = e.id @@ -192,14 +227,20 @@ ALTER TABLE routing.road_line_noded UPDATE routing.road_line_noded rn SET oneway = r.oneway - FROM osm.road_line r - WHERE rn.old_id = r.osm_id AND rn.oneway IS NULL + FROM routing.road_line r + WHERE rn.old_id = r.id AND rn.oneway IS NULL ; ``` +### Forward and reverse costs + Calculate forward cost. ```sql +ALTER TABLE routing.road_line_noded + DROP COLUMN IF EXISTS cost_length +; + -- Cost with oneway considerations ALTER TABLE routing.road_line_noded ADD cost_length NUMERIC @@ -231,7 +272,11 @@ ALTER TABLE routing.road_line_noded ; ``` -Route, now directed. +### New undirected route + +Found new start point slightly to the north that will require one-way aware +for proper routing. The route from this query incorrectly goes the wrong +way on 6th Street Northwest. ```sql SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom @@ -241,14 +286,44 @@ SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom n.geom FROM routing.road_line_noded n INNER JOIN osm.road_line r - ON n.old_id = r.osm_id + ON n.old_id = r.id AND route_motor AND n.cost_length IS NOT NULL ', - 39877, 8227, + 14624, 14686, + directed := False + ) d + INNER JOIN routing.road_line_noded_vertices_pgr n ON d.node = n.id + LEFT JOIN routing.road_line_noded e ON d.edge = e.id +; +``` + + +![Screenshot from DBeaver showing a route with a small segment going the wrong way on a one-way street because the query was using `directed := False`.](dc-route-not-respecting-one-way.png) + +### Directed + +Route, now directed. This respects the one-way rules. + + +```sql +SELECT d.*, n.the_geom AS node_geom, e.geom AS edge_geom + FROM pgr_dijkstra( + 'SELECT n.id, n.source, n.target, n.cost_length AS cost, + n.cost_length_reverse AS reverse_cost, + n.geom + FROM routing.road_line_noded n + INNER JOIN routing.road_line r + ON n.old_id = r.id + AND route_motor + AND n.cost_length IS NOT NULL + ', + 14624, 14686, directed := True ) d INNER JOIN routing.road_line_noded_vertices_pgr n ON d.node = n.id LEFT JOIN routing.road_line_noded e ON d.edge = e.id ; ``` + +![alt coming soon](dc-route-respecting-one-way.png)