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.