Python - 将 GPS 位置批量转换为经纬度小数

Posted

技术标签:

【中文标题】Python - 将 GPS 位置批量转换为经纬度小数【英文标题】:Python - Batch convert GPS positions to Lat Lon decimals 【发布时间】:2012-06-01 15:16:15 【问题描述】:

您好,我有一个带有一些位置数据的旧数据库。这些字段只是带有类似0°25'30"S, 91°7'W 的字符串的文本字段。有什么方法可以将它们转换为Decimal LatitudeDecimal Longitude 的两个浮点数?

编辑:

所以一个例子是:0°25'30"S, 91°7'W -> 0.425, 91.116667 其中原始的单个字段位置产生两个浮点数。

非常感谢任何帮助。

【问题讨论】:

您提供的坐标对应的输出是什么。此外,纬度有 3 个数字字段,经度 2 .. 是如何指定这些字段的典型值(并且在您的数据中是常量)?到目前为止,您尝试过什么? 所以我想生成浮点数:0°25'30"S, 91°7'W -> 0.425, 91.116667。看起来数据可能有也可能没有相关的分钟数。如果没有,那么我可以假设为 0。 经度 180 W = -180 180 E = 180 纬度 90 N = 90 90 S = -90 示例必须给出 -0.425,-91.116667。例如,通过在 Google 地图中搜索 0°25'30"S、91°7'W 来检查这一点。 【参考方案1】:

这种方法可以处理秒和分钟的缺失,我认为可以正确处理指南针方向:

# -*- coding: latin-1 -*-

def conversion(old):
    direction = 'N':1, 'S':-1, 'E': 1, 'W':-1
    new = old.replace(u'°',' ').replace('\'',' ').replace('"',' ')
    new = new.split()
    new_dir = new.pop()
    new.extend([0,0,0])
    return (int(new[0])+int(new[1])/60.0+int(new[2])/3600.0) * direction[new_dir]

lat, lon = u'''0°25'30"S, 91°7'W'''.split(', ')
print conversion(lat), conversion(lon)
#Output:
0.425 91.1166666667

【讨论】:

+1 不让我头疼……“简单胜于复杂。” 几乎完美...方向相反...direction = 'N':1, 'S':-1, 'E': 1, 'W':-1 如何更改此27°29'04.2"N 89°19'44.6"E的代码【参考方案2】:

这会将您的输入字符串转换为您的预期输出。它可以处理不存在的分钟和秒。

目前,它不考虑北/南、东/西。如果您告诉我您希望如何处理这些问题,我会更新答案。

# -*- coding: latin-1 -*-
import re

PATTERN = re.compile(r"""(?P<lat_deg>\d+)°      # Latitude Degrees
                         (?:(?P<lat_min>\d+)')? # Latitude Minutes (Optional)
                         (?:(?P<lat_sec>\d+)")? # Latitude Seconds (Optional)
                         (?P<north_south>[NS])  # North or South
                         ,[ ]
                         (?P<lon_deg>\d+)°      # Longitude Degrees
                         (?:(?P<lon_min>\d+)')? # Longitude Minutes (Optional)
                         (?:(?P<lon_sec>\d+)")? # Longitude Seconds (Optional)
                         (?P<east_west>[EW])    # East or West
                      """, re.VERBOSE)

LAT_FIELDS = ("lat_deg", "lat_min", "lat_sec")
LON_FIELDS = ("lon_deg", "lon_min", "lon_sec")

def parse_dms_string(s, out_type=float):
    """
    Convert a string of the following form to a tuple of out_type latitude, longitude.

    Example input:
    0°25'30"S, 91°7'W
    """
    values = PATTERN.match(s).groupdict()

    return tuple(sum(out_type(values[field] or 0) / out_type(60 ** idx) for idx, field in enumerate(field_names)) for field_names in (LAT_FIELDS, LON_FIELDS))


INPUT = """0°25'30"S, 91°7'W"""

print parse_dms_string(INPUT) # Prints: (0.42500000000000004, 91.11666666666666)

【讨论】:

谢谢。让我看看我能用它做什么。【参考方案3】:

一个简单的方法(鉴于我今天因为这个问题自学了正则表达式)。处理缺失的字段和指南针方向。

# -*- coding: latin-1 -*-
import re
s = """0°25'30"S, 91°7'W"""

def compLat_Long(degs, mins, secs, comp_dir):
    return (degs + (mins / 60) + (secs / 3600)) * comp_dir

def extract_DegMinSec(data):   
    m = re.search(r'(\d+°)*(\d+\')*(\d+")*', data.strip())
    deg, mins, secs = [0.0 if m.group(i) is None else float(m.group(i)[:-1]) for i in range(1, 4)]
    comp_dir = 1 if data[-1] in ('W', 'S') else -1
    return deg, mins, secs, comp_dir 

s1, s2 = s.split(',')
dms1 = extract_DegMinSec(s1)
dms2 = extract_DegMinSec(s2)
print(':7.4f  :7.4f'.format(compLat_Long(*dms1), compLat_Long(*dms2)))

产量

 0.4250  91.1167

【讨论】:

【参考方案4】:

如果您的数据在 DataFrame 中,您可以使用库 DataPrep 中的函数 clean_lat_long()。使用 pip install dataprep 安装 DataPrep。

from dataprep.clean import clean_lat_long
df = pd.DataFrame("coord": ["""0°25'30"S, 91°7'W""", """27°29'04.2"N   89°19'44.6"E"""])

df2 = clean_lat_long(df, "coord", split=True)
# print(df2)
                        coord  latitude  longitude
0           0°25'30"S, 91°7'W   -0.4250   -91.1167
1  27°29'04.2"N\t89°19'44.6"E   27.4845    89.3291

【讨论】:

【参考方案5】:

试试这个,它一次只处理一个坐标(纬度或经度)。它能够返回坐标的有效结果,罗盘方向位于坐标的开头或结尾,“,”作为小数分隔符,如果无法解码输入,则返回原始字符串。

def dec(coord):
    c = coord.upper()
    s = 1
    if c.find('S')>0 or c.find('W')>0:
        s = -1
    c = c.replace('N','').replace('E','').replace('S','').replace('W','').replace(',','.').replace(u'°',' ').replace('\'',' ').replace('"',' ')
    a = c.split()
    a.extend([0,0,0])
    try:
        return s*(float(a[0])+float(a[1])/60.0+float(a[2])/3600.0) 
    except:
        return coord

【讨论】:

以上是关于Python - 将 GPS 位置批量转换为经纬度小数的主要内容,如果未能解决你的问题,请参考以下文章

怎样把GPS得到的经纬度转换为具体位置

如何将像素位置转换为 GPS 点?

将 GPS 坐标转换为纬度经度?

将 GPS 纬度/经度从不同格式转换为一种格式(在 PHP 中)

如何将 GPS 坐标转换为位置

GPS数据如何转换为高德地图的经纬度?