Search code examples
pythonpython-3.xmathgeolocationgeo

Calculating the distance between measured points and target line


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?


Solution

  • 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!