Firstly few questions:
1. what do you mean by converting roads to nodes? Maybe you meant network graph?
2. Are you able to find at least one way and the trouble is with many ways?
3. Nearest school euclidean or by the roads?
4. What was the work-flow of this conversion form roads to nodes?
5. What are the names of tables and column names in this tables?
6. How big are your tables with students and schools?
7. Is it OK to select nearest school euclidean
Please add information to your question so maybe there will be simplest to help you.
But back to the point:
PG_Routing is not a resolution out of the box since it provides a kind of 'low level' stored procedures. You can't write query like 'select pg_CountMeTheWay(student, scholl), but it can find shortest way if you'll give it source edge id, target edge id and set of edges as graph with cost.
Also function st_DrivingDistance is not finding route, but it's creating set of edges reachable in specified time (e.g. how far you can go in 15 minutes).
Also 2 you need distance from student to nearest school but which is nearest if you don't know the distance? Do you have some kind of relation between schools and students? If not you have to count distance from one student to every school to know which is nearest. In most cases nearest euclidean (in straight line) will be also nearest by the roads, but if you have some special cases in your graph such as river with one bridge you cant be sure.
There are many resolutions of your problem even without this questions to your question, so please try to be more specific.
EDIT
Ok, so hope you have a lot of time :)
Firstly - to know the driving distance you have to (one way or another) find shortest path - there is no smoke without fire...
1. Driving distance is not doing anything different then this, but under another conditions. It's like space-time in military meaning - you have to dig ditch from here to everywhere till 4:00pm.
2. Also as far as I know driving_distance is working like window functions (e.g. row_number() over()) so it's designating cost during calculations, so you can't make him to do calculations for all edges, but designate cost only to few. Of course you can do select from select but this means that distance to every edge will be calculated anyway.
3. pgr_Driving_distance is much more slower then pgr_dijkstra - finding one route between points spaced about 15km is taking on my dataset (all Poland) about 1s (0,5-2,5), driving distance with the same condition will be about 15s
Basing upon this times counting:
1. Shortest paths between all students and scholls (100000x50x2) will last 115 days
2. Shortest paths between all students and scholls with minimal time will last about 46 days
3. Mixed version - Shortest paths between all students and 10 euclidean nearest to them scholls will last about 10 days
4. driving_distance for all students till 15km will last 17 days
5. Short version - Shortest paths between all students and 1 euclidean nearest to them scholl will last about 1 day.
6. Performance depends on numer of rows in edges table (network graph) so less records less time you'll need.
Possible resolution (1):
- Write stored procedure with your pgr_djikstra() with id_source, id_target as input and cost as output (there are many exapmples on network)
- create table with id_student, id_source, id_school, id_target, cost
- Fill it with Id's and nearest edges of network graph
- update it with cost of shortest path using your function
- select for every student record with the lowest cost
Possible resolution (2):
- Write stored procedure with driving_distance with source_id as input and retorn output of driving_distance
- Write stored procedure with geometry as input and nearest edge id as output.
- create tables with students and their nearest edges using above procedure, the same for schools
- create table a as select *, your_proc(nearest_edge_id) as dist from students_nearest.
- create another table b as select * from a where exists id of nearest student and school id
- Select from this table records with student_id, school_id, min(cost) group by student_id, school_id
IMO the best resolution as compromise of time and quality is to find 3 euclidean nearest schools for every student and count for them shortest paths, then choose one - the shortest. With some tuning and only absolutely necessary edges in network graph you can feet in few hours.
As @robin loche suggested, you don't assign the points in your from and to point lists to the network vertices. You use the locations of your from and to points to find the closest start and destination vertices in the network for each search.
The following nested queries do this in stages:
generate all pairs of source and destination points
find closest network vertices for each point pair
run the routing algorithm
The results of pgr_Dijkstra are returned here as a sequence of rows for each from, to point pair with each row containing a step in the route sequence in a composite type. You may want to nest this to unpack those results a bit more. Being a stream application, you probably also have a directed network.
This should get you started.
ALTER TABLE streams ADD COLUMN length float8; -- add length field for pgr costs
UPDATE streams SET length = ST_Length(geom::geography);
WITH all_pairs AS (
-- all pairs of start and end geometries with IDs
-- that get carried through so your routing results
-- match with the pt IDs you know.
SELECT f.gid AS fid, f.geom as fgeom,
t.gid as tid, t.geom as tgeom
FROM from_pts AS f,
to_pts AS t
), vertices AS (
SELECT fid, tid,
(SELECT id -- proximity search for closest from vertex
FROM streams_vertices_pgr
ORDER BY the_geom <-> fgeom
LIMIT 1) as fv,
(SELECT id -- proximity search for closest to vertex
FROM streams_vertices_pgr
ORDER BY the_geom <-> tgeom
LIMIT 1) as tv
FROM all_pairs
)
SELECT fid, tid, pgr_Dijkstra(
'SELECT gid AS id, source, target, length AS cost FROM streams',
fv, tv,
directed =>false
) from vertices;
Best Answer
The geometrytype should be LineString, not LineStringM.
Try changing your geom column to LineString with this: