Home > Blockchain >  Python: Generating multiple lat/longs between two predetermined GPS points and saving to .csv file
Python: Generating multiple lat/longs between two predetermined GPS points and saving to .csv file

Time:08-06

My goal is to take 2 known GPS points (lat/long) and generate the lat/long between those 2 points in a straight line.

I found some code that gets me 90% of the way there:

import math
import csv

def getPathLength(lat1,lng1,lat2,lng2):
    '''calculates the distance between two lat, long coordinate pairs'''
    R = 6371000 # radius of earth in m
    lat1rads = math.radians(lat1)
    lat2rads = math.radians(lat2)
    deltaLat = math.radians((lat2-lat1))
    deltaLng = math.radians((lng2-lng1))
    a = math.sin(deltaLat/2) * math.sin(deltaLat/2)   math.cos(lat1rads) * math.cos(lat2rads) * math.sin(deltaLng/2) * math.sin(deltaLng/2)
    c = 2 * math.atan2(math.sqrt(a), math.sqrt(1-a))
    d = R * c
    return d

def getDestinationLatLong(lat,lng,azimuth,distance):
    '''returns the lat an long of destination point 
    given the start lat, long, aziuth, and distance'''
    R = 6378.1 #Radius of the Earth in km
    brng = math.radians(azimuth) #Bearing is degrees converted to radians.
    d = distance/1000 #Distance m converted to km
    lat1 = math.radians(lat) #Current dd lat point converted to radians
    lon1 = math.radians(lng) #Current dd long point converted to radians
    lat2 = math.asin(math.sin(lat1) * math.cos(d/R)   math.cos(lat1)* math.sin(d/R)* math.cos(brng))
    lon2 = lon1   math.atan2(math.sin(brng) * math.sin(d/R)* math.cos(lat1), math.cos(d/R)- math.sin(lat1)* math.sin(lat2))
    #convert back to degrees
    lat2 = math.degrees(lat2)
    lon2 = math.degrees(lon2)
    return[lat2, lon2]

def calculateBearing(lat1,lng1,lat2,lng2):
    '''calculates the azimuth in degrees from start point to end point'''
    startLat = math.radians(lat1)
    startLong = math.radians(lng1)
    endLat = math.radians(lat2)
    endLong = math.radians(lng2)
    dLong = endLong - startLong
    dPhi = math.log(math.tan(endLat/2.0 math.pi/4.0)/math.tan(startLat/2.0 math.pi/4.0))
    if abs(dLong) > math.pi:
         if dLong > 0.0:
             dLong = -(2.0 * math.pi - dLong)
         else:
             dLong = (2.0 * math.pi   dLong)
    bearing = (math.degrees(math.atan2(dLong, dPhi))   360.0) % 360.0;
    return bearing

def main(interval,azimuth,lat1,lng1,lat2,lng2):
    '''returns every coordinate pair inbetween two coordinate 
    pairs given the desired interval'''

    d = getPathLength(lat1,lng1,lat2,lng2)
    remainder, dist = math.modf((d / interval))
    counter = float(interval)
    coords = []
    coords.append([lat1,lng1])
    for distance in range(0,int(dist)):
        coord = getDestinationLatLong(lat1,lng1,azimuth,counter)
        counter = counter   float(interval)
        coords.append(coord)
    coords.append([lat2,lng2])
    return coords

if __name__ == "__main__":
    #point interval in meters
    interval = 1.0
    #direction of line in degrees
    #start point
    lat1 = 58.294858
    lng1 = -148.200708
    #end point
    lat2 = 58.276672
    lng2 = -148.188580
    azimuth = calculateBearing(lat1,lng1,lat2,lng2)
    print (azimuth)
    coords = main(interval,azimuth,lat1,lng1,lat2,lng2)
    print (coords)
    header = ['Lat','Long']
    data = [coords]
    with open('Y:/Gulf of Alaska IYS/IYS Data_Feb-Apr_2022/gps/Gretel_Coords_test.csv', 'w', encoding='UTF8', newline='') as f:
            writer = csv.writer(f)
            writer.writerow(header)
            writer.writerow(data)
       

the headers on the csv file this generates is fine but the lat/long is printed on one row. What I'm trying to accomplish is for these generated GPS points to be recorded in a new row each time and for lat/long to be in 2 separate columns. Help

CodePudding user response:

coords is already a list of x-y coordinate pairs, but then you put it into another list with the line data = [coords], so then when you call writer.writerow(data), it will just dump the entire list as a single row of data.

What you want is to call csv.writerows (notice the plural, it's designed to write multiple rows instead of one) with coords, like in this version of your __main__ block.

if __name__ == "__main__":
    #point interval in meters
    interval = 1.0
    #direction of line in degrees
    #start point
    lat1 = 58.294858
    lng1 = -148.200708
    #end point
    lat2 = 58.276672
    lng2 = -148.188580
    azimuth = calculateBearing(lat1,lng1,lat2,lng2)
    #print (azimuth)
    coords = main(interval,azimuth,lat1,lng1,lat2,lng2)
    #print (coords)
    header = ['Lat','Long']
    with open('Y:/Gulf of Alaska IYS/IYS Data_Feb-Apr_2022/gps/Gretel_Coords_test.csv', 'w', encoding='UTF8', newline='') as f:
        writer = csv.writer(f)
        writer.writerow(header)
        writer.writerows(coords)

And I get this in the resulting CSV file:

❯ head -n10 coords.csv
Lat,Long
58.294858,-148.200708
58.294849522637115,-148.20070234510936
58.294841045273984,-148.20069669022146
58.29483256791059,-148.20069103533626
58.294824090546946,-148.2006853804538
58.29481561318306,-148.200679725574
58.294807135818935,-148.20067407069692
58.29479865845454,-148.20066841582255
58.294790181089915,-148.20066276095088

# etc.
  • Related