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)
Converting Google Earth Formatted Longitude/Latitude points to decimal degrees
I had cause, today, to mark the location of something in Google Earth and then provide the longitude/latitude values to a website that wanted them in decimal degrees.
Here is my location as a Google Placemark Location.
Note that the longitude/latitude values are coded as formatted degrees, minutes and seconds as follows:
Latitude | Longitude | |
43� 0’50.60“S | 147�12’18.20“E |
I wrote a DMS2DD function in my PL/SQL COGO package many years ago. I decided to use it to do the conversion.
SELECT round(cogo.dms2dd(' 43� 0''50.60"S'),9) AS latitude, round(cogo.dms2dd('147�12''18.20"E'),9) AS longitude FROM dual; -- LATITUDE LONGITUDE ---------------------- ---------------------- -43.014055556 147.205055556 1 ROWS selected
Here is the source code for the function.
-- -- Support function STRTOK -- (Added in response to Fabio Caroletta) -- -- ---------------------------------------------------------------------------------------- -- @function : StrTok -- @precis : Simple string tokeniser. -- @version : 1.0 -- @usage : function StrTok( -- p_str in varchar2, -- p_delim in varchar2 -- ) -- return stringarray deterministic; -- eg tokens := StrTok('299900, 5200000, 300000, 5200100',' ,' -- @param : p_Str : String containing tokens for extraction. -- @paramtype : p_Str : string. -- @param : p_delim : String containg one or more token separators. -- @paramtype : p_Delim : String -- @return : Tokens : A list of tokens (string). -- @rtnType : Tokens : Table of tokens (like a varray). -- @note : Does not throw exceptions -- @history : Simon Greener, Feb 2005 - Original coding. -- FUNCTION strtok(p_str IN varchar2, p_delim IN varchar2) RETURN STRINGARRAY DETERMINISTIC IS v_numtok NUMBER; v_length NUMBER; v_outside NUMBER; v_char CHAR(1); v_strtok_vals STRINGARRAY; BEGIN -- initialise strtok_vals array v_strtok_vals := STRINGARRAY(''); v_numtok := 0; v_length := LENGTH(p_str); v_outside := 1; FOR i IN 1..v_length loop v_char := SUBSTR(p_str,i,1); IF instr(p_delim, v_char) <> 0 THEN -- outside v_outside := 1; v_strtok_vals.EXTEND; v_strtok_vals(v_strtok_vals.LAST) := ''; ELSE -- inside IF (v_outside = 1) THEN v_numtok := v_numtok + 1; END IF; v_strtok_vals(v_strtok_vals.LAST) := v_strtok_vals(v_strtok_vals.LAST) || v_char ; v_outside := 0; END IF; END LOOP; -- Return value RETURN v_strtok_vals; END strtok; -- -- Main function -- FUNCTION DMS2DD(strDegMinSec IN varchar2) RETURN NUMBER IS i NUMBER; intDmsLen NUMBER; --Length of original string strCompassPoint CHAR(1); strNorm varchar2(16); --Will contain normalized string strDegMinSecB varchar2(100); blnGotSeparator INTEGER; -- Keeps track of separator sequences arrDegMinSec stringarray; -- TYPE stringarray is table of varchar2(2048) ; dDeg NUMBER := 0; dMin NUMBER := 0; dSec NUMBER := 0; strChr CHAR(1); BEGIN -- Remove leading and trailing spaces strDegMinSecB := REPLACE(strDegMinSec,' ',NULL); -- assume no leading and trailing spaces? intDmsLen := LENGTH(strDegMinSecB); 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 FOR i IN 1..intDmsLen LOOP -- Get current character strChr := SubStr(strDegMinSecB, i, 1); -- either add character to normalized string or replace -- separator sequence with single blank IF InStr('0123456789,.', strChr) > 0 THEN -- add character but replace comma with point IF (strChr <> ',') THEN strNorm := strNorm || strChr; ELSE strNorm := strNorm || '.'; END IF; blnGotSeparator := 0; ElsIf InStr('neswNESW',strChr) > 0 THEN -- Extract Compass Point if present strCompassPoint := strChr; ELSE -- ensure only one separator is replaced with a blank - -- suppress the rest IF blnGotSeparator = 0 THEN strNorm := strNorm || ' '; blnGotSeparator := 0; END IF; END IF; END Loop; -- Split normalized string into array of max 3 components arrDegMinSec := strtok(strNorm, ' '); --convert specified components to double i := arrDegMinSec.COUNT; IF i >= 1 THEN dDeg := TO_NUMBER(arrDegMinSec(1)); END IF; IF i >= 2 THEN dMin := TO_NUMBER(arrDegMinSec(2)); END IF; IF i >= 3 THEN dSec := TO_NUMBER(arrDegMinSec(3)); END IF; -- convert components to value RETURN (CASE WHEN UPPER(strCompassPoint) IN ('S','W') THEN -1 ELSE 1 END * (dDeg + dMin / 60 + dSec / 3600)); END DMS2DD;
I hope this function is useful 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