I am trying to route though a set of pedestrian crossings. I ask a route to the Google Maps service to get a default route, the problem with that route is that it does not include some waypoints (pedestrian crossings) (and re-requesting a route with found walkways as waypoints does not lead to satisfying results). I have the geocoordinates of each pedestrian crossing in the streets the route is requested (for each one, I have both endpoints coordinates).
To solve the problem, I approximate the lat,lon coordinates to (x,y) values which is correct for the accuracy I need. So a route is defined by a with a set of (x,y) coordinates.
I can decompose the problem in two sub-problems:
1) Finding which pedestrian crossings should be used to reach the destination
2) Update the existing route with the found pedestrian crossings
For 1), I defined some conditions about when to attach a crossing to a given route segment.
a. Each extremity of the pedestrian crossing should be max 10m far from the current segment
b. Each extremity is located “inside" the current segment (dot product of some extremity to segment begin and to segment end should be negative)
c. I only attach one crossing to a given route segment (others are rejected) It gives me a quite correct subset of pedestrian crossings but I am not sure if it is optimal ?
For 2) I have no clue about how to efficiently merge the found pedestrian walkways with the existing route (I started looking at the A* algorithm) ?
Here is some example of route from point A to point B (in orange the pedestrian crossings, in black the input route, in blue the expected output route).
Related
I'm passing the google maps "Snap to Road" api a list of 99 points. I only get back 85 points, which means I have some points missing that won't be snapped. Is there a way to get back all the points?
Observable.fromPromise(googleMapsClient.snapToRoads({
path: bucket,
interpolate: interpolate
}).asPromise()).map(routeLocations => {
console.log(routeLocations)
}
RESPONSE FROM API:
routeLocations.query.path.split('|').length
> 99
routeLocations.json.snappedPoints.length
> 85
Certain points can be dropped from the snapped points array. Typically it happens when the points in the original path array are zigzag back and forth along a road. Unfortunately, I cannot see your path array in this question, so let me use my examples to explain this.
The path parameter describes a continuous path, so the order of points that you pass is important. As the official documentation states, the snap to road returns the most likely path taken by a vehicle, so points will get dropped if they e.g. zigzag back and forth along a road.
The following screenshot shows an example of good path where all three points can be snapped.
Now have a look at the example where the point 2 is dropped because it seems to not follow direction from 1 to 3, you have to go back and forward.
Finally, let's consider a more complex example:
52.14475625,20.79042166|52.14475625,20.79036802|52.14471345,20.79042435|52.14479246,20.79031706|52.14466408,20.79047531|52.14460647,20.79051822|52.1448369,20.79028487|52.14455544,20.79060137
Several points are dropped as shown in the following screenshot (orange points)
I hope my answer addresses your doubts!
I have a list of Points-of-Interest (e.g. car rest areas).
The user selects the Starting Point and the Ending Point.
This generates a route.
How can I programmatically filter the POIs that are close (e.g. 50 meters distance from the road) that route?
Can Google Maps SDK or OSRM offer this functionality?
Thank you,
Nick
1. You have to find the distance from one POI to the road.
In order to accomplish this, you have to store your road in a mathematical fashion:
You can sample equidistant points of your road and store them in an array (more practical, less precise) and then calculate the distance of the POI from every point in the array, then save the minor result and repeat the whole process for every POIs.
You can store a road in a function (more and more complex, but more precise). Now that you have this function, you can calculate same distance from your POI, take the minimum value and repeat for all POIs.
2. Google Distance Matrix can actually do this
With this Api you can calculate distance till 2500 origins * destinations points.
The result will give you an array of rows, with each row corresponding
to an origin, and each element within that row corresponds to a pairing of the origin with a destination value.
Example of a request:
https://maps.googleapis.com/maps/api/distancematrix/json?units=metric&origins=32.777211,35.021250&destinations=32.778663,35.015757&key=YOURAPIKEY
This is very useful to your goal, because lets you specify more than one points of which calculates distance.
I'll find a route between two places, for example using google maps. I'd like to divide the route to kilometers (two following places will be at a distance of 1 km), and get GPS coordinations of these places. This is because then I'll be able to get exacly the coordinations of, for example, 5th kilometer on the route. Could you please advice me how to achieve it?
This is extremely nontrivial. Is say your best bet is to find an algorithm to load the bearing between two points, then one to load a coordinate given a start point, distance, and bearing. This could give you it, but only if the data contained only straight lines. Since I assume the Google Maps API only gives you the turns the user has to make, this approach will be inaccurate when there are bends in roads. You'd need GIS data for roads and what will undoubtedly turn into a complicated algorithm to find something like this. It's definitely doable, but that's l how I'd start. Look into the Census TIGER road data, it should help.
Unless, of course, I'm wrong and the API does actually give enough points to cleanly map it, in which case those functions should be easy to find and implement.
This will only work if you have the polyline as a sequence of lat/lon (or other) coordinates, wherever you get that from.
Then you start at the beginning an iterate through the lines (point[i], point[i+1]).
THis distance you calculate with standard API.
while itersting you sum up the distance.
Once you exceed the 1000m, you know that the splitting point (the 1000m marker) is at line segment [i,i+1].
To calculate the exact position where on the line that is, you take the total summed meters from previous segment, and the value of this segment and do a linear interpolation.
The working code is a bit complexer: there can be multiple markes within one segement.
But first find out where you get the polyline from, whitou that it will not work.
What I want to get is: the path which connect all the points in my graph, but without having to tell the algorithm where to start and where to finish.
It need to use the driving direction in google-maps api but without setting a start or end point.
It is not the TSP problem because I don't have a "start city" and I don't have to get back to the "start city" neither.
As expressed in this question: Find the shortest path in a graph which visits certain nodes,
I could just use permutation because I have a few nodes, but the problem is that I need to analyze several groups of this few nodes So I would like the function to be the less time consuming posible.
NOTE: Im not looking for a Minimum Spaning Tree as this one neither: https://math.stackexchange.com/questions/130863/connecting-all-points-on-a-plane-with-shortest-path-possible
I want a path which tell me you will save gas if you go first here, then overthere, then overthere, and finally there.
Question: is there any library which can help me with that? Or is it a know problem that has already an exact answer? How could I solve it?
It sounds like you want an all pairs shortest path algorithm. This is the class of shortest path algorithms that attempt to compute the shortest path (or the length of the shortest path) between every pair of vertices in the graph.
These is a well-known problem, and solutions exist. Here's some reading material that describes other possible algorithms. There might be implementations of Johnson's algorithm for your chosen language and development environment.
Keep in mind, this is an expensive problem, computationally speaking.
If I understand you correctly, you want 1 route to visit all the nodes, without a predefined start/end and you want that to be minimal. A possible solution could be to modify your graph a bit to allow a travelling salesman algorithm to get a complete tour.
You start with your graph and add 1 extra node E. You connect that node to all other nodes in your graph and set the cost of all those edges to a very high constant M. You then unleash a travelling salesman algorithm on that graph which will give you a path P starting at E, passing all nodes and returning to E. If you remove the 2 edges in P that connected E to the rest of your path you will have what you were looking for.
A quick intuitive proof that it is indeed what you were looking for: Suppose it's not the cheapest way to connect all nodes. Let's call the supposedly better path Q. Q and P both connect all nodes in your original graph. The end points of Q would be A and B. Both of these would be connected to node E with an edge of cost M. If you would add those 2 edges to Q, you would get a better TSP solution than P, which is not possible as P was the best.
As you are using google map, your particular instance of TSP might satisfy the Triangle inequality.
Are you really speaking of distances or travel time ?
In the case of distances:
try Googling: "triangle traveling salesman problem"
IMPORTANT: The result is a very good approximation of the best result with guaranteed uper bound, not always the best.
One way to go would be using (self-organized) kohonen networks.
Assume you have n cities on a map (works the same in any dimension).
Take a chain of n connected "neurons" and place it randomly on the map.
Then you do several iterations, one iteration contains:
choose any city. (e.g. go through them in a ordered fashion)
determine the "closest" neuron, call it x. (e.g. euclidian distance)
Move this x closer to the city (e.g. take the direction vector from the neuron to the city and multiply it with a learning rate 0
Move neighbors of this neuron also towards this city (but less than in 3., dependend of distance from the neighbors to the "current closest" neuron x)
One can choose various functions in step 2, 3 and 4.
Notice also that this might not give the globally shortest path since it depends on where the start chain is located and different other things. For this on may consider doing several runs with different starting conditions or (depending of the problem) one can help a bit with pre-knowlege.
I hope this helps to complete this question for further readers...
I am trying to get the current traffic conditions at a particular location. The GTrafficOverlay object mentioned here only provides an overlay on an existing map.
Does anyone know how I can get this data from Google using their API?
It is only theorical, but there is perhaps a way to extract those data using the distancematrix api.
Method
1)
Make a topological road network, with node and edge, something like this:
Each edge will have four attributes: [EDGE_NUMBER;EDGE_SPEED;EDGE_TIME,EDGE_LENGTH]
You can use the openstreetmap data to create this network.
At the begining each edge will have the same road speed, for example 50km/h.
You need to use only the drivelink and delete the other edges. Take also into account that some roads are oneway.
2)
Randomly chose two nodes that are not closer than 5 or 10km
Use the dijsktra shortest path algorithm to calculate the shortest path between this two nodes (the cost = EDGE_TIME). Use your topological network to do that. The output will look like:
NODE = [NODE_23,NODE_44] PATH = [EDGE_3,EDGE_130,EDGE_49,EDGE_39]
Calculate the time needed to drive between the two nodes with the distance matrix api.
Preallocate a matrix A of size N X number_of_edge filled with zero value
Preallocate a matrix B of size 1 X number_of_edge filled with zero value
In the first row of matrix A fill each column (corresponding to each edge) with the length of the edge if the corresponding edge is in the path.
[col_1,col_2,col_3,...,col_39,...,col_49,...,col_130]
[0, 0, len_3,...,len_39,...,len_49,...,len_130] %row 1
In the first row of matrix B put the time calculated with the distance matrix api.
Then select two news node that were not used in the first path and repeat the operation until that there is no node left. (so you will fill the row 2, the row 3...)
Now you can solve the linear equation system: Ax = B where speed = 1/x
Assign the new calculated speed to each edge.
3)
Iterate the point 2) until your calculated speed start to converge.
Comment
I'm not sure that the calculated speed will converge, it will be interesting to test the method.I will try to do that if I got some time.
The distance matrix api don't provide a traveling time more precise than 1 minute, that's why the distance between the pair of node need to be at least 5 or 10 or more km.
Also this method fails to respect the Google's terms of service.
Google does not make available public API for this data.
Yahoo has a feed (example) with traffic conditions -- construction, accidents, and such. A write-up on how to access it is here.
If you want actual road speeds, you will probably need to work with a commercial provider.