Top 5 Recent Articles
ARTICLES CATEGORIES
- Algorithms (22)
- All (399)
- Biography (1)
- Blog (44)
- Business Requirements (1)
- Commentary (1)
- Conversion (2)
- Customers (2)
- Data Models (1)
- Education (2)
- GeoRaptor (13)
- GPS (1)
- Image Processing (2)
- Import Export (8)
- Licensing (2)
- LiDAR (1)
- Linear Referencing (4)
- Manifold GIS (3)
- Mapping (1)
- MySQL Spatial (7)
- Networking and Routing (including Optimization) (5)
- Open Source (18)
- Oracle Spatial and Locator (194)
- Partitioning (1)
- PostGIS (36)
- Projections (1)
- Published Articles (1)
- qGIS (1)
- Recommendations (1)
- Services (1)
- Software Change Log (1)
- Source Code (37)
- Space Curves (9)
- Spatial Database Functions (109)
- Spatial DB comparison (1)
- Spatial XML Processing (11)
- SQL Server Spatial (92)
- Standards (3)
- Stored Procedure (17)
- Tessellation or Gridding (10)
- Tools (2)
- Topological Relationships (1)
- Training (2)
- Triangulation (2)
COGO: Converting (Google Earth) Formatted Longitude/Latitude points to decimal degrees (SQL Server)
In an article on Oracle I described how to convert Google Earth textual representations of a longitude or latitude value to its decimal equivalent.
Here is a version that will work with SQL Server 2008/2012 Spatial.
/** ---------------------------------------------------------------------------------------- * @function : DMSS2DD
* @precis : Function parses provided string, say extracted from Google Earth, * that represents DD MM SS.SS values, extracts and creates a single * floating point decimal degrees value.
* @version : 1.0
* @usage : Function DMSS2DD(@p_strDegMinSec nvarchar(100))
* Returns Float
* eg SELECT 3 as id, DMSS2DD('43� 0'' 50.00"S') as DD;
* @param : p_strDegMinSec : DD MM SS.SS description eg 43� 0'' 50.00"S
* @param : p_strDegMinSec : String
* @return : Decimal Degree : Returns decimal degrees equivalent eg -43.0138888888889 * @returnType : Float
* @depends : dbo.Tokenizer()
* @history : Simon Greener - Feb 2011 - Original coding for Oracle in PL/SQL * @history : Simon Greener - May 2011 - Original coding for SQL Server in TSQL * @copyright : Licensed under a Creative Commons Attribution-Share Alike 2.5 Australia License. * (http://creativecommons.org/licenses/by-sa/2.5/au/)
**/
CREATE FUNCTION DMSS2DD(@p_strDegMinSec nvarchar(100))
RETURNS FLOAT
AS
BEGIN
DECLARE
@i INT = 0,
@intDmsLen INT = -1, --Length of original string
@strCompassPoint NVarChar(1),
@strNorm Nvarchar(100) = N'', --Will contain normalized string
@strDegMinSecB Nvarchar(100),
@token Nvarchar(100),
@strChr NVarChar(1),
@blnGotSeparator INTEGER = -1, -- Keeps track of separator sequences @dDeg FLOAT = 0,
@dMin FLOAT = 0,
@dSec FLOAT = 0,
@dReturnDecimal FLOAT = 0.0;
BEGIN
-- Remove leading and trailing spaces
SET @strDegMinSecB = REPLACE(@p_strDegMinSec,' ','');
-- assume no leading and trailing spaces?
SET @intDmsLen = DATALENGTH(@strDegMinSecB);
SET @blnGotSeparator = 0; -- Not in separator sequence right now
-- Loop over string, replacing anything that is not a digit or a
-- decimal separator with
-- a single blank
SET @i = 0;
WHILE ( @i <= @intDmsLen)
BEGIN
SET @i = @i + 1;
-- Get current character
SET @strChr = SUBSTRING(@strDegMinSecB, @i, 1);
-- either add character to normalized string or replace
-- separator sequence with single blank
IF (CHARINDEX(@strChr,N'0123456789,.') > 0 )
BEGIN
-- add character but replace comma with point
IF ((@strChr <> N',') )
BEGIN
SET @strNorm = @strNorm + @strChr;
END
ELSE
BEGIN
SET @strNorm = @strNorm + N'.';
END;
SET @blnGotSeparator = 0;
END;
ELSE
BEGIN
IF (CHARINDEX(@strChr,N'neswNESW') > 0 ) -- Extract Compass Point IF (present BEGIN
SET @strCompassPoint = UPPER(@strChr);
END;
ELSE
BEGIN
-- ensure only one separator is replaced with a marker -
-- suppress the rest
IF (@blnGotSeparator = 0 )
BEGIN
SET @strNorm = @strNorm + N'@';
SET @blnGotSeparator = 0;
END;
END;
END;
END /* LOOP */
-- Split normalized string into array of max 3 components
DECLARE tokenList CURSOR FOR
SELECT a.token
FROM dbo.Tokenizer(@strNorm,N'@') a;
OPEN tokenList
FETCH NEXT FROM tokenList
INTO @token
SET @i = 1;
WHILE ( ==@@==FETCH_STATUS = 0 )
BEGIN
--convert specified components to double
IF ( @i = 1 ) SET @dDeg = CAST(@token AS FLOAT);
IF ( @i = 2 ) SET @dMin = CAST(@token AS FLOAT);
IF ( @i = 3 ) SET @dSec = CAST(@token AS FLOAT);
SET @i = @i + 1
FETCH NEXT FROM tokenList INTO @token
END;
CLOSE tokenList
DEALLOCATE tokenList
-- convert components to value
SET @dReturnDecimal = CASE WHEN UPPER(@strCompassPoint) IN (N'S',N'W')
THEN -1
ELSE 1
END
*
(@dDeg + @dMin / 60 + @dSec / 3600);
RETURN @dReturnDecimal;
END;
END
GO
And here are a few examples.
SELECT a.DD
FROM (
SELECT 1 AS id, DMSS2DD('43� 0'' 50.00"S') AS DD
UNION SELECT 2 AS id, DMSS2DD('43� 30'' 45.50"N') AS DD
UNION SELECT 3 AS id, DMSS2DD('147� 50'' 30.60"E') AS DD
UNION SELECT 4 AS id, DMSS2DD('65� 10'' 12.60"W') AS DD
) a
ORDER BY a.id;
Result
| DD |
|---|
| -43.0138888888889 |
| 43.5126388888889 |
| 147.841833333333 |
| -65.1701666666667 |
I hope this is of use to someone.
Documentation
- GeoRaptor Documentation
- MySQL Spatial General Functions
- Oracle LRS Objects
- Oracle Spatial Exporter (Java + pl/SQL)
- Oracle Spatial Object Functions
- Oracle Spatial Object Functions (Multi Page)
- PostGIS pl/pgSQL Functions
- SC4O Oracle Java Topology Suite (Java + pl/SQL)
- SQL Server Spatial General TSQL Functions
- SQL Server Spatial LRS TSQL Functions