0

I have two kinds of geographical coordinates.
One is target points and another is measured points by GPS.

I can draw line and points like the following image:

sample image

These black points are measured points and white points are target points.

So, I'd like to calculate the distance between the measured points and the line which is made by target points. But importantly, the both points includes going backward points. I mean that it'is like a returning path.

I read this article -- Calculating the distance between a point and a virtual line of two lat/lngs but my coordinates includes so many points. And the interval of points is not fixed.

Therefor, I think that I should use for loop something like that. I'd like to know how far between points and line.

How can I calculate the distance?

yyykkkyyy
  • 35
  • 9

1 Answers1

0

Here is how I would structure my algorithm. I am assuming the target points and the measured points are 'linear' (that I don't go backwards at any point).

Step 1: Defining the virtual segments

You know from Calculating the distance between a point and a virtual line of two lat/lngs how to determine the distance of a point from a virtual line. So you can think of your list of target points instead as a series of virtual lines. Assuming your target points are provided in an array of x,y pairs targetCoords, if you have n = len(targetCoords) target points, then you will have n-1 virtual segments.

For each point in your target points, determine it's distance from the next target point. You can do this with a simple list comprehension:

targetPointDistances = [(Dist(Coords2,Coords1) for Coords1, Coords2 in zip(targetCoords[:-1], targetCoords[1:])]

"Dist" is a user defined function to determine the distance between coordinate pairs. This question gives an example of how to easily implement this, while this question gives detail on the more precise Vincenty formula.

Step 2: Determining the current virtual segment

You want to start looking at each measured point, and comparing it's distance from a virtual segment. For each point, you want to check that you're still comparing it to the proper virtual segment.

So, check that you're in the correct segment before doing each distance determination. Let's try this:

targetSegment = 0
for point in measuredPoints:
    while Dist(point, targetCoords[targetSegment+2]) < targetPointDistances[targetSegment+1]:
        targetSegment += 1

For each point, I'm checking to see if its distance from the end point of the next segment is less than the length of the current segment. If this is true, I start comparing it to the next virtual segment. (Extra credit: are there any cases where this won't work, or would be suboptimal?)

In your example image, this leaves the first 4 measured points in the first segment. The fifth measured point is closer to the third target point than the second target point is to the third target point, so we advance to the next virtual segment.

Step 3: Calculate the distance from the virtual line

This seems to be pretty straightforward - you already linked to this!

Just use targetCoords[targetSegment] and targetCoords[targetSegment+1] as the starting and ending points for your virtual line. This can be part of the for loop in step 2!

  • 1
    Thank you very much for your comment !! The thing I cannot understand is the step 1. Is "Dist(Coords2,Coords1)" the user difined function ? And, I'm a very newbie, so I haven't understood clearly the list comprehension. Could you tell me more about the step 1 ? – yyykkkyyy Oct 16 '18 at 02:45
  • @yyykkkyyy yes, I have created a user defined function. I've updated the question with a link (https://stackoverflow.com/questions/5228383/how-do-i-find-the-distance-between-two-points/5230380) that should be helpful here. – Peanut Butter Vibes Oct 16 '18 at 02:49
  • 1
    Thanks for your reply. I can understand the Dist function. I have another question. All of the coordinates are geographical coordinates. So when I calculate the distance, should I use pyproj ? – yyykkkyyy Oct 16 '18 at 03:00
  • good question! It depends on the processing power you have available, and the distance you're covering, and the precision you need. If you're looking at distances around your city block and don't need high precision, you can do a simple distance determination (Pythagorean Theorem). You may want to read more about the Vincenty formula (https://gis.stackexchange.com/questions/84885/whats-the-difference-between-vincenty-and-great-circle-distance-calculations) – Peanut Butter Vibes Oct 16 '18 at 03:05
  • I'm assuming you're inputting your target coordinates as a list of coordinates. The brackets get the item at the index. Your virtual line is made up of virtual line segments from point to point. The first segment is the line from the first target coordinates (targetCoordinates[0]) to the second target coordinates (targetCoordinates[1]). The length of this line is the first value in targetPointDistances (targetPointDistances[0]). – Peanut Butter Vibes Oct 16 '18 at 03:20
  • 1
    Oh, sorry I understand ! – yyykkkyyy Oct 16 '18 at 03:32
  • I cannot still understand about step 2. Why the fifth measured point is closer to the third target point ? I cannot understand the logic of step 2. – yyykkkyyy Oct 16 '18 at 03:47
  • I've cleaned up the explanation a bit, can you try rereading this and trying again? I'm using the distance of the measured point from the end point to determine the best virtual segment. The snippets here are pseudocode, there are a few edge cases here which you should check for. – Peanut Butter Vibes Oct 16 '18 at 23:02
  • Thank you for your reply ! I understand the logic of this program. But my target points include duplicated points. so, targetPointDistances includes a lot of 0. I tried the code, but in step 2, I cannot advance the segment because targetPointDistances[targetSegment+1] is always 0. Can I solve this problem ? – yyykkkyyy Oct 17 '18 at 00:39
  • I use if statement to exclude 0 targetPointDistances[targetSegment+1]. If targetPointDistances[targetSegment+1] IS 0, increment. And if targetPointDistances[targetSegment+1] is NOT 0, do step 2. Is this processing wrong ? If you have better solution, I'd like to know it. – yyykkkyyy Oct 17 '18 at 01:21
  • I think it may be best to edit the original question to include the problematic datapoints in the example. Can you do this? – Peanut Butter Vibes Oct 17 '18 at 20:51
  • Of course. I changed the sample image. Please show that. – yyykkkyyy Oct 18 '18 at 01:50
  • it sounds like if you clean your targetPoints to remove duplicates, this should fix your problem. – Peanut Butter Vibes Oct 18 '18 at 03:03
  • Is this solution able to calculate the returning path as well ? – yyykkkyyy Oct 18 '18 at 05:21