简体   繁体   English

Python-对点列表进行下采样,在列表中两个相邻点之间具有给定的坐标和距离

[英]Python - Downsampling of a list of points, with given coordinates and distance between two adjacent points in the list

I really hope someone can help me with this! 我真的希望有人可以帮助我! I'm trying to make this script run as I want, but I cannot seem to get the hang of it. 我试图使该脚本按我的意愿运行,但似乎无法掌握它。

The file with the data to be handled is input from a GPS and looks like this: 带有要处理的数据的文件是从GPS输入的,看起来像这样:

Line 20081002-1119.nmea
$GPGGA,094406.00,5849.40174,N,01738.15828,E,2,08,00.9,00003.26,M,0024.93,M,005,0734*62
$GPGGA,094407.00,5849.40177,N,01738.15827,E,2,08,00.9,00003.22,M,0024.93,M,005,0734*6B
$GPGGA,094408.00,5849.40174,N,01738.15826,E,2,08,00.9,00003.00,M,0024.93,M,006,0734*65
$GPGGA,094409.00,5849.40171,N,01738.15831,E,2,08,00.9,00003.24,M,0024.93,M,005,0734*62
$GPGGA,094410.00,5849.40176,N,01738.15833,E,2,08,00.9,00003.29,M,0024.93,M,006,0734*61
$GPGGA,094411.00,5849.40172,N,01738.15831,E,2,08,00.9,00003.31,M,0024.93,M,004,0734*6D
$GPGGA,094412.00,5849.40172,N,01738.15830,E,2,08,00.9,00003.15,M,0024.93,M,005,0734*68
$GPGGA,094413.00,5849.40175,N,01738.15834,E,2,08,00.9,00003.18,M,0024.93,M,005,0734*67
$GPGGA,094414.00,5849.40173,N,01738.15835,E,2,08,00.9,00003.16,M,0024.93,M,006,0734*6A
EOL

My output file should look like this (now with made up distances just to show what I want): 我的输出文件应该看起来像这样(现在为了显示我想要的东西已经补足了距离):

Line 20081002-1119.nmea
58.853952   17.643113   102.15 
58.853946   17.643243   101.63 
58.853939   17.643372   105.93 
58.853933   17.643503   104.01 
58.853927   17.643633   104.25 
...
EOL

The columns are: longitude, latitude, distance to the point above. 列为:经度,纬度,到上述点的距离。

How do I do to downsample this to a given interval between two points (100 meters in my case)? 如何将其下采样到两个点之间的给定间隔(本例中为100米)?

The script I've manged so far:` 到目前为止,我管理过的脚本:

indata=open('C:/nav.nmea', 'r')
outdata=open('C:/nav_out.txt', 'w')

from math import *

coords_list=[]
coords=[]

def distance(coords_list):
    for (longi2,lati2) in coords_list:
        for (longi1,lati1) in coords_list:
            a = sin(lati1) * sin(lati2)+cos(longi1-longi2)*cos(lati1) * cos(lati2)
            c= 2* asin(sqrt(a))

            s= (6367* c)/100000 # For results in meters

        if s<100:
            # Here I want to discard current line if not s<100 and jump to the next line
        else:
            "Return the valid lines"
    return s


for line in indata:

    if line.startswith('$GPGGA'):

        data=line.split(",")
        # Import only coordinates from input file

        LON=float(data[2])/100

        LAT=float(data[4])/100

        # Convert coordinates from DDMM.MMMM to DD.DDDDDD

        lon=((LON-int(LON))/60)*100+int(LON)

        lat=((LAT-int(LAT))/60)*100+int(LAT)

        coords_list.append((lon,lat))

        outdata.writelines("%0.6f\t" %lon)

        outdata.writelines("%0.6f\t" %lat)
        outdata.writelines("%s \n" %distance(coords_list))


    elif line.startswith('EOL'):

        outdata.writelines("EOL")

    elif line.startswith('Line'):

        LineID=line

        outdata.writelines('\n%s' %LineID)


indata.close()     

outdata.close() 

` `

For point reduction in a curve, you probably want to use the Ramer–Douglas–Peucker algorithm . 为了减少曲线上的点,您可能需要使用Ramer–Douglas–Peucker算法 This maintains the overall shape of the curve, but removes the detail, the amount removed can be controlled by a parameter. 这样可以保持曲线的整体形状,但是可以去除细节,可以通过参数控制去除量。

Note that the code on the linked Wikipedia page is pseudo code, and not python. 请注意,链接的Wikipedia页面上的代码是伪代码,而不是python。


I've found a python implementation of the DP line-simplication algorthim , I haven't tested it and can't vouch for its correctness. 我找到了DP行简化algorthimpython实现,但尚未测试,也无法保证其正确性。

Here is a fairly simple way to downsample the data: coord1 is used to store the previous coordinate. 这是一种对数据进行下采样的相当简单的方法: coord1用于存储先前的坐标。 Each time through the loop, the distance between coord1 and the new coordinate, coord2 , is computed. 每次通过循环,都会计算coord1和新坐标coord2之间的距离。 When the distance is <100, the rest of the loop is skipped. 当距离小于100时,将跳过循环的其余部分。

import math
import itertools

def distance(coord1,coord2):
    longi1,lati1=coord1
    longi2,lati2=coord2
    a = (math.sin(lati1)*math.sin(lati2)
         +math.cos(longi1-longi2)*math.cos(lati1)*math.cos(lati2))
    c = 2*math.asin(math.sqrt(a))
    s = (6367*c)/100000 # For results in meters
    return s

with open('nav.nmea', 'r') as indata:
    with open('nav_out.txt', 'w') as outdata:
        coords=[]
        coord1=None
        for line in indata:
            if line.startswith('$GPGGA'):
                data=line.split(",")
                # Import only coordinates from input file
                LON=float(data[2])/100
                LAT=float(data[4])/100
                # Convert coordinates from DDMM.MMMM to DD.DDDDDD
                lon=((LON-int(LON))/60)*100+int(LON)
                lat=((LAT-int(LAT))/60)*100+int(LAT)
                coords.append((lon,lat))
                if coord1 is None:
                    # The first time through the loop `coord1` is None
                    outdata.write('%0.6f\t%0.6f\t%s \n'%(lon,lat,0))
                    coord1=(lon,lat)
                else:
                    coord2=(lon,lat)
                    dist=distance(coord1,coord2)
                    if dist<100:
                        # go back to the beginning of the loop
                        continue
                    outdata.write('%0.6f\t%0.6f\t%s \n'%(lon,lat,dist))
                    coord1=coord2
            elif line.startswith('EOL'):
                outdata.writelines("EOL")
            elif line.startswith('Line'):
                LineID=line
                outdata.writelines('\n%s' %LineID)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM