I have a set of origin-destination coordinates that I want to calculate the shortest paths between them.
My origin-destination coordinates are sometimes located in the middle of a long straight-line road. However, the shortest path calculated by OSMnx/networkx will not consider that mid-edge to nearest-node path.
Is there any ready function in OSMnx or networkx that I can use to find shortest path that originates/ends in the middle of the road?
If there is no such function, I am thinking of using the following steps.
Get nearest edges of origin and destination
Get nodes of those nearest edges: let's say (a,b) for origin, and (c,d) for destination
Calculate distance of 4 possible combinations: a->c, a->d, b->c, b->d
Project origin/destination onto their nearest edges: let's call them o1 and e1
Calculate distance o1->a, o1->b, e1->c, e1->d
Add (5) distance to (3): to get
o1->a->c->e1
o1->a->d->e1
o1->b->c->e1
o1->b->d->e1
Select path with smallest distance
OSMnx produces a networkx graph object for routing/analysis. As you note, networkx shortest path calculation takes an origin and a destination node, so trying to calculate a shortest graph path from an edge midpoint won't work.
A couple things you could try:
try to set simplify=False when you create the graph to retain as many nodes in the middle of streets as possible.
if that doesn't work, you could try to subdivide edges (with greater than some threshold length) into 50 meter chunks or somesuch to discretize them with more nodes.
See also: https://stackoverflow.com/a/55601732/7321942
Related
I have been using networkX to compute the shortest path distance between two points A and B in a graph thanks to Dijkstra's algorithm.
The edges of my graph represent road segments, and the nodes the connections between segments. The weight function is the segment length, so that the returned path distance is the actual geographical distance.
However, the calculated paths are sometimes unrealistic for my use. More specifically, I would like to prevent the algorithm from using paths implying very sharp turns between two successive edges. This implies that the weight of a particular edge is a function of the edge itself, but also of its precedessor in the path (so that the turn angle can be computed and sharp turns dismissed).
As a (simplistic) example, let's consider the below graph (assuming that the nodes and represented according to their actual geographical position). For the sake of simplicity, each edge has a weight (or distance) equal to 1.
The shortest path from A to B is shown in green, and the corresponding distance is 2.
Shortest path without "sharp turn" constraint
However, the proposed path involve a sharp turn at node C (which can be detected based on the geographical coordinates of nodes A, B and C). This kind of turn should be forbidden, such that the proposed shortest path becomes the one described below.
Shortest path with "sharp turn" constraint
The distance is now 6, but the path avoids the transition A-B-C which involved a sharp turn.
What do you think are my options to implement such requirement?
I have done something similar by making it a multi edge graph. Such as there is more than one edge between any two nodes. The 2nd edge in your case could be a numerical value identifying the orientation of the edge(road).
Considering south to north as 0, you could assign -180 to 180 to each orientation and then your algorithm need only compute the difference between the two weights of these edges to figure out if the node is sharp turn and thus eliminate it.
Look up “multgraph” or “multidigraph” in networkx api for implementation
One edge has to be distance other has to be orientation, encoding both orientation and distance to a single weight will require trignometric coding from a central (0) point
Building on the discussions here and here. I'm trying to compute the shortest distance between a 3D line and a 3D triangle.
I'm using barycentric coordinates to determine whether or not the point is inside the triangle. So given a triangle defined by vertices UVW and a line defined by point AB, I first compute the intersection of line AB with the plane defined by UVW. Let's call this intersection P and assume I've already done the checks to verify whether or not the point actually intersects the plane at all.
I then compute barycentric coordinates (S,T) such that S is defined along the edge UV and T is defined along the edge UW. Naturally, if 0≤S and 0≤T and S+T≤1 then P is on the triangle (or its edge) and my distance to the triangle is obviously zero.
If that's not true then P is outside the triangle and I need to compute the distance. The guidance of from the first link says to project point P onto all three edges to get three candidate points. Adding those points to the three triangle's vertices, you then have six points to test against.
Isn't it easier than that, though? If T<0, then don't you already know that UV is the closest edge and you only have to test against the projection of P onto that line? Similarly, if S<0 then UW would be the closest edge. If T>0 and S>0 then VW is the closest edge.
Thus based on the signs of S and T you already know the closest edge and only have to compute the distance from P to its projection onto that edge. If the projection isn't inside the triangle, then the closest point is either vertex. Thus your computations are about 1/3 of the proposed methods.
Am I missing something here, or is this a valid optimization? I'm fairly new to barycentric coordinates and their attributes.
It turns out that the problem of closest distance from a point and from a line are very similar and can both be reduced to a pure 2D problem.
Distance from a point
By Pythagoras, the squared distance from a point to a point of the triangle is the sum of the squared distance to the plane of support of the triangle and the squared distance of the projection of the point to that plane.
The latter distance is precisely the distance from the normal line to the triangle.
Distance from a line
Looking in the direction of the line, you see the projected triangle and the line is reduced to a single point. The requested 3D distance is equal to the 2D distance seen on the projection.
To obtain the desired coordinates, you use an auxiliary coordinate frame such that Z is in the direction of the line (and XY is a perpendicular plane); for convenience, choose the origin of the new frame to be on the line. Then by just ignoring Z, you get a planar problem in XY. The change of coordinates is an affine tranformation.
Point vs. triangle
Consider the three triangles formed by the origin (projection of the point/line) and a pair of triangle vertices (taken in cyclic order). The signed area of these triangles is a mere 2x2 determinant.
If the three areas have the same sign, the point is inside. Otherwise, the signs tell you where you are among the six surrounding regions, either past an edge or past a vertex.
On the upper figure, the point is inside (three positive areas). On the other figure, it is outside of the top-right edge (one negative area). Also note that dividing an area by the length of the corresponding side, you get the distance to the side. (Factor 2 omitted.)
The total work is
compute the affine frame;
convert the coordinates of the 3 or 4 points;
compute the three signed areas;
if inside, you are done;
otherwise, if in an edge region, compute a distance to a line and two distances to points;
otherwise you are in a vertex region, compute two distances to lines and one distance to vertex.
I have two points dataset, which come from two mesh with an intersection. How can I find the shortest point in the 2nd dateset for each points in the first one?
I am looking for how to calculate the distance along a path in a binary array.
I imported a map as a matrix in matlab. There is a binary image of a river crossing two cities. I only found out how to calculate the distance from the river points to the nearest city but I don't manage to compute the shortest distance along the river.
I made a vector with the indices of all river points but I don't know how to get the distance to the nearest city from that...
Image
So I am looking for the shortest distance through the red line towards one of the light blue points it crosses !
Thnx
If I understand you in the right way it is not very difficult: Just do a dfs or bfs (8-neighbourhood) starting at each river-town and add sqrt(2) if you go diagonal and 1 if you go to a 4-neighbour. At each river pixel you can finally decide by taking the minimum value. You can develop it further stopping at river pixels with already smaller distance to another city...
I really hope I got you in the right way :)
I managed to find the intersections of an arbitrary number of lines within a binary image.
Then i use a function where i detect the intersections between the lines. So now i have the coordinates of the intersections saved in an array.
Now i want to calculate the distance between the intersections(an imaginary line that connects all my intersections) but i want the distance calculation to traverse along the lines that are already on the binary image.
So the distance calculation cannot escape a line while calculating, instead it must ''walk along it''.
The imaginary path(of which eventually we calculate its distance) must walk along the already drawn lines.
EDIT** THIS IS MY INTERSECTION DETECTION ''ALGO''
clear all
pellara4=imread('C:/users/lemesios/desktop/pellara4.jpg');
blackwhitepellara=im2bw(pellara4,0.5);
I = blackwhitepellara;
C = corner(I);
num_of_rows=size(C,1);
num_of_cols=size(C,2);
for z =1:num_of_rows
k=C(z,2);
j=C(z,1);
if (I(k+1,j)==0)&& (I(k,j+1)==0) && (I(k-1,j)==0) && (I(k,j-1)==0)
imshow(I);
hold on
plot((j), (k), 'b*');
disp(k);
disp(j);
end
end
I feel this is similar to Dijkstra's algorithm. You can denote the intersection points by nodes. Then generate a mesh where each intersecting point is connected to every other intersecting point. Then if there exists a line in the binary image, assign a unit weight, otherwise assign inf i.e. infinite weight. When you have to measure distnace between m-th point and n-th point (say), then make m-th point as source and n-th point as destination and find the shortest path according to Dijkstra's algorithm.