Go to content Go to navigation and search

Home

Current Oracle Spatial Blogs

Search

RSS / Atom

Email me

textpattern

ST_Azimuth for Oracle: AKA Cogo.Bearing

· Dec 23, 04:39 pm by Simon Greener

Many years ago I wrote a Coordinate Geometry (COGO) package for Oracle Sdo_Geometry that contained a Bearing function that, given two points, would return the angle in radians from the horizontal of the vector defined by point A and B.

PostGIS has a similar function called ST_Azimuth.

Here are the relevant declarations of the Bearing function and overloaded ST_Azimuth interfaces.

CREATE OR REPLACE PACKAGE "COGO"
AUTHID CURRENT_USER
As

.........

    /* ----------------------------------------------------------------------------------------
    ** function   : Bearing
    ** precis     : Returns a value between 0 and 2*PI representing the bearing
    **               North = 0, East = PI/2, South = PI, West = 3*PI/4
    **               To convert to degrees multiply by (180/PI).
    ** version    : 1.0
    ** usage      : FUNCTION Bearing( dE1 in number,
    **                               dN1 in number,
    **                               dE2 in number,
    **                               dN2 in number)
    **                        RETURN NUMBER DETERMINISTIC;
    **               eg :new.shape := CODESYS.cogo.Bearing(299900, 5200000, 300000, 5200100);
    ** param      : dE1     : X Ordinate of the start point for the vector
    ** paramtype  : dE1     : NUMBER
    ** param      : dN1     : Y Ordinate of the start point for the vector
    ** paramtype  : dN1     : NUMBER
    ** param      : dE2     : X Ordinate of the end point for the vector
    ** paramtype  : dE2     : NUMBER
    ** param      : dN2     : Y Ordinate of the end point for the vector
    ** paramtype  : dN2     : NUMBER
    ** return     : Bearing : the angle in radians between 0 and 2*PI representing the bearing
    ** rtnType    : Bearing : NUMBER
    ** note       : Does not throw exceptions
    ** note       : Assumes planar projection eg UTM.
    ** @history   : Simon Greener - Feb 2005 - Original coding.
    */
    Function Bearing( dE1 in number,
                      dN1 in number,
                      dE2 in number,
                      dN2 in number)
             Return Number Deterministic;

    /** Alternate binding: 1
    **/
    Function Bearing( startCoord in mdsys.sdo_point_type,
                        endCoord in mdsys.sdo_point_type)
             Return Number Deterministic;

    /** Alternate binding: 2
    **/
    Function Bearing( p_startCoord in mdsys.sdo_point_type,
                        p_endCoord in mdsys.sdo_point_type,
                     p_planar_srid in number,
                 p_geographic_srid in number := 8311
	                  )
     Return Number Deterministic;

    /* Alternate binding for SQL/MM
    **/
    Function ST_Azimuth( p_startCoord in mdsys.ST_Point,
                         p_endCoord   in mdsys.ST_Point)
      Return Number Deterministic;

.....

END Cogo;

Now, some examples of the use of these functions.

/* What happens when NULL points are provided */
SELECT COGO.Bearing(NULL,NULL) 
  FROM DUAL;

AZIMUTH
----------------------
NULL

1 rows selected

/* What happens if start and end point are the same? */
SELECT ROUND(COGO.Bearing(mdsys.sdo_point_type(1,2,null), mdsys.sdo_point_type(1,2,null)) / ( 2 * Constants.pi ) * 360) as degAz
  FROM DUAL;

DEGAZ
----------------------
NULL

1 rows selected

/* PostGIS example */
SELECT ST_Azimuth(ST_MakePoint(1,2), ST_MakePoint(3,4))/(2*pi())*360 as degAz, 
       ST_Azimuth(ST_MakePoint(3,4), ST_MakePoint(1,2))/(2*pi())*360 As degAzrev

degaz	degazrev
------	---------
45      225

/* Oracle version of PostGIS example using "native" interfaces */
SELECT ROUND(COGO.Bearing(mdsys.sdo_point_type(1,2,null), mdsys.sdo_point_type(3,4,null)) / ( 2 * Constants.pi ) * 360) as degAz,
       ROUND(COGO.Bearing(mdsys.sdo_point_type(3,4,null), mdsys.sdo_point_type(1,2,null)) / ( 2 * Constants.pi ) * 360) as degAzRev
  FROM DUAL;

DEGAZ                  DEGAZREV
---------------------- ----------------------
45                     225

1 rows selected

/* PostGIS example using "equivalent" ST_* interfaces */
SELECT Round(Cogo.ST_Azimuth(mdsys.ST_Point(1,2), mdsys.ST_Point(3,4))/(2*Constants.pi)*360) as degAz, 
       Round(Cogo.ST_Azimuth(mdsys.ST_Point(3,4), mdsys.ST_Point(1,2))/(2*Constants.pi)*360) As degAzrev
  FROM dual;

DEGAZ                  DEGAZREV
---------------------- ----------------------
45                     225

1 rows selected

I hope this is useful to someone.

post this at del.icio.uspost this at Diggpost this at Technoratipost this at Newsvinepost this at Ma.gnoliapost this at Furlpost this at Blinklistpost this at Spurlpost this at Wistspost this at Simpypost this at Redditpost this at Farkpost this at Blogmarkspost this at Yahoo! my webpost this at Mr. Wongpost this at Windows Livepost this at Google Bookmarkspost this to Twitter
  Textile Help