11

I'm a logistics programmer, and I've been asked to figure out if a GPS point is "off route" where the route consists of a number of geospatial points (latitude,longitude).

What is the best algorithm for determining if a point is near the route? I will be using C# and SQL Server, but really that doesn't matter a whole lot if I know what algorithm to use.

I've considered

  1. Finding the two nearest points and determining if the area of the triangle is above a specific limit.
  2. Using vectors for all pairs of points and then checking to see if any of them are "similar" to the vector defined by the GPS point and the point I determine to be "next" in the route.

I don't have a mathematics degree, but I can probably handle about anything given the correct terms and a search engine.

I will have to make at least 4000 calculations an hour so using a mapping solution is probably not acceptable due to volume.

Doug Heeren
  • 143
  • 1
  • 7
  • What you've asked is an interesting question. That surface-area-of-a-triangle solution wouldn't work because two points that are very far apart would generate a triangle with a large surface area even when the point is only slightly off route. Not sure I have a better solution. Thanks for giving me something to think about. – Brian Willis Jan 18 '12 at 21:55
  • What version of SQL Server are you using? Do you have an attributes about the bus location other than lat/long? How about bus ID, route ID, etc that can be tied back to the correct road/route it should be on? – RyanKDalton Jan 19 '12 at 16:02
  • @RyanDalton 2005 unfortunately. As I understand it 2012 had some pretty nice features regarding spatial data. I'm not above using mongo or some other database, but that will end up being a bit more work to set up and maintain another database with real time information. – Doug Heeren Jan 19 '12 at 17:30
  • @BrianWillis Yeah that is why I posed the question. I figured that wouldn work. Neither would finding the distance of the GPS point to the lines involved. – Doug Heeren Jan 19 '12 at 17:32

5 Answers5

5

I will have to make at least 4000 calculations an hour so using a mapping solution is probably not acceptable due to volume.

In fact, this is a PERFECT example where a mapping solution would be beneficial. Not your traditional "look at a map and determine distance", but rather "let the database determine what is the closest route to your GPS point.

Since you say you are not opposed to using a different database, you could consider:

  1. SQL Server 2008, which has Spatial Database Engine functions, or
  2. PostgreSQL with the open-source PostGIS (spatial) extension, which has significantly more spatial analysis functions that MS SQL 2008.

Take a look at the PostGIS ST_Distance function or MS SQL Server 2008 STDistance function. This is a good blog entry that describes the benefits of SQL2005 vs SQL2008.

You might also consider reading (or asking more detailed mapping) posts over at gis.stackexchange. That whole group is dedicated to spatial analysis. Some good discussions for you to take a look at would be

Community
  • 1
  • 1
RyanKDalton
  • 1,271
  • 3
  • 14
  • 30
  • Thank you. I had a friend suggest gis.stackexchange to me as well. Speed is my concern with using a mapping solution. I have to a minimum of 4000 of these an hour. But you are right is is probably the most accurate solution. – Doug Heeren Jan 20 '12 at 21:54
4

Google for "Along-track distance" and you should find the formulas commonly used in aviation. Alternatively, the cross-track distance could also be what you want.

Has QUIT--Anony-Mousse
  • 76,138
  • 12
  • 138
  • 194
1

How about the following...

Iterate through all line segments

lineSegSlope = Calculate slope for each line segment

draw a pretend line from the point in question that intersects the current line segment. this is done by inverting the lineSegSlope and multiplying by -1 to get the new slope, then substitute your target point X, Y, and new slope into y-y1 = b * (x-x1). Your X goes into x1, your Y goes into Y1, and your newSlope goes into B.

make an equation for the line segment.

if you draw the two lines on top of each other, they should make an X where each corner is 90 degrees.

calculate the intersection of the two lines

calculate the distance between the intersection point and your new point. If it's greater than some tolerable value, the new point is too far.

this looks like a mess, but hopefully it should work.

mj_
  • 6,297
  • 7
  • 40
  • 80
  • The angle of the points on the route vs the point in question is what throws this off when I reasoned it out. If the line segment is far away from the point, but the angle of the two points of the route are such that the line is very near the point when extended it will produce an incorrect answer. I'm struggling to understand this a little though so I may have a wrong response with this. – Doug Heeren Jan 20 '12 at 22:03
  • I see what you're saying, good catch. I think in that case though, the actual ends of the line segments would be the closest points. You can then compute the distance from the target point to the line segment ends. Fun little problem you've got here. – mj_ Jan 23 '12 at 15:03
0

Can you take your existing route as a sequence of line segments in 2-D, then take your query point and find the closest point and the closest line segment? The distance to that closest point / line segment would be the distance you care about.

If you're sticking to relatively low latitudes (below 60 degrees) you might be able to treat latitude and longitude as if they were simply flat, as on a Mercator projection.

If not, then you could transform the coordinate system to be relative to a great circle running through some of the route points.

Unless you're dealing with millions of route points, you shouldn't have a problem with CPU time.

Mike Dunlavey
  • 40,059
  • 14
  • 91
  • 135
  • That is one of the formulas I've considered, but I've found instances where it just won't work depending on the shape of the route. Most of them aren't anywhere near a straight line and some of them double back on them selves. It gets even more complicated when time is involved, but I saved that for another question. – Doug Heeren Jan 19 '12 at 17:38
0

A naive approach would be to insert the new GPS point at various places along the route. Start by inserting it before your first point P0, then between your first and second points P0, and P1, and so on until you try inserting it as the last point. Each time you try inserting it at a location, compute the total distance for the circuit and save save the shortest total distance. This can be sped up by precomputing leg distances and storing that sum. Check the distance by subtracting the leg distance for the leg you are inserting the new point, and adding the new distance from the point P(n) to your GPS point to P(n+1). If that shortest total distance is within your tolerance level, the you can accept it.

This is probably not the "best" algorithm (depending on your definition of best) but it's O(n) on the number of points in your route for both time and space complexity. So unless you have an enormous number of points in your route, each check should be quite a bit less than a second, so this should be within your time requirements.

Also, be sure you use haversine distance equations when computing the distance between consecutive points on your route.

andand
  • 17,134
  • 11
  • 53
  • 79
  • Best to me is fast and accurate under a very large portion of the circumstances. The tolerance level in this situation will need to grow when the distance between points in the route is larger wouldn't it? – Doug Heeren Jan 20 '12 at 21:58