Extract coordinates from rows and get distance

#Python
I have a file that contains station latitude and longitude with elevation as shown below:

 sta        long        lat  elevation
0   ML39  104.498783  29.474033        420
1   ML03  104.476017  29.476300        492
2   ML01  104.474617  29.476233        471
3   ML02  104.475450  29.476400        489
4   ML04  104.476317  29.476517        499
..   ...         ...        ...        ...
71  ML76  104.523467  29.477933        360
72  ML77  104.524100  29.477917        375
73  ML78  104.524933  29.477633        397
74  ML79  104.526317  29.477483        375
75  ML80  104.527400  29.478117        369

I want to calculate the distance between each lat and long in two consecutive rows, I use these commands to do it for a single value but I am not sure how can I run a loop to extract lat and long from each row and get distance with respect to next line.

dist_m,_,_=gps2dist_azimuth(29.478383,104.481117,29.478483,104.481717,)
print (dist_m,_,_)

How can we run a loop to calculate the distance between each lat and long in rows?

Hi @aqeelkhan14125,

I've moved your topic to the Programming category.

In order to be able to handle two consecutive lines at a time, you have to remember the previous line:

with open('infile') as ifile:
    # skip header
    ifile.readline()
    # old data line
    d0 = None
    for d1 in ifile:
        if d0:
            lon0, lat0 = d0.split()[2:4] # prev data
            lon1, lat1 = d1.split()[2:4] # actual data
            # get 1st element of returned tuple by the function
            dist_m = gps2dist_azimuth(lat0, lon0, lat1, lon1)[0]
        # set old line to actual one
        d0 = d1

_ is a throwaway variable, the value of which can be ignored. So it doesn't make sense to print it.

1 Like

Assuming Python is a procedural language, the following should work with syntax changes:

read prev_station prev_lat prev_long prev_elev
while read station lat long elev
do
distance = (lat - prev_lat) .......
print prev_station  "to" station distance
prev_station=station
prev_lat=lat
prev_long=long
prev_elev=elev...
done
1 Like

Thank you so much for your reply.
I tried this script but it seems there is something wrong. I didn't get any output and even errors.
I am sorry if I am doing some stupid mistake.

from obspy.geodetics import gps2dist_azimuth
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
with open("array_loc.txt", 'r') as ifile:
    # skip header
    ifile.readline()
    # old data line
    d0 = None
    for d1 in ifile:
        if d0:
            lon0, lat0 = d0.split()[2:4] # prev data
            lon1, lat1 = d1.split()[2:4] # actual data
            # get 1st element of returned tuple by the function
            dist_m= gps2dist_azimuth(lat0, lon0, lat1, lon1)[0]
            # set old line to actual one
            d0 = d1
            print(dist_m)

I am confused about parameter [2:4]
here is the data format without a header.

ML39 104.498783 29.474033 420
ML03 104.476017 29.476300 492
ML01 104.474617 29.476233 471
ML02 104.475450 29.476400 489
ML04 104.476317 29.476517 499
ML05 104.476783 29.476867 482
ML06 104.477400 29.476883 469
ML07 104.485067 29.477100 487
ML08 104.477600 29.477317 458
ML09 104.477683 29.477850 456
ML10 104.478367 29.477767 451
ML11 104.478867 29.477883 455
ML12 104.479383 29.478000 459
ML13 104.479883 29.478217 471

Hi @aqeelkhan14125,

if you don't get any output, the infile seems to be empty. Could you please post the output of

$ head -n3 array_loc.txt

sure, here is the head

ML39 104.498783 29.474033 420
ML03 104.476017 29.476300 492
ML01 104.474617 29.476233 471

well, that's a different format than in your first post, cause the 1st column is missing. In this case you have to replace [2:4] with [1:3].

1 Like

yes, I agreed with you, I modified the script accordingly but still seems, there is something wrong.
Maybe I am repeating some mistakes.

with open("array_loc.txt", 'r') as ifile:
    # skip header
    #ifile.readline()
    # old data line
    d0 = None
    for d1 in ifile:
        if d0:
            lon0, lat0 = d0.split()[1:3] # prev data
            lon1, lat1 = d1.split()[1:3] # actual data
            # get 1st element of returned tuple by the function
            dist = gps2dist_azimuth(lat0, lon0, lat1, lon1)[0]
            # set old line to actual one
            d0 = d1
            print(dist)

then please do the following:

$ head -n3 array_loc_txt > test.txt
# replace array_loc.txt by test.txt in the script
# insert the line 'print(d1)' before 'if d0:'
# start the script
1 Like

Yes, even without replacing, text3, I added print (d1) and I got the original file as below:
Maybe there is some errors in later part.

code:

with open("array_loc.txt", 'r') as ifile:
    # skip header
    ifile.readline()
    # old data line
    d0 = None
    for d1 in ifile:
        print(d1)
        if d0:
            lon0, lat0 = d0.split()[1:3] # prev data
            lon1, lat1 = d1.split()[1:3] # actual data
            # get 1st element of returned tuple by the function
            dist = gps2dist_azimuth(lat0, lon0, lat1, lon1)[0]
            # set old line to actual one
            d0 = d1
            print(dist)

only "d1"as putput

ML03 104.476017 29.476300 492

ML01 104.474617 29.476233 471

ML02 104.475450 29.476400 489

ML04 104.476317 29.476517 499

ML05 104.476783 29.476867 482

ML06 104.477400 29.476883 469

ML07 104.485067 29.477100 487

ML08 104.477600 29.477317 458

ML09 104.477683 29.477850 456

ML10 104.478367 29.477767 451

ML11 104.478867 29.477883 455

ML12 104.479383 29.478000 459

ML13 104.479883 29.478217 471

ML14 104.481117 29.478383 475

ML15 104.481717 29.478483 469

ML16 104.482533 29.478200 460

you have a wrong indentation in your version. I've seen that too late, sorry. Instead of

        if d0:
            ...
            # set old line to actual one
            d0 = d1
            print(dist)

it has to be

        if d0:
            ...
            print(dist)
        # set old line to actual one
        d0 = d1

In your version, the conditional if d0: never matches, cause d0 = d1 would only be set if d0 has some value, but that never happens. As you can see, indentation is essential in python :slight_smile:

1 Like