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)
ST_Azimuth for Oracle: AKA Cogo.Bearing
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”:http://postgis.refractions.net/documentation/manual-svn/ST_Azimuth.html.
Here are the relevant declarations of the Bearing function and overloaded ST_Azimuth interfaces that implement ST_Azimuth function wrappers which would allow some level of portability between Oracle and PostGIS.
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.
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