Конвертировать DD (десятичные градусы) в DMS (градусы минуты и секунды) в Python?

Как конвертировать десятичные градусы в градусы, минуты, секунды в Python? Формула уже написана?

15 ответов

Это именно то, что divmod был изобретен для:

>>> def decdeg2dms(dd):
...   mnt,sec = divmod(dd*3600,60)
...   deg,mnt = divmod(mnt,60)
...   return deg,mnt,sec

>>> dd = 45 + 30.0/60 + 1.0/3600
>>> print dd
45.5002777778
>>> decdeg2dms(dd)
(45.0, 30.0, 1.0)

Вот моя обновленная версия, основанная на версии Пола Макгуайра. Этот должен правильно обрабатывать негативы.

def decdeg2dms(dd):
   is_positive = dd >= 0
   dd = abs(dd)
   minutes,seconds = divmod(dd*3600,60)
   degrees,minutes = divmod(minutes,60)
   degrees = degrees if is_positive else -degrees
   return (degrees,minutes,seconds)

Если вы хотите правильно обработать негативы, первая ненулевая мера будет установлена ​​как отрицательная. Это противоречит общепринятой практике - указывать все градусы, минуты и секунды как отрицательные ( Википедия показывает 40° 26,7717, -79° 56,93172 в качестве действительного примера обозначения градусов-минут, в котором градусы отрицательны, а минуты не имеют знака), и установка степеней как отрицательных не имеет никакого эффекта, если часть градусов равна 0. Вот функция, которая адекватно обрабатывает это, основываясь на функциях Пола МакГвайра и Баенса:

def decdeg2dms(dd):
    negative = dd < 0
    dd = abs(dd)
    minutes,seconds = divmod(dd*3600,60)
    degrees,minutes = divmod(minutes,60)
    if negative:
        if degrees > 0:
            degrees = -degrees
        elif minutes > 0:
            minutes = -minutes
        else:
            seconds = -seconds
    return (degrees,minutes,seconds)

Просто пара * 60 умножения и пара int усечения, то есть:

>>> decdegrees = 31.125
>>> degrees = int(decdegrees)
>>> temp = 60 * (decdegrees - degrees)
>>> minutes = int(temp)
>>> seconds = 60 * (temp - minutes)
>>> print degrees, minutes, seconds
31 7 30.0
>>> 

Это мой код Python:

def DecimaltoDMS(Decimal):
d = int(Decimal)
m = int((Decimal - d) * 60)
s = (Decimal - d - m/60) * 3600.00
z= round(s, 2)
if d >= 0:
    print ("N ", abs(d), "º ", abs(m), "' ", abs(z), '" ')
else:
    print ("S ", abs(d), "º ", abs(m), "' ", abs(z), '" ')

Улучшение ответа @chqrlie:

    def deg_to_dms(deg, type='lat'):
        decimals, number = math.modf(deg)
        d = int(number)
        m = int(decimals * 60)
        s = (deg - d - m / 60) * 3600.00
        compass = {
            'lat': ('N','S'),
            'lon': ('E','W')
        }
        compass_str = compass[type][0 if d >= 0 else 1]
        return '{}º{}\'{:.2f}"{}'.format(abs(d), abs(m), abs(s), compass_str)

Вот мой немного другой подход, который работает так же, как на моем HP Prime для положительных и отрицательных десятичных градусов ...

      def dms(deg):
    f,d = math.modf(deg)
    s,m = math.modf(abs(f) * 60)
    return (d,m,s * 60)

Знак лучше вернуть отдельно, чтобы его можно было использовать на выбор ('N', 'S') или же ('E', 'W'), например.

import math

def dd_to_dms(degs):
    neg = degs < 0
    degs = (-1) ** neg * degs
    degs, d_int = math.modf(degs)
    mins, m_int = math.modf(60 * degs)
    secs        =           60 * mins
    return neg, d_int, m_int, secs

Это пустая версия ответа PaulMcG с добавлением того, что она округляется до десятых долей секунды (вы можете изменить второй аргумент на функцию округления) и возвращает знак (-1 или 1) как отдельное значение (это облегчило задачу). для меня, чтобы обрабатывать значения широты/долготы). Основное отличие здесь заключается в том, что вы можете передать массив decimal_grades или одно двойное значение (обратите внимание, что если вы передаете список, вы получаете обратно список списков). Перед использованием убедитесь, что вас устраивает поведение округления, или вы можете его удалить.

      def to_dms(decimal_degrees):
    # convert degrees into dms and a sign indicator
    degrees = np.array(decimal_degrees)
    sign = np.where(degrees < 0, -1, 1)
    r, s = np.divmod(np.round(np.abs(degrees) * 3600, 1), 60)
    d, m = np.divmod(r, 60)
    # np.transpose([d, m, s]*sign)  # if you wanted signed results
    return np.transpose([d, m, s, sign])

# print("array test:", to_dms([101.816652, -101.816653]))
# array test: [[101. 48. 59.9000000000232831 1.] [101. 49. 0. -1.]]

Теперь мы можем использовать библиотеку LatLon...

https://pypi.org/project/LatLon/

>> palmyra = LatLon(Latitude(5.8833), Longitude(-162.0833)) # Location of Palmyra Atoll in decimal degrees
>> palmyra = LatLon(5.8833, -162.0833) # Same thing but simpler! 
>> palmyra = LatLon(Latitude(degree = 5, minute = 52, second = 59.88),
                     Longitude(degree = -162, minute = -4.998) # or more complicated!
>> print palmyra.to_string('d% %m% %S% %H') # Print coordinates to degree minute second
('5 52 59.88 N', '162 4 59.88 W')`
      # Program to convert degree to Degree, Minutes and Seconds
# Using try and except for int data validations
try:

    # Requesting input degree from user
    print ("degree to Degree Minutes seconds converter ". upper ())
    degree = float(input ("\nEnter Degree: "))
    
    # Casting input from float to int 
    degree_d = int(degree)
    
    # Working on minutes
    minute =60 * (degree - degree_d)
    minutes = int(minute)
    
    # Working on seconds
    second = 60 * (minute - minutes)
    # Rounding seconds to whole number 
    seconds= round(second)
    
    # print 
    print (f"\nThe Answer In Degree-Minutes-Seconds are: \n{degree_d}°{minutes}'{seconds}\"  ✓\n ") 


#Except

except ValueError:
    print ("Wrong Input ")

Использование fmod и округление, чтобы разделить градусы и дроби. Умножьте дробь на 60 и повторите, чтобы получить минуты и остаток. Затем умножьте эту последнюю часть на 60 снова, чтобы получить количество секунд.

Вы можете использовать функцию <tcode id="3161656"></tcode>из библиотеки DataPrep, если ваши данные находятся в DataFrame. Установите DataPrep с помощью pip install dataprep.

      from dataprep.clean import clean_lat_long
df = pd.DataFrame({"coord": [(45.5003, -122.4420), (5.8833, -162.0833)]})

df2 = clean_lat_long(df, "coord", output_format="dms")
# print(df2)
                 coord                        coord_clean
0  (45.5003, -122.442)  45° 30′ 1.08″ N, 122° 26′ 31.2″ W
1  (5.8833, -162.0833)  5° 52′ 59.88″ N, 162° 4′ 59.88″ W

Или, если широта и долгота находятся в отдельных столбцах:

      df = pd.DataFrame({"latitude": [45.5003, 5.8833], "longitude": [-122.4420, -162.0833]})

df2 = clean_lat_long(df, lat_col="latitude", long_col="longitude", output_format="dms")
# print(df2)
   latitude  longitude                 latitude_longitude
0   45.5003  -122.4420  45° 30′ 1.08″ N, 122° 26′ 31.2″ W
1    5.8833  -162.0833  5° 52′ 59.88″ N, 162° 4′ 59.88″ W

Мой подход:

      import sys
import math

dd = float(sys.argv[1])
f,d = math.modf(dd)
f,m = math.modf(60*f)
s = round(60*f, 6)

print(int(d), int(m), s)
      def dms_to_deg(dms):
    import math
    import numpy as np
    a=math.fabs(dms)
    d=a//10000
    m=(a-d*10000)//100
    s=(a-d*10000-m*100)
    deg=(d+m/60+s/3600)*np.sign(dms)
    return deg

#---Usage
r1=dms_to_deg(243055.25)
r2=dms_to_deg(-243055.25)
print(r1,r2)
Другие вопросы по тегам