Go to content Go to navigation and search

Home

Current SQL Server Blog Articles


Search

Browse

RSS / Atom

Email me

textpattern

Creative Commons License
All Blog Articles, Data Models and Free Source Code by Simon Greener, The SpatialDB Advisor is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

COGO: Convert Degrees, Minutes and Seconds values to Decimal Degrees

Friday May 06 2011 at 06:38

Keywordsdecimal degrees from degrees minutes seconds values sql server 2008 2012 cogo
Summary

This article presents a function that computes a decimal degree floating point number from degrees, minutes and seconds values. This function will work in Sql Server 2008 and 2012.

Sometimes data is provided to spatial databases via spreadsheets or other database tables in the form of degrees, minutes and seconds values. For example, data may come like this:

Degree Minute Seconds
45 30 30.0


Which then need converting to a single decimal degree floating point value for use as an ordinate in a spatial coodinate (eg a Point). The following function, DMS2DD, converted from my free Oracle COGO package, is presented for us by SQL Server 2008 Spatial users.

Note that I have a schema called cogo in which I create functions like this. You can use anything you like.

  1. /** ----------------------------------------------------------------------------------------
  2.   * @function   : DMS2DD
  3.   * @precis     : Function computes a decimal degree floating point number from individual
  4.   *               degrees, minutes and seconds values.
  5.   * @version    : 1.0
  6.   * @usage      : Function DMS2DD(@p_dDeg  Int,
  7.   *                               @p_dMin  Int,
  8.   *                               @p_dSec  Float )
  9.   *                RETURNS Float
  10.   *               eg SELECT DMS2DD(45,30,30)
  11.   * @param      : p_dDeg       : Non-NULL degree value (0-360)
  12.   * @paramType  : p_dDeg       : Int
  13.   * @param      : p_dMin       : Non-NULL degree value (0-60)
  14.   * @paramType  : p_dMin       : Int
  15.   * @param      : p_dSec       : Non-NULL seconds value (0-60)
  16.   * @paramType  : p_dSec       : FLOAT
  17.   * @return     : DD Value     : Decimal degrees equivalent value.
  18.   * @returnType : DD Value     : Float
  19.   * @history    : Simon Greener - Apr 2007 - Original coding.
  20.   * @history    : Simon Greener - May 2011 - Ported to TSQL
  21.   * @copyright  : Licensed under a Creative Commons Attribution-Share Alike 2.5 Australia License.
  22.   *               (http://creativecommons.org/licenses/by-sa/2.5/au/)
  23. **/
  24. CREATE FUNCTION cogo.DMS2DD(@p_dDeg INT,
  25.                             @p_dMin INT,
  26.                             @p_dSec FLOAT)
  27. RETURNS FLOAT
  28. AS
  29. BEGIN
  30.     DECLARE
  31.        @dDD FLOAT;
  32.     BEGIN
  33.        IF ( @p_dDeg IS NULL OR
  34.             @p_dMin IS NULL OR
  35.             @p_dSec IS NULL )
  36.           RETURN NULL;  
  37.        SET @dDD = ABS(@p_dDeg) + @p_dMin / 60.0 + @p_dSec / 3600.0;
  38.        RETURN SIGN(@p_dDeg) * @dDD;
  39.     END;
  40. END
  41. GO

Some test cases as examples.

  1. SELECT cogo.DMS2DD(-44,10,50) AS DD
  2. UNION
  3. SELECT cogo.DMS2DD(45,30,30) AS DD;

Result.

DD
-44.0138888888889
45.0083333333333


I hope this is helpful to someone.

Creative Commons License

post this at del.icio.uspost this at Diggpost this at Technoratipost this at Redditpost this at Farkpost this at Yahoo! my webpost this at Windows Livepost this at Google Bookmarkspost this to Twitter

Comment [2]

You should cast your divisors (60, 3600) to floats. Integer division rounds off to an integer result. Your test cases actually demonstrate this error: e.g. (44,10,50) should give -44.180555 not -44.013888

— Reuben · 27 August 2013, 09:58 · #

Reuben,

Well spotted! 10 points to Gryffindor!

Keep those bug fixes coming!

regards
Simon

— Simon Greener · 2 September 2013, 20:22 · #