Skip to content
You are here: Home » Documents » get_csquare.txt
Views
  • State: published

get_csquare.txt

Document Actions

Click here to get the file

Size 5.4 kB - File type text/plain

File contents

---  PL/SQL function: get_csquare                                              
---  Written by: Tony Rees, CSIRO Australia (Tony.Rees@csiro.au)              
---  Date Created: January, 2002                                                            
---  Description: gets c-squares code for a supplied lat/long coordinate pair  
---  Inputs: nlat: latitude in decimal degrees (number)
---          nlong: longitude in decimal degrees (number)
---          resolution: square size in decimal degrees (number)
---  Output: code as varchar2
---  Remarks: resolution currently expected as one of the following: 10, 5, 1, 0.5, 0.1 [degrees]
---          0 deg latitude/longitude is treated as positive
---          90 deg latitude is treated as 89.99999, -90 deg latitude is treated as -89.99999
---          180 deg longitude is treated as 179.99999, -180 deg longitude is treated as -179.99999

  function get_csquare (nlat number :=null, nlong number :=null, resolution number :=1) return varchar2 is
  
    code_char1 varchar2 (1) :=null;
    code_char2 varchar2 (1) :=null;
    code_chars34 varchar2 (2) :=null;
    code_char5 varchar2 (1) :=null;
    code_char6 varchar2 (1) :=null;
    code_char7 varchar2 (1) :=null;
    code_char8 varchar2 (1) :=null;
    code_char9 varchar2 (1) :=null;
    code_char10 varchar2 (1) :=null;
    lat_remainder number :=null;
    long_remainder number :=null;    

  begin
    
     --get the global quadrant
    if nlat>=0 then
      if nlong>=0 then
        code_char1 :='1';
      elsif nlong<0 then
        code_char1 :='7';
      end if;  
    elsif nlat<0 then
      if nlong>=0 then
        code_char1 :='3';
      elsif nlong<0 then
        code_char1 :='5';
      end if;  
    end if;
    
     --get the next digit (tens of degrees latitude)
    if nlat not in (90, -90) then     
      code_char2 := to_char(trunc(abs(nlat/10)));
      lat_remainder := abs(nlat) - (to_number(code_char2)*10);
      
    else     
         --special case for +90, -90 degrees
      code_char2 := '8';
      lat_remainder := 9.99999;
    end if;
        
     --get the next 2 digits (tens of degrees longitude)
     
    if nlong not in (180, -180) then     
      code_chars34 := substr('00'||to_char(trunc(abs(nlong/10))), -2);
      long_remainder := abs(nlong) - (to_number(code_chars34)*10);
    else     
         --special case for +180, -180 degrees
      code_chars34 := '17';
      long_remainder := 9.99999;
    end if;


    if resolution <10 then
    
       --get the 6th digit (single degrees latitude)
      code_char6 := to_char(trunc(lat_remainder));
      lat_remainder := lat_remainder - to_number(code_char6);
    
       --get the 7th digit (single degrees longitude)
      code_char7 := to_char(trunc(long_remainder));
      long_remainder := long_remainder - to_number(code_char7);


       --get the 5th digit (5-degree quadrant)
      if (to_number(code_char6) between 0 and 4) and (to_number(code_char7) between 0 and 4) then
        code_char5 := '1';
      elsif (to_number(code_char6) between 0 and 4) and (to_number(code_char7) between 5 and 9) then
        code_char5 := '2';
      elsif (to_number(code_char6) between 5 and 9) and (to_number(code_char7) between 0 and 4) then
        code_char5 := '3';
      elsif (to_number(code_char6) between 5 and 9) and (to_number(code_char7) between 5 and 9) then
        code_char5 := '4';
      end if;
      
      if resolution <1 then
        
         --get the 9th digit (tenths of degrees latitude)
        code_char9 := to_char(trunc(lat_remainder*10));
        lat_remainder := lat_remainder - to_number(code_char9/10);
     
         --get the 10th digit (tenths of degrees longitude)
        code_char10 := to_char(trunc(long_remainder*10));
        long_remainder := long_remainder - to_number(code_char10/10);

         --get the 8th digit (0.5-degree quadrant)
        if (to_number(code_char9) between 0 and 4) and (to_number(code_char10) between 0 and 4) then
          code_char8 := '1';
        elsif (to_number(code_char9) between 0 and 4) and (to_number(code_char10) between 5 and 9) then
          code_char8 := '2';
        elsif (to_number(code_char9) between 5 and 9) and (to_number(code_char10) between 0 and 4) then
          code_char8 := '3';
        elsif (to_number(code_char9) between 5 and 9) and (to_number(code_char10) between 5 and 9) then
          code_char8 := '4';
        end if;
      
      end if;
      
    end if;  
      
    if resolution = 10 then      -- 10 deg. resolution, e.g. Hobart: "3414"
      return code_char1||code_char2||code_chars34;
      
    elsif resolution = 5 then      -- 5 deg. resolution, e.g. Hobart: "3414:2"
      return code_char1||code_char2||code_chars34||':'||code_char5;
      
    elsif resolution = 1 then      -- 1 deg. resolution, e.g. Hobart: "3414:227"
      return code_char1||code_char2||code_chars34||':'||code_char5||code_char6||code_char7;
      
    elsif resolution = 0.5 then      -- 0.5 deg. resolution, e.g. Hobart: "3414:227:3"
      return code_char1||code_char2||code_chars34||':'||code_char5||code_char6||code_char7||
        ':'||code_char8;
        
    elsif resolution = 0.1 then      -- 0.1 deg. resolution, e.g. Hobart: "3414:227:383"
      return code_char1||code_char2||code_chars34||':'||code_char5||code_char6||code_char7||
        ':'||code_char8||code_char9||code_char10;
        
    end if;
    
  end get_csquare;
Created by admin
Last modified 2006-03-23 08:34
 

Personal tools
The c-squares mapper perl script is now on sourceforge at http://sourceforge.net/projects/csquares/
A "c-squares-discuss" listserver has been established for interested developers and/or implementers to exchange information or post enquiries relevant to c-squares. To join the list, send an email to c-squares-discuss-request@marine.csiro.au with the word 'subscribe' in the BODY of the email.