在Python中将DD(十进制度)转换为DMS(度分秒)?

发布于 2024-08-27 13:01:02 字数 42 浏览 7 评论 0原文

如何在 Python 中将十进制度转换为度分秒?有没有已经写好的公式?

How do you convert Decimal Degrees to Degrees Minutes Seconds In Python? Is there a Formula already written?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(15

兮子 2024-09-03 13:01:02

这正是 divmod 的发明目的:

def decdeg2dms(dd):
    mult = -1 if dd < 0 else 1
    mnt,sec = divmod(abs(dd)*3600, 60)
    deg,mnt = divmod(mnt, 60)
    return mult*deg, mult*mnt, mult*sec

dd = 45 + 30/60 + 1/3600
print(decdeg2dms(dd))

# negative value returns all negative elements
print(decdeg2dms(-122.442))

打印:

(45.0, 30.0, 1.0)
(-122.0, -26.0, -31.199999999953434)

This is exactly what divmod was invented for:

def decdeg2dms(dd):
    mult = -1 if dd < 0 else 1
    mnt,sec = divmod(abs(dd)*3600, 60)
    deg,mnt = divmod(mnt, 60)
    return mult*deg, mult*mnt, mult*sec

dd = 45 + 30/60 + 1/3600
print(decdeg2dms(dd))

# negative value returns all negative elements
print(decdeg2dms(-122.442))

Prints:

(45.0, 30.0, 1.0)
(-122.0, -26.0, -31.199999999953434)
灵芸 2024-09-03 13:01:02

这是我根据 Paul McGuire 的更新版本。这个应该正确处理底片。

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)

Here is my updated version based upon Paul McGuire's. This one should handle negatives correctly.

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)
如梦亦如幻 2024-09-03 13:01:02

如果要正确处理负数,请将第一个非零度量设置为负数。将所有度数、分数和秒数指定为负数是违反惯例的(Wikipedia 显示 40 ° 26.7717, -79° 56.93172 作为度分表示法的有效示例,其中度数为负数,分没有符号),如果度数部分为 0,则将度数设置为负数不会产生任何影响。这是一个函数基于 Paul McGuire 和 baens 的函数,可以充分处理这个问题:

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)

If you want to handle negatives properly, the first non-zero measure is set negative. It is counter to common practice to specify all of degrees, minutes and seconds as negative (Wikipedia shows 40° 26.7717, -79° 56.93172 as a valid example of degrees-minutes notation, in which degrees are negative and minutes have no sign), and setting degrees as negative does not have any effect if the degrees portion is 0. Here is a function that adequately handles this, based on Paul McGuire's and baens' functions:

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)
无可置疑 2024-09-03 13:01:02

只需几个 * 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
>>> 

Just a couple of * 60 multiplications and a couple of int truncations, i.e.:

>>> 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
>>> 
梦里°也失望 2024-09-03 13:01:02

改进@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)

Improving @chqrlie answer:

    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)
旧伤慢歌 2024-09-03 13:01:02

这是我的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), '" ')

This is my Python code:

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), '" ')
北方。的韩爷 2024-09-03 13:01:02

这是我的稍微不同的方法,其工作原理与我的 HP Prime 上的正十进制和负十进制相同......

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

Here's my slightly different approach that works the same as on my HP Prime for positive and negative decimal degrees...

def dms(deg):
    f,d = math.modf(deg)
    s,m = math.modf(abs(f) * 60)
    return (d,m,s * 60)
于我来说 2024-09-03 13:01:02

该符号最好单独返回,以便可以用来选择 ('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

The sign has better be returned separately, so that it can be used to choose from ('N', 'S') or ('E', 'W'), for example.

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
狼性发作 2024-09-03 13:01:02

这是 PaulMcG 答案的 numpy 版本,另外它会舍入到十分之一秒(您可以将第二个参数更改为舍入函数),并且它返回符号(-1 或 1)作为单独的值(这使得它更容易)让我处理为纬度/经度值)。这里的主要区别是您可以传入一个十进制_度数组或单个双精度值(请注意,如果您传递一个列表,您会得到一个列表列表)。使用之前,请确保您对舍入行为感到满意,否则您可以将其删除。

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.]]

This is a numpy version of PaulMcG's answer with the addition that it will round to tenths of a second (you can change second argument to round function) and it returns the sign (-1 or 1) as a separate value (this made it easier for me to handle as latitude/longitude values). Main difference here is that you can pass in an array of decimal_degrees or a single double value (note if you pass a list you get a list-of-lists back). Before using please make sure you are happy with the rounding behavior or you can remove it.

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.]]
葮薆情 2024-09-03 13:01:02

使用 fmod 和舍入来分离度数和分数。将分数乘以 60 并重复以获得分钟和余数。然后将最后一部分再次乘以 60 即可得到秒数。

Use fmod and rounding to get the degrees and fraction separated. Multiply the fraction by 60 and repeat to get minutes and a remainder. Then multiply that last part by 60 again to get the number of seconds.

一腔孤↑勇 2024-09-03 13:01:02

现在我们可以使用 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')`

Now we can use LatLon library...

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')`
蓝眸 2024-09-03 13:01:02

您可以使用函数 clean_lat_long()如果您的数据位于 DataFrame 中,则库 DataPrep 。使用 pip install dataprep 安装 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

You can use the function clean_lat_long() from the library DataPrep if your data is in a DataFrame. Install DataPrep with 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

Or if latitude and longitude are in separate columns:

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
℉服软 2024-09-03 13:01:02
# 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 ")
# 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 ")
梦忆晨望 2024-09-03 13:01:02

我的做法:

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)

My approach:

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)
怎樣才叫好 2024-09-03 13:01:02
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)
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)
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文