Graph line from GPS points

I have about 100 lists of gps coordinates and I want to draw a line that each of these lists make.

One of the scatter-plotted lists looks something like this:

gps points

Clearly there is a line in there;

I tried several methods for sorting gps positions and plotting them:

lats = []
lngs = []
with open(filename) as f:
    for line in f:
        lat, lng = line.split("\t")
        lats.append(float(lat))
        lngs.append(float(lng))

def sort_positions(position):
    return position[0]+position[1]

positions= zip(lngs, lats)
positions = sorted(poss, key=sort_positions)
for i, positionin enumerate(positions):
    lng, lat = position
    #plt.scatter(lng, lat)
    try:
        n_lng, n_lat = positions[i+1]
        plt.plot((lng, n_lng),(lat, n_lat), "b")
    except IndexError:
        pass

plt.show()

      

Sorted by longitude

def sort_positions(position):
    return position[0]

      

Longitude Sort

Sorted by latitude

def sort_positions(position):
    return position[1]

      

Latitude Sort

Sort by summing both

def sort_positions(position):
    return position[0]+position[1]

      

Sommation Sort

If the line is mostly straight on one of the axes (latitude / longitude) it looks good (some small bumps are still displayed)

Here's one of the lists that do fine sorting by sorting by latitude.

Latitude Sort 2

I only plan if the distance between the two points was less than 200 ~ 500 meters, but I get holes in the rows as some data is missing there.

Distance

Perhaps I am doing it wrong. Does anyone know how to construct these lines correctly?

EDIT:

In response to the rth

answer:

Two Approachs

The blue line uses its own approach in these questions, the red one uses this method in its other answer .

Ignoring the fact that red closes the loop.

There are some limitations in both cases: firstly, red cannot handle too many points, I had to use 1/90 points for both, blue generates some strange sharp turns when the points are too (dark spots in the image), and red is some strange curves in these places.

+3


source to share


3 answers


The easiest thing to do here is to figure out why the GPS coordinates were involved in the first place and fix it.

If this is not possible, the only thing I can think of is an iterative algorithm that takes an xy point and decides, based on some criteria (like distance, directions of consecutive points, etc.) which should go further.

Something along these lines

import numpy as np
from scipy.spatial.distance import pdist, squareform

def find_gps_sorted(xy_coord, k0=0):
    """Find iteratively a continuous path from the given points xy_coord,
      starting by the point indexes by k0 """      
    N = len(xy_coord)
    distance_matrix = squareform(pdist(xy_coord, metric='euclidean'))
    mask = np.ones(N, dtype='bool')
    sorted_order = np.zeros(N, dtype=np.int)
    indices = np.arange(N)

    i = 0
    k = k0
    while True:
        sorted_order[i] = k
        mask[k] = False

        dist_k = distance_matrix[k][mask]
        indices_k = indices[mask]

        if not len(indices_k):
            break

        # find next unused closest point
        k = indices_k[np.argmin(dist_k)]
        # you could also add some criterion here on the direction between consecutive points etc.
        i += 1
    return sorted_order, xy_coord[sorted_order]

      

which you could use like



 xy_coord = np.random.randn(10, 2)
 sorted_order, xy_coord_sorted = find_gps_sorted(xy_coord, k0=0)

      

enter image description here

although this may need to be expanded.

For example, you could say that in addition to the closest distance criteria, you don't want the trajectory to rotate more than 90 ° (if that's what makes sense for buses) and ignores those points on each iteration. Basically, you can add enough constraints to this algorithm to get the result you are looking for.

Change: . Since GPS coordinates have some uncertainty, the last step could be to smooth the resulting trace using B-spline interpolation using scipy.interpolate.splprep

and play with the argument s

(see related questions (1) , (2) )

+3


source


I suspect that all the (nice but) weird plots (except the first one) are due to the fact that you are trying to sort something that doesn't allow alphabetical ordering.

There is no reason to plot each line segment separately. Try to do only:

plt.plot(lngs, lats, 'b')

      



Here's a sample track I plotted: I didn't scale the horizontal and vertical axes correctly, so the graph is stretched vertically (too tall).

enter image description here

0


source


put each coordinate in an array (lat, long). put all the coordinates in another array collection (array1, array2, ... arrayn)

sort the sort array and then the graph.

-1


source







All Articles