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)
COGO: TSQL Function For Creating a Point from Point, Bearing and Distance
Sometimes the definition of an object can be as a bearing and distance from a known point. This often happens in unbiased statistical sampling, or when creating polygons describing land titles from coordinate geometry (COGO) measurements.
Here is a version of the STPointFromBearingAndDistance PL/SQL function I wrote for Oracle Spatial many years ago for SQL Server.
Note that I have a schema call cogo in which I create functions like this. You can use anything you like.
CREATE FUNCTION [cogo].[STPointFromBearingAndDistance]
(
@p_dStartE Float,
@p_dStartN Float,
@p_dBearing Float,
@p_dDistance Float,
@p_round_xy int = 3,
@p_srid int = 0
)
RETURNS geometry
AS
/****f* COGO/STPointFromBearingAndDistance (2008)
* NAME
* STPointFromBearingAndDistance -- Returns a projected point given starting point, a bearing in Degrees, and a distance (geometry SRID units).
* SYNOPSIS
* Function STPointFromBearingAndDistance (
* @p_dStartE float,
* @p_dStartN float,
* @p_dBearing float,
* @p_dDistance float
* @p_round_xy int = 3,
* @p_srid int = 0
* )
* Returns float
* DESCRIPTION
* Function that computes a new point given a starting coordinate, a whole circle bearing and a distance (SRID Units).
* Returned point's XY ordinates are rounded to @p_round_xy decimal digits of precision.
* @p_SRID is the SRID of the supplied start point.
* INPUTS
* @p_dStartE (float) - Easting of starting point.
* @p_dStartN (float) - Northing of starting point.
* @p_dBearing (float) - Whole circle bearing between 0 and 360 degrees.
* @p_dDistance (float) - Distance in SRID units from starting point to required point.
* @p_round_xy (int) - XY ordinates decimal digitis of precision.
* @p_srid (int) - SRID associated with @p_dStartE/p_dStartN.
* RESULT
* point (geometry) - Point
* EXAMPLE
* SELECT [cogo].[STPointFromBearingAndDistance] (0,0,45,100,3,0).STAsText() as endPoint;
* GO
*
* endPoint
* POINT (70.711 70.711)
* AUTHOR
* Simon Greener
* HISTORY
* Simon Greener - December 2011 - Original TSQL Coding for SQL Server.
* COPYRIGHT
* (c) 2008-2018 by TheSpatialDBAdvisor/Simon Greener
******/
Begin
Declare
@dBearing Float,
@dAngle1 Float,
@dAngle1Rad Float,
@dDeltaN Float,
@dDeltaE Float,
@dEndE Float,
@dEndN Float,
@v_round_xy int = ISNULL(@p_round_xy,3),
@v_srid int = ISNULL(@p_srid ,0);
BEGIN
IF ( @p_dStartE IS NULL OR
@p_dStartN IS NULL OR
@p_dBearing IS NULL OR
@p_dDistance IS NULL )
RETURN NULL;
SET @dBearing = ABS(@p_dBearing);
-- First calculate dDeltaE and dDeltaN
IF ( @dBearing < CAST(90.0 as float) )
BEGIN
SET @dAngle1 = CAST(90.0 as float) - @dBearing;
SET @dAngle1Rad = @dAngle1 * PI() / CAST(180.0 as float)
SET @dDeltaE = Cos(@dAngle1Rad) * @p_dDistance;
SET @dDeltaN = Sin(@dAngle1Rad) * @p_dDistance;
-- Calculate the easting and northing of the end point
SET @dEndE = @p_dStartE + @dDeltaE;
SET @dEndN = @p_dStartN + @dDeltaN;
RETURN geometry::Point(ROUND(@dEndE,@v_round_xy),ROUND(@dEndN,@v_round_xy), @v_srid);
END;
IF ( @dBearing < CAST(180.0 as float) )
BEGIN
SET @dAngle1 = @dBearing - CAST(90.0 AS float);
SET @dAngle1Rad = @dAngle1 * PI() / CAST(180.0 AS float);
SET @dDeltaE = Cos(@dAngle1Rad) * @p_dDistance;
SET @dDeltaN = Sin(@dAngle1Rad) * @p_dDistance * -1;
-- Calculate the easting and northing of the end point
SET @dEndE = @p_dStartE + @dDeltaE;
SET @dEndN = @p_dStartN + @dDeltaN;
RETURN geometry::Point(ROUND(@dEndE,@v_round_xy),ROUND(@dEndN,@v_round_xy), @v_srid);
END;
IF ( @dBearing < CAST(270.0 AS float) )
BEGIN
SET @dAngle1 = CAST(270.0 AS float) - @dBearing;
SET @dAngle1Rad = @dAngle1 * PI() / CAST(180.0 AS float);
SET @dDeltaE = Cos(@dAngle1Rad) * @p_dDistance * -1;
SET @dDeltaN = Sin(@dAngle1Rad) * @p_dDistance * -1;
-- Calculate the easting and northing of the end point
SET @dEndE = @p_dStartE + @dDeltaE;
SET @dEndN = @p_dStartN + @dDeltaN;
RETURN geometry::Point(ROUND(@dEndE,@v_round_xy),ROUND(@dEndN,@v_round_xy), @v_srid);
END;
IF ( @dBearing <= CAST(360.0 AS float) )
BEGIN
SET @dAngle1 = @dBearing - CAST(270.0 AS float);
SET @dAngle1Rad = @dAngle1 * PI() / CAST(180.0 as float);
SET @dDeltaE = Cos(@dAngle1Rad) * @p_dDistance * -1;
SET @dDeltaN = Sin(@dAngle1Rad) * @p_dDistance;
-- Calculate the easting and northing of the end point
SET @dEndE = @p_dStartE + @dDeltaE;
SET @dEndN = @p_dStartN + @dDeltaN;
RETURN geometry::Point(ROUND(@dEndE,@v_round_xy),ROUND(@dEndN,@v_round_xy), @v_srid);
End;
Return null;
END;
END;
GO
Here is an example of how to generate the geometry::Point object at the end of a bearing of 45 degrees and distance of 100 meters from ( 0,0 ) .
select cogo.STPointFromBearingAndDistance(0,0,45,100,3,0).STAsText() as NewPoint;
| NewPoint |
|---|
| POINT (70.711 70.711) |
Or more visually:
DECLARE
@XY Float = SQRT(POWER(100,2)/2);
select geometry::STGeomFromText('POINT(0 0)',0).STBuffer(10) as geom
union all
select geometry::STGeomFromText('LINESTRING(0 0,' + STR(@XY,10,5) + ' ' + STR(@XY,10,5) + ')',0) as geom
union all
select cogo.STPointFromBearingAndDistance(0,0,45,100,3,0).STBuffer(10) as geom;

I hope this is helpful to someone.
Documentation
- GeoRaptor 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