* @param r - location of first point.
* @param s - location of second point.
* @param spheroid - spheroid definition.
-* @param azimuth - azimuth in radians.
-* @return
+* @return azimuth - azimuth in radians.
*
*/
double lwgeom_azumith_spheroid(const LWPOINT *r, const LWPOINT *s, const SPHEROID *spheroid)
y2 = lwpoint_get_y(s);
geographic_point_init(x2, y2, &g2);
- /* Same point, return a standard azimuth instead of NULL or NaN */
+ /* Same point, return NaN */
if ( FP_EQUALS(x1, x2) && FP_EQUALS(y1, y2) )
{
- return 0.0;
+ return NAN;
}
/* Do the direction calculation */
CREATE OR REPLACE FUNCTION ST_Project(geog geography, distance float8, azimuth float8)
RETURNS geography
AS 'MODULE_PATHNAME','geography_project'
- LANGUAGE 'C' IMMUTABLE STRICT
+ LANGUAGE 'C' IMMUTABLE
COST 100;
-- Availability: 2.0.0
elog(ERROR, "ST_Project(geography) is only valid for point inputs");
PG_RETURN_NULL();
}
+
+ /* Return NULL on NULL distance */
+ if ( PG_ARGISNULL(1) )
+ PG_RETURN_NULL();
+ distance = PG_GETARG_FLOAT8(1); /* Distance in Meters */
lwgeom = lwgeom_from_gserialized(g);
/* EMPTY things cannot be projected from */
PG_RETURN_NULL();
}
- /* Read the other parameters */
- distance = PG_GETARG_FLOAT8(1); /* Meters */
- azimuth = PG_GETARG_FLOAT8(2); /* Radians */
+ if ( PG_ARGISNULL(2) )
+ azimuth = 0.0;
+ else
+ azimuth = PG_GETARG_FLOAT8(2); /* Azimuth in Radians */
/* Initialize spheroid */
spheroid_init(&s, WGS84_MAJOR_AXIS, WGS84_MINOR_AXIS);
+ /* Handle the zero distance case */
+ if( FP_EQUALS(distance, 0.0) )
+ {
+ PG_RETURN_POINTER(g);
+ }
+
/* Calculate the length */
lwp_projected = lwgeom_project_spheroid(lwgeom_as_lwpoint(lwgeom), &s, distance, azimuth);
PG_FREE_IF_COPY(g1, 0);
PG_FREE_IF_COPY(g2, 1);
+
+ /* Return NULL for unknown (same point) azimuth */
+ if( isnan(azimuth) )
+ {
+ PG_RETURN_NULL();
+ }
+
PG_RETURN_FLOAT8(azimuth);
}