1

私の目標は、100m ごとにインデータをダウンサンプリングし、最初と最後の行を取得することです

私の問題は、ダウンサンプリングするときに本来よりもはるかに少ない行を取得し、最後の行を取得する方法がわからないことです。

誰かが理解できるほど明確であることを願っています

To make this
Line 20130904_0848.nmea
$GPGGA,111936.00,5849.37538,N,01739.88263,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*42
$GPGGA,111936.00,5849.37548,N,01739.88240,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*44
$GPGGA,111936.00,5849.37556,N,01739.88216,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*48
$GPGGA,111936.00,5849.37569,N,01739.88193,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*4a
$GPGGA,111936.00,5849.37581,N,01739.88171,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*40
$GPGGA,111936.00,5849.69118,N,01739.89674,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*4c
EOL 

Line 20130904_0926.nmea
$GPGGA,111936.00,5849.67569,N,01739.98426,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*45
$GPGGA,111936.00,5849.67593,N,01739.98453,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*42
$GPGGA,111936.00,5849.67616,N,01739.98479,,E,2,09,00.9,00004.43,M,0024.87,M,007,0734*44
....

Look like this

Line 20081002-1119.nmea
58.853952   13.309779   0.00
58.853907   13.310688   101.15
58.853858   13.311593   100.72
58.853811   13.312498   100.62
58.853764   13.313402   100.59
58.853752   13.313660   28.70

EOL

Line 20081002-1119.nmea
58.853952   13.309779   0.00
58.853907   13.310688   101.15
58.853858   13.311593   100.72
58.853811   13.312498   100.62
58.853764   13.313402   100.59
...

これはこれまでの私のコードです

from math import sin, cos, sqrt, atan2, radians

coord=[]
coord1=None
def distance(coord1,coord2): #Haversin
    lat1,lon1=coord1
    lat2,lon2=coord2
    dlat = radians(lat2-lat1)
    dlon = radians(lon2-lon1)
    a = sin(dlat/2) * sin(dlat/2)
    + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)*sin(dlon/2)
    c = 2 *atan2(sqrt(a),sqrt(1-a))
    s = (6367*c)*1000 #meter
    return s

# with open as data will close itself after reading each line. so you don't need to close it yourself

with open('asko_nav_2013.nmea', 'r') as indata:         #making a indata and outdata, r stands for reading(readcapabilities
    with open('asko_nav_out.txt', 'w') as outdata:      #w stands for write write to a new file(open for writing-you can change things)


        while True:
            line = indata.readline()
            if not line:
                break
            if line.startswith('EOL'):  #if the line starts with EOL(end of line) it writes it in the output
                outdata.writelines("EOL")
                coord1=None
            elif line.startswith('Line'): 
                LineID=line
                outdata.writelines('\n%s' %LineID)
            elif line.startswith('$GPGGA'):  #when the fist line starts with $GPGGA it splits the columns
                data=line.split(",")        #the for loop reads the file line by line



            # Importing only coordinates from asko input file (Row 2 and 4)

                # Converting the coordinates from DDMM.MMMM to DD.DDDDDD
                LAT=(data[2])
                LAT_D=LAT[0:2]               
                LATID=float(LAT_D)

                LAT_M=LAT[2:]
                LATM=float(LAT_M)
                LATIM = float(LATM) / 60.0

                latitude=(LATID + LATIM)                  

                LON=(data[4])
                LON_D=LON[1:3]
                LONGD=float(LON_D)

                LON_M=LON[3:]
                LONM=float(LON_M)
                LONGM = float(LONM) / 60.0

                longitude=(LONGD + LONGM)

                if coord1 is None:

                # The first time through the loop "coord1" is None
                    outdata.writelines('%0.6f\t%0.6f\t%s \n'%(latitude,longitude,0))
                    coord1=(latitude,longitude)
                else:
                    coord2=(latitude,longitude)
                    dist=distance(coord1,coord2)

                    if dist <100:
                        continue
                    outdata.writelines('%0.6f\t%0.6f\t%f\n' % (latitude,longitude,dist))
                    coord1=coord2
4

2 に答える 2

0

コードを少し再編成して、より明確にすることができます。EOL距離が 100m 未満の場合は、 が表示されるたびに追加の書き込みを追加する必要があります。

from math import sin, cos, sqrt, atan2, radians    

def distance(coord1, coord2): #Haversin
    lat1,lon1=coord1
    lat2,lon2=coord2
    dlat = radians(lat2-lat1)
    dlon = radians(lon2-lon1)
    a = sin(dlat/2) * sin(dlat/2)
    + cos(radians(lat1))*cos(radians(lat2))*sin(dlon/2)*sin(dlon/2)
    c = 2 *atan2(sqrt(a),sqrt(1-a))
    s = (6367*c)*1000 #meter
    return s

def get_coordinates(data):
    # Importing only coordinates from asko input file (Row 2 and 4)
    # Converting the coordinates from DDMM.MMMM to DD.DDDDDD

    LAT = (data[2])
    LAT_D = LAT[0:2]               
    LATID = float(LAT_D)

    LAT_M = LAT[2:]
    LATM = float(LAT_M)
    LATIM = float(LATM) / 60.0

    latitude = (LATID + LATIM)                  

    LON = (data[4])
    LON_D = LON[1:3]
    LONGD = float(LON_D)

    LON_M = LON[3:]
    LONM = float(LON_M)
    LONGM = float(LONM) / 60.0

    longitude = (LONGD + LONGM)

    return (latitude, longitude)


coord1 = None

# with open as data will close itself after reading each line. so you don't need to close it yourself

with open('asko_nav_2013.nmea', 'r') as indata, open('asko_nav_out.txt', 'w') as outdata:
    for line in indata:
        if line.startswith('EOL'):  #if the line starts with EOL(end of line) it writes it in the output
            if dist < 100:
                outdata.write('%0.6f\t%0.6f\t%f\n' % (latitude, longitude, dist))
            outdata.write("\nEOL\n")
            coord1 = None   # Reset the first coordinate
        elif line.startswith('Line'): 
            outdata.write('\n%s' % line)
        elif line.startswith('$GPGGA'):  #when the fist line starts with $GPGGA it splits the columns
            data=line.split(",")        #the for loop reads the file line by line
            latitude, longitude = get_coordinates(data)

            if coord1:
                coord2 = (latitude, longitude)
                dist = distance(coord1, coord2)

                if dist >= 100:
                    outdata.write('%0.6f\t%0.6f\t%f\n' % (latitude, longitude, dist))
                    coord1 = coord2         
            else:
                # The first time through the loop "coord1" is None
                outdata.write('%0.6f\t%0.6f\t0.0 \n' % (latitude, longitude))
                coord1 = (latitude, longitude)

指定された入力に対して、これにより次の出力ファイルが生成されます。

Line 20130904_0848.nmea
58.822923   17.664710   0.0 
58.828186   17.664946   584.888514

EOL

Line 20130904_0926.nmea
58.827928   17.666404   0.0 
58.827936   17.666413   0.870480

EOL

また、最初のエントリで が再度表示されるように、が検出されるcoord1たびにリセットする必要があります。EOL0

サンプルデータが予想される出力と一致しないように見えるため、これで問題が完全に解決するかどうかを確認するのは少し困難です。

于 2015-11-13T11:05:01.933 に答える
0

予想より少ない結果行に関する 2 番目の問題への対処: 問題の性質と処理している入力データに関する情報が少なすぎます。「100m ごとに」入力をサンプリングすることは、移動するオブジェクトが移動する軌跡から入力データがサンプリングされる場合、特にモーションが純粋に線形でない場合、異なる意味になる可能性があります。

たとえば、半径 15m 未満の円に沿って移動しながら、一定の間隔で GPS 座標を測定することによって得られた座標が入力に記述されていると想像してください。入力が提供するデータ ポイントの数に関係なく、提案されたソリューションの出力が 2 ラインより長くなることはありません。これは、その曲線に沿った 2 つのポイントが 100 m を超える絶対距離を持つことはできないためです。これは、出力に表示される行数が予想よりも少ない理由を説明している可能性があります。

移動する 100 m ごとに入力をサンプリングする場合は、最後に出力用にサンプリングされたポイント以降の入力サンプル間のすべての距離を合計し、代わりにそれを使用する必要がありdistます。Martin の再編成されたコードを変更すると、次のようになります (簡潔にするために一部の行は省略されています)。

coord1 = None
coord_last = None  # holds coordinate of last input sample
dist = 0.0         # total distance travelled since coord1
# [...]
with open('asko_nav_2013.nmea', 'r') as indata, open('asko_nav_out.txt', 'w') as outdata:
    for line in indata:
    # [...]
            if coord1:
                coord2 = (latitude, longitude)
                delta = distance(coord_last, coord2)
                dist += delta
                coord_last = coord2

                if dist >= 100:
                    outdata.write('%0.6f\t%0.6f\t%f\n' % (latitude, longitude, dist))
                    coord1 = coord2
                    dist = 0.0
            else:
                # The first time through the loop "coord1" is None
                outdata.write('%0.6f\t%0.6f\t0.0 \n' % (latitude, longitude))
                coord1 = (latitude, longitude)
                coord_last = coord1
                dist = 0.0
于 2015-11-13T14:43:17.547 に答える