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