如何将度分秒转换为度小数

问题描述 投票:0回答:10

我以这种格式从 GPS 接收纬度和经度:

纬度 : 78°55'44.29458"N

我需要将此数据转换为:

纬度:78.9288888889

我在这里找到这段代码:link

import re

def dms2dd(degrees, minutes, seconds, direction):
    dd = float(degrees) + float(minutes)/60 + float(seconds)/(60*60);
    if direction == 'E' or direction == 'S':
        dd *= -1
    return dd;

def dd2dms(deg):
    d = int(deg)
    md = abs(deg - d) * 60
    m = int(md)
    sd = (md - m) * 60
    return [d, m, sd]

def parse_dms(dms):
    parts = re.split('[^\d\w]+', dms)
    lat = dms2dd(parts[0], parts[1], parts[2], parts[3])
 
    return (lat)

dd = parse_dms("78°55'44.33324"N )

print(dd)

它正在为这种格式工作

dd = parse_dms("78°55'44.33324'N" )

但它不适用于我的 datafromat。谁能帮我解决这个问题?

python parsing gis
10个回答
20
投票

这是我的一条线(很好,很好——也许是两行):)

import re
lat = '''51°36'9.18"N'''
deg, minutes, seconds, direction =  re.split('[°\'"]', lat)
(float(deg) + float(minutes)/60 + float(seconds)/(60*60)) * (-1 if direction in ['W', 'S'] else 1)

这输出

51.60255


16
投票

上面的函数(dms2dd)不正确。

实际(有错误):

如果方向 == 'E' 或方向 == 'N': dd *= -1

更正条件:

如果方向 == 'W' 或方向 == 'S': dd *= -1


9
投票

问题是秒 44.29458 在

.
处被分割。

您可以直接定义拆分字符(而不是 where not to split):

>>> re.split('[°\'"]+', """78°55'44.29458"N""")
['78', '55', '44.29458', 'N']

或者保留正则表达式并合并第 2 部分和第 3 部分:

dms2dd(parts[0], parts[1], parts[2] + "." + parts[3], parts[4])

更新:

你的方法调用

dd = parse_dms("78°55'44.33324"N )
是一个语法错误。添加结束
"
并转义另一个。或者对字符串定义使用三重引号:

parse_dms("""78°55'44.29458"N""")

4
投票

我知道这是一个老问题,但对于跟进的人来说,我只是想指出您的

dms2dd()
函数中关于小数符号的逻辑似乎不正确。你有:

if direction == 'E' or direction == 'N':
    dd *= -1

但是如果方向是本初子午线的西(W)或赤道的南(S),它应该只有负数。所以它应该是:

if direction == 'W' or direction == 'S':
    dd *= -1

这里引用了一篇详尽的指南:https://www.ubergizmo.com/how-to/read-gps-coordinates/

纬线的坐标代表北 赤道因为它是正的。如果数字是负数,则 代表赤道以南。

[...] 经线的坐标表示东 本初子午线因为它是积极的。如果数字是负数,则 代表本初子午线以西。


4
投票

你可以使用这个模块https://pypi.org/project/dms2dec/

将 DMS 转换为十进制。

用法

from dms2dec.dms_convert import dms2dec

dms2dec('''36°44'47.69"N''') # converts to dec
dms2dec('''3° 2'33.53"E''') # converts to dec

2
投票

我稍微修改了回复:

parts = re.split('[^\d\w\.]+', dms)

正如@Falko 所建议的那样,您可以使用双引号或转义引号字符

parse_dms("53°19\'51.8\"N")

0
投票

对于多个坐标,你可以在using pandas中读取它们。格式很重要 - 不应有任何空格。可以使用替换功能删除空格。输出可以很容易地保存为文本文件或电子表格。我只是打印它们进行验证并将小数点四舍五入到 4.

### read input file
df = pd.read_excel('dms.xlsx')

n = len(df)

for i in range(n):
  Lat_d = round(parse_dms(df.Lat[i].replace(" ", "")),4)
  Long_d = round(parse_dms(df.Long[i].replace(" ", "")),4)
  print(Lat_d, Long_d)

0
投票

如果您的数据在 DataFrame 中,您可以使用库 DataPrep

 中的函数 
clean_lat_long()。使用
pip install dataprep
.

安装 DataPrep
from dataprep.clean import clean_lat_long
df = pd.DataFrame({"Latitude": ["78°55'44.29458''N", "51°36'9.18''N"]})

df2 = clean_lat_long(df, lat_col="Latitude")
            Latitude  Latitude_clean
0  78°55'44.29458''N         78.9290
1      51°36'9.18''N         51.6026

0
投票

您可以简单地使用

pygeodesy
无论如何它对许多其他功能都很有用,例如查找坐标的中点,精确的距离和方位计算。

from pygeodesy import parse3llh, fstr

x = parse3llh('000° 00′ 05.31″W, 51° 28′ 40.12″ N')
print (fstr(x, prec=6))

结果

51.477811, -0.001475, 0.0

0
投票

https://github.com/medo-mi/dms-to-dd

import re

#Degrees Minutes Seconds to Decimal Degrees
def dms_dd(dd):
    dd = f"""{dd}"""
    dd = re.sub('[^a-zA-Z0-9. ]', '', dd)
    dd = dd.split(" ")
    return round(float(dd[0])+(float(dd[1])/60)+(float(dd[2])/3600), 8)
© www.soinside.com 2019 - 2024. All rights reserved.