Reputation: 1619
I have a Postgis table containing a lot of MultiLineString features.
I would like to use that data to create a route between Point A and Point B. I assume there is no single feature, which allows to solve that problem. It means the route has to combined from two or more MultiLineString features.
How can I solve that problem?
Upvotes: 2
Views: 85
Reputation: 21
It's not really possible to answer without the examples but I can point you to the direction of what I've done to solve a similar issue. I had a lot of MultiLineString that represented roads. I also had Points that represented a road node, where two roads merge.
You can find the shapefiles here: https://geoservices.ign.fr/route500#telechargement
I had to create a pgRouting table to calculate how to get from a road point to another.
CREATE TABLE routes (
id INTEGER,
source INTEGER,
target INTEGER,
cost FLOAT,
reverse_cost FLOAT);
Then fill the table with infos from the road multilinestrings:
WITH troncon AS (
SELECT ogc_fid AS id,
CASE
WHEN sens = 'Sens inverse' THEN ST_EndPoint(ST_LineMerge(wkb_geometry))
ELSE ST_StartPoint(ST_LineMerge(wkb_geometry)) END AS source,
CASE
WHEN sens = 'Sens inverse' THEN ST_StartPoint(ST_LineMerge(wkb_geometry))
ELSE ST_EndPoint(ST_LineMerge(wkb_geometry)) END AS target,
longueur AS cost,
CASE WHEN sens = 'Double sens' THEN longueur ELSE -longueur END AS reverse_cost
FROM troncon_route
)
INSERT INTO routes (id, source, target, cost, reverse_cost)
SELECT id,
(SELECT noeud_routier.ogc_fid FROM noeud_routier ORDER BY noeud_routier.wkb_geometry <-> source LIMIT 1) AS source,
(SELECT noeud_routier.ogc_fid FROM noeud_routier ORDER BY noeud_routier.wkb_geometry <-> target LIMIT 1) AS target,
cost,
reverse_cost
FROM troncon;
You can then use dijstra to get the most optimal route:
WITH road_near_parcel AS (
SELECT noeud_routier.ogc_fid AS id
FROM noeud_routier
ORDER BY noeud_routier.wkb_geometry <-> (SELECT parcels.centroid FROM parcels WHERE id = 250000054000010276) LIMIT 1
),
road_near_facility AS (
SELECT noeud_routier.ogc_fid AS id
FROM noeud_routier
ORDER BY noeud_routier.wkb_geometry <-> (SELECT facilities.geometry FROM facilities WHERE id = 1946) LIMIT 1
)
SELECT troncon_route.num_route,
SUM(di.cost) AS cost
FROM pgr_dijkstra(
'SELECT id, source, target, cost, reverse_cost FROM routes',
(SELECT road_near_parcel.id FROM road_near_parcel),
(SELECT road_near_facility.id FROM road_near_facility),
false
) AS di
JOIN troncon_route ON troncon_route.ogc_fid = di.edge
GROUP BY troncon_route.num_route;
I hope that helps! I think you can focus on how to transform a multilinestring to a routing table. You can use ST_EndPoint and ST_EndPoint to get the extremities
Upvotes: 2