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.
