Python - Пакетное преобразование позиций GPS в десятичные дроби в лат-лонах

Привет, у меня есть устаревшая база данных с некоторыми позиционными данными. Поля - это просто текстовые поля с такими строками0°25'30"S, 91°7'W, Есть ли способ, которым я могу преобразовать их в два числа с плавающей запятой дляDecimal Latitude а такжеDecimal Longitude?

РЕДАКТИРОВАТЬ:

Вот пример:0°25'30"S, 91°7'W - & GT;0.425, 91.116667 где исходная позиция одного поля дает два числа с плавающей точкой.

Любая помощь высоко ценится.

 Renat Zaripov27 февр. 2014 г., 21:55
Долгота 180 W = -180 180 E = 180 Широта 90 N = 90 90 S = -90 Пример должен дать -0,425, -91,116667. Проверьте это, например, выполнив поиск по 0 & # xB0; 25 '30' S, 91 & # xB0; 7 'W в Картах Google.
 Darwin Tech01 июн. 2012 г., 17:30
Итак, я хочу сгенерировать с плавающей точкой:0°25'30"S, 91°7'W - & GT;0.425, 91.116667, Кажется, что данные могут иметь или не иметь связанные минуты. Там, где его нет, я могу принять 0.
 Levon01 июн. 2012 г., 17:27
Какой будет соответствующий вывод для предоставленной вами координаты. Кроме того, широта имеет 3 числовых поля, долгота 2 .. это типично для того, как они указаны (и постоянны в ваших данных)? что ты уже испробовал?

Ответы на вопрос(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

Этот подход может иметь дело с отсутствием секунд и минут, и я думаю, что правильно обрабатывает направления компаса:

# -*- 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
 01 июн. 2012 г., 20:41
+1 за то, что у меня не болит голова ... "Простое лучше, чем сложное."
 28 дек. 2013 г., 13:13
А если секунды в формате float?
 11 авг. 2015 г., 11:57
почти идеально ... направления поменялись местами ...direction = {'N':1, 'S':-1, 'E': 1, 'W':-1}
 02 июн. 2012 г., 03:02
Нет регулярных выражений = +1.

Это преобразует вашу входную строку в ожидаемый результат. Он может обрабатывать минуты и секунды, отсутствующие.

В настоящее время он не учитывает север / юг, восток / запад. Если вы скажете мне, как вам это нравится, я обновлю ответ.

# -*- 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)
 Darwin Tech01 июн. 2012 г., 18:43
Спасибо. Дайте мне посмотреть, что я могу сделать с этим, как есть.

Ваш ответ на вопрос