该程序转换坐标。我想做的是
我的文件(worksheet.csv)具有三列,即纬度,经度和高度。
我将如何处理?
import math
import csv
# semi-major axis of earth
a = 6378137.0
# 1/f is reciprocal of flatteing
f= 0.00335281068
# converts the input from degree to radians
latitude = math.radians(float(input('Enter Latitude:')))
longitude = math.radians(float(input('Enter Longitude:')))
height = float(input('Enter Height:'))
def earthConverter(latitude, longitude, height):
e = math.sqrt((2 * f) - (f**2))
N = a / math.sqrt(1-e**2 * math.sin(latitude)**2)
x = (N + height) * math.cos(latitude) * math.cos(longitude)
y = (N + height) * math.cos(latitude) * math.sin(longitude)
z = (N * (1 - e**2 ) + height) * math.sin(latitude)
return x, y, z
############################################
with open('worksheet.csv', 'r') as csvFile:
reader = csv.reader(csvFile)
for row in reader:
writer = csv.writer(csvFile)
writer.writerow(row[0], row[1], row[2], earthConverter(math.radians(float(row[0])),
earthConverter(math.radians(float(row[1])), earthConverter(float(row[2])) )
csvFile.close()
答案 0 :(得分:2)
您已经很接近了,但是有几件事需要更改。我认为这是一个完整的解决方案,但是下面我将研究代码的每个部分
import math
import csv
def earthConverter(latitude, longitude, height):
f = 0.00335281068
a = 6378137.0
e = math.sqrt((2 * f) - (f**2))
N = a / math.sqrt(1-e**2 * math.sin(latitude)**2)
x = (N + height) * math.cos(latitude) * math.cos(longitude)
y = (N + height) * math.cos(latitude) * math.sin(longitude)
z = (N * (1 - e**2 ) + height) * math.sin(latitude)
return x, y, z
with open('worksheet.csv', 'r') as Infile, open('worksheet_out.csv', 'w') as Outfile:
reader = csv.reader(Infile)
# next(reader, None)
writer = csv.writer(Outfile)
for row in reader:
lat = math.radians(float(row[0]))
lon = math.radians(float(row[1]))
ht = math.radians(float(row[2]))
x, y, z = earthConverter(lat, lon, ht)
row_out = [row[0], row[1], row[2], x, y, z]
writer.writerow(row_out)
首先,您可以将f
和a
的定义移到earthConverter
函数本身中,以避免variable scoping的任何可能的问题。这不是绝对必要的。
第二,您可以摆脱latitude = math.radians(float(input('Enter Latitude:')))
行。这些请求用户输入,这不是您想要的。
第三,您不能写回同一csv。您已经以读取模式('r'
)打开了它,但是即使您进行了更改,this post也提供了一些有关为何不起作用/不是一个好主意的详细信息。您也可以在代码末尾省去单独的调用以关闭csv的方法-with open()
的构造会为您解决这个问题。
第四,您的earthConverter
函数返回一个元组,因此您需要以某种方式解压缩这些值,然后再尝试将其写出。
for row in reader:
块中的所有内容都可以压缩为更少的行。我以这种方式将其分解,因为它使阅读起来更容易。
此外,您没有提及输入的csv是否具有标头。如果是这样,则取消注释行next(reader, None)
的注释,这将跳过标题。如果您需要再次写出标题,则可以将for row in reader:
块更改为此:
for i, row in enumerate(reader):
if i == 1:
header_out = ['lat', 'lon', 'ht', 'x', 'y', 'z'] # or whatever
writer.writerow(header_out)
lat = math.radians(float(row[0]))
lon = math.radians(float(row[1]))
ht = math.radians(float(row[2]))
x, y, z = earthConverter(lat, lon, ht)
row_out = [row[0], row[1], row[2], x, y, z]
writer.writerow(row_out)
答案 1 :(得分:0)
所有您需要做的就是创建一个数据框以读取csv文件,并创建一个for循环以遍历每一行,然后将其插入新的数据框。然后,让熊猫库将其导出到新的csv文件中。
import pandas as pd
import math
# semi-major axis of earth
a = 6378137.0
# 1/f is reciprocal of flatteing
f = 0.00335281068
def earthConverter(latitude, longitude, height):
e = math.sqrt((2 * f) - (f**2))
N = a / math.sqrt(1-e**2 * math.sin(latitude)**2)
x = (N + height) * math.cos(latitude) * math.cos(longitude)
y = (N + height) * math.cos(latitude) * math.sin(longitude)
z = (N * (1 - e**2 ) + height) * math.sin(latitude)
return x, y, z
def new_csv(input_file, output_file):
df = pd.read_csv(input_file)
points_df = pd.DataFrame(columns=['Latitude', 'Longitude', 'Height'])
for i, row in df.iterrows():
x1, y1, z1 = earthConverter(row['Latitude'], row['Longitude'], row['Height'])
temp_df = pd.DataFrame({'Latitude': x1,
'Longitude': y1,
'Height': z1}, index=[0])
points_df = points_df.append(temp_df, ignore_index=True)
points_df.to_csv(output_file)
new_csv('worksheet.csv', 'new_worksheet.csv')