Changes between Version 21 and Version 22 of UsersWikiplpgsqlfunctions


Ignore:
Timestamp:
Jan 20, 2011, 7:43:36 PM (13 years ago)
Author:
robe
Comment:

Legend:

Unmodified
Added
Removed
Modified
  • UsersWikiplpgsqlfunctions

    v21 v22  
    6161}}}
    6262
     63* '''Convert degree minutes seconds to long lat decimals '''
     64This is from Simon Greener's article [http://www.spatialdbadvisor.com/postgis_tips_tricks/115/dms2dd-for-postgis/ DMS2DD for PostGIS]
     65and was an adaptation of his Oracle function described in [http://www.spatialdbadvisor.com/oracle_spatial_tips_tricks/114/converting-google-earth-formatted-longitude-latitude-points-to-decimal-degrees Converting Google Earth Formatted Longitude/Latitude points to decimal degrees]
     66{{{
     67CREATE OR REPLACE FUNCTION DMS2DD(strDegMinSec varchar)
     68    RETURNS numeric
     69    AS
     70    $$
     71    DECLARE
     72       i               numeric;
     73       intDmsLen       numeric;          -- Length of original string
     74       strCompassPoint Char(1);
     75       strNorm         varchar(16) = ''; -- Will contain normalized string
     76       strDegMinSecB   varchar(100);
     77       blnGotSeparator integer;          -- Keeps track of separator sequences
     78       arrDegMinSec    varchar[];        -- TYPE stringarray is table of varchar(2048) ;
     79       dDeg            numeric := 0;
     80       dMin            numeric := 0;
     81       dSec            numeric := 0;
     82       strChr          Char(1);
     83    BEGIN
     84       -- Remove leading and trailing spaces
     85       strDegMinSecB := REPLACE(strDegMinSec,' ','');
     86       -- assume no leading and trailing spaces?
     87       intDmsLen := Length(strDegMinSecB);
     88
     89       blnGotSeparator := 0; -- Not in separator sequence right now
     90
     91       -- Loop over string, replacing anything that is not a digit or a
     92       -- decimal separator with
     93       -- a single blank
     94       FOR i in 1..intDmsLen LOOP
     95          -- Get current character
     96          strChr := SubStr(strDegMinSecB, i, 1);
     97          -- either add character to normalized string or replace
     98          -- separator sequence with single blank         
     99          If strpos('0123456789,.', strChr) > 0 Then
     100             -- add character but replace comma with point
     101             If (strChr <> ',') Then
     102                strNorm := strNorm || strChr;
     103             Else
     104                strNorm := strNorm || '.';
     105             End If;
     106             blnGotSeparator := 0;
     107          ElsIf strpos('neswNESW',strChr) > 0 Then -- Extract Compass Point if present
     108            strCompassPoint := strChr;
     109          Else
     110             -- ensure only one separator is replaced with a blank -
     111             -- suppress the rest
     112             If blnGotSeparator = 0 Then
     113                strNorm := strNorm || ' ';
     114                blnGotSeparator := 0;
     115             End If;
     116          End If;
     117       End Loop;
     118
     119       -- Split normalized string into array of max 3 components
     120       arrDegMinSec := string_to_array(strNorm, ' ');
     121
     122       --convert specified components to double
     123       i := array_upper(arrDegMinSec,1);
     124       If i >= 1 Then
     125          dDeg := CAST(arrDegMinSec[1] AS numeric);
     126       End If;
     127       If i >= 2 Then
     128          dMin := CAST(arrDegMinSec[2] AS numeric);
     129       End If;
     130       If i >= 3 Then
     131          dSec := CAST(arrDegMinSec[3] AS numeric);
     132       End If;
     133
     134       -- convert components to value
     135       return (CASE WHEN UPPER(strCompassPoint) IN ('S','W')
     136                    THEN -1
     137                    ELSE 1
     138                END
     139               *
     140               (dDeg + dMin / 60 + dSec / 3600));
     141    End
     142$$
     143    LANGUAGE 'plpgsql' IMMUTABLE;
     144
     145}}}
     146
     147
    63148 * '''Find Length of Day for a given location and date'''
    64149{{{