Convert DD (decimal degrees) to DMS (degrees minutes seconds) in Python?
Asked Answered
W

15

26

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

Waves answered 5/4, 2010 at 16:32 Comment(1)
@David: it's a matter of multiplying decimal part by 60. What do you need beyond that?Plurality
Z
30

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)
Zayin answered 5/4, 2010 at 18:32 Comment(5)
It doesn't work with negative. -122.442 returns (-123,33,28.8). Should be (-122,26,31.12)Pasteurization
@baens - do you mean (-122, -26, -31.12)? I think -123 + 33/60 + 28.8/3600 does in fact equal -122.442Zayin
A multiplication by 3600, followed by 2 divisions by 60, doesn't look as efficient as possible.Faux
As said by @erik-l it gives wrong results for negative angles and must be correctedAnalemma
Only took 10 years, but here is a solution where all values are positive or negative, not mixed.Zayin
P
17

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)
Pasteurization answered 23/4, 2012 at 19:7 Comment(1)
minutes and seconds also need to be negated if is_positive is False.Zayin
C
14

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)
Catullus answered 5/10, 2012 at 0:27 Comment(0)
G
8

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
>>> 
Gratin answered 5/4, 2010 at 17:56 Comment(0)
L
5

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), '" ')
Lavonda answered 11/4, 2015 at 9:31 Comment(1)
Using Decimal as a variable name may conflict with decimal.Decimal and is not a good idea.Faux
E
5

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)
Extreme answered 17/9, 2018 at 16:16 Comment(0)
A
4

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)
Antitoxin answered 17/12, 2020 at 16:47 Comment(0)
F
3

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
Faux answered 1/6, 2015 at 22:49 Comment(0)
K
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.]]
Knock answered 27/6, 2023 at 16:42 Comment(0)
H
0

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.

Harding answered 5/4, 2010 at 16:51 Comment(1)
You probably meant math.modf.Faux
F
0

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')`
Fringe answered 12/3, 2020 at 10:50 Comment(4)
The version you linked is only tested to Python 2.7. There is a newer version, but even that one is only tested to Python 3.6 pypi.org/project/latlon3Lifesaver
Hi, what I am using now is LatLon23 in my Python 3.7.4 pypi.org/project/LatLon23/#descriptionFringe
That's great. It seems to be working with 3.9 as well. It's more straightforward than Geographiclib, which is what I ended up with.Lifesaver
Just a note for users following the documentation that says that you import the module using the syntax import latlon You need to use the following from latlon import LatLon to make these examples work. Note the caseFlightless
A
0

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
Ammons answered 23/2, 2021 at 5:58 Comment(0)
Z
0
# 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 ")
Zirkle answered 26/7, 2022 at 23:3 Comment(0)
R
0

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)
Ralston answered 18/6, 2023 at 1:27 Comment(2)
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.Majka
Testing with math.degrees(1.777036) and rounding set to 1 decimal place on seconds you get (101 48 60.0) -- any simplistic conversion that rounds will have this kind of issue.Knock
U
-1
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)
Understood answered 19/7, 2023 at 3:54 Comment(2)
A Python function to Convert degree minutes seconds to degree decimal for both positive and negative numbers. Check Example in Usage.Understood
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Majka

© 2022 - 2024 — McMap. All rights reserved.