You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
The actual SQL behind "The Answer You Didn't Want" — Rounds 4 and 5
#5
A reader of the DEV article asked for the real SQL from the two most instructive rounds. Fair ask. Here it is, from scripts/t27_q4.sql in the repo (commit a6c0d98):
Three different SRIDs were in play: argos.road_seg_vertices.geom in EPSG:32634 (UTM), argos.road_seg and argos.pois in 4326, and the raw planet_osm_* tables in 3857. The census check:
Comparing geometries across that mix without transforming does two kinds of damage: the PostGIS <-> KNN runs an internal ST_Distance recheck that errors on mixed SRIDs, and when the plan skips the recheck it silently picks a garbage anchor vertex. The fix in the production query is explicit transforms at every comparison point:
sql
WITH o AS (
-- Fiskardo anchor point: planet_osm way is EPSG:3857, transform to 4326SELECT ST_Transform(p.way,4326) AS g FROMpublic.planet_osm_point p
WHEREp.nameLIKE'%ισκάρδ%'ANDp.placeIS NOT NULLLIMIT1
),
anchor AS (
-- routing vertices are EPSG:32634, transform to 4326 BEFORE the KNNSELECTv.idAS vid FROMargos.road_seg_vertices v, o
ORDER BY ST_Transform(v.geom,4326) <->o.gLIMIT1
)
Note: ST_Transform inside the ORDER BY defeats the GiST index. Acceptable for a one-off anchor lookup on 17,468 vertices; for batch work you materialize transformed endpoints into a table with its own index first.
Round 5: the row-order bug
The wrong pattern, which I had written:
sql
-- WRONG: over one-to-many pgr_dijkstra outputSELECTr.end_vid, r.agg_costFROM pgr_dijkstra(
'SELECT id, source, target, cost_m AS cost, rcost_m AS reverse_cost FROM argos.road_seg',
<anchor_vid>,
(SELECT array_agg(net_vid) FROMargos.poisWHERE poi_type IN ('ferry_terminal','marina') AND net_vid IS NOT NULL),
true
) r
ORDER BYr.agg_costLIMIT1;
In one-to-many mode every path's anchor row carries agg_cost = 0, so ORDER BY agg_cost LIMIT 1 returns the first row of an arbitrary path, not the cheapest destination. (Lixouri "won" by row-order luck before the fix.) The fixed pattern from the script:
sql
tot AS (
-- agg_cost accumulates along each path, so the per-destination total-- is the MAX within each end_vid groupSELECT end_vid, max(agg_cost) AS total_min FROM d0 GROUP BY end_vid
),
best AS (SELECT end_vid, total_min FROM tot ORDER BY total_min LIMIT1)
Then the winning route is reconstructed by filtering to that end_vid and ordering by seq:
sql
SELECTd.seq, d.cost, rn.geomFROM d0 d JOINargos.road_seg rn ONrn.id=d.edgeWHEREd.end_vid= (SELECT end_vid FROM best) ANDd.edge>0ORDER BYd.seq;
Two details worth keeping: d.edge > 0 drops pgRouting's terminal row per path (edge = -1, no geometry), and ORDER BY d.seq is what turns a pile of segments back into a drawn route.
Final answer from this exact script: Agia Effimia Marina. 29.0 km. 44 minutes. 116 segments.
The full file (three queries: stats JSON, route GeoJSON, origin/destination markers) is MIT-licensed in the repo; the pre-computed outputs it generates live at docs/assets/demo/.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
A reader of the DEV article asked for the real SQL from the two most instructive rounds. Fair ask. Here it is, from
scripts/t27_q4.sqlin the repo (commit a6c0d98):https://github.com/argos-geo/kefalonia-digital-twin/blob/main/scripts/t27_q4.sql
Round 4: mixed SRIDs
Three different SRIDs were in play:
argos.road_seg_vertices.geomin EPSG:32634 (UTM),argos.road_segandargos.poisin 4326, and the rawplanet_osm_*tables in 3857. The census check:sql
Comparing geometries across that mix without transforming does two kinds of damage: the PostGIS
<->KNN runs an internalST_Distancerecheck that errors on mixed SRIDs, and when the plan skips the recheck it silently picks a garbage anchor vertex. The fix in the production query is explicit transforms at every comparison point:sql
Note:
ST_Transforminside theORDER BYdefeats the GiST index. Acceptable for a one-off anchor lookup on 17,468 vertices; for batch work you materialize transformed endpoints into a table with its own index first.Round 5: the row-order bug
The wrong pattern, which I had written:
sql
In one-to-many mode every path's anchor row carries
agg_cost = 0, soORDER BY agg_cost LIMIT 1returns the first row of an arbitrary path, not the cheapest destination. (Lixouri "won" by row-order luck before the fix.) The fixed pattern from the script:sql
Then the winning route is reconstructed by filtering to that
end_vidand ordering byseq:sql
Two details worth keeping:
d.edge > 0drops pgRouting's terminal row per path (edge = -1, no geometry), andORDER BY d.seqis what turns a pile of segments back into a drawn route.Final answer from this exact script: Agia Effimia Marina. 29.0 km. 44 minutes. 116 segments.
The full file (three queries: stats JSON, route GeoJSON, origin/destination markers) is MIT-licensed in the repo; the pre-computed outputs it generates live at
docs/assets/demo/.Background reading: [The Answer You Didn't Want (DEV)](https://dev.to/ptzivras/the-answer-you-didnt-want-fiskardo-evacuation-routing-4hok)
All reactions