Bind ST_LocateAlong() to the new LRS function that supports offsets.

git-svn-id: http://svn.osgeo.org/postgis/trunk@8757 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
Paul Ramsey 2012-01-10 23:14:28 +00:00
parent c48d00d607
commit 242d9c9476
3 changed files with 55 additions and 20 deletions

View file

@ -154,13 +154,29 @@ lwmline_locate_along(const LWMLINE *lwmline, double m, double offset)
return lwmpoint;
}
static LWPOINT*
lwpoint_locate_along(const LWPOINT *lwpoint, double m, double offset)
{
LWGEOM *lwg = lwpoint_as_lwgeom(lwpoint);
double point_m = lwpoint_get_m(lwpoint);
if ( FP_EQUALS(m, point_m) )
return lwpoint_clone(lwpoint);
else
return lwpoint_construct_empty(lwgeom_get_srid(lwg), lwgeom_has_z(lwg), lwgeom_has_m(lwg));
}
LWGEOM*
lwgeom_locate_along(const LWGEOM *lwin, double m, double offset)
{
if ( ! lwin ) return NULL;
if ( ! lwgeom_has_m(lwin) )
lwerror("Input geometry does not have a measure dimension");
switch (lwin->type)
{
case POINTTYPE:
return (LWGEOM*)lwpoint_locate_along((LWPOINT*)lwin, m, offset);
case LINETYPE:
return (LWGEOM*)lwline_locate_along((LWLINE*)lwin, m, offset);
case MULTILINETYPE:

View file

@ -18,7 +18,6 @@
Datum LWGEOM_locate_between_m(PG_FUNCTION_ARGS);
Datum ST_AddMeasure(PG_FUNCTION_ARGS);
typedef struct
{
@ -520,11 +519,11 @@ Datum LWGEOM_locate_between_m(PG_FUNCTION_ARGS)
/*
* CREATE OR REPLACE FUNCTION ST_AddMeasure(geometry, float8, float8)
* RETURNS geometry
* AS '$libdir/postgis-1.5', 'ST_AddMeasure'
* LANGUAGE 'C' IMMUTABLE STRICT;
* Add a measure dimension to a line, interpolating linearly from the
* start value to the end value.
* ST_AddMeasure(Geometry, StartMeasure, EndMeasure) returns Geometry
*/
Datum ST_AddMeasure(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(ST_AddMeasure);
Datum ST_AddMeasure(PG_FUNCTION_ARGS)
{
@ -554,7 +553,37 @@ Datum ST_AddMeasure(PG_FUNCTION_ARGS)
PG_RETURN_NULL();
gout = geometry_serialize(lwout);
lwgeom_release(lwout);
lwgeom_free(lwout);
PG_RETURN_POINTER(gout);
}
/*
* Locate a point along a feature based on a measure value.
* ST_LocateAlong(Geometry, Measure, [Offset]) returns Geometry
*/
Datum ST_LocateAlong(PG_FUNCTION_ARGS);
PG_FUNCTION_INFO_V1(ST_LocateAlong);
Datum ST_LocateAlong(PG_FUNCTION_ARGS)
{
GSERIALIZED *gin = (GSERIALIZED *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
GSERIALIZED *gout;
LWGEOM *lwin = NULL, *lwout = NULL;
double measure = PG_GETARG_FLOAT8(1);
double offset = PG_GETARG_FLOAT8(2);;
lwnotice("offset %g",offset);
lwin = lwgeom_from_gserialized(gin);
lwout = lwgeom_locate_along(lwin, measure, offset);
lwgeom_free(lwin);
PG_FREE_IF_COPY(gin, 0);
if ( ! lwout )
PG_RETURN_NULL();
gout = geometry_serialize(lwout);
lwgeom_free(lwout);
PG_RETURN_POINTER(gout);
}

View file

@ -4512,27 +4512,17 @@ CREATE OR REPLACE FUNCTION ST_WKBToSQL(bytea)
---
-- Linear referencing functions
---
CREATE OR REPLACE FUNCTION ST_LocateBetween(geometry, float8, float8)
CREATE OR REPLACE FUNCTION ST_LocateBetween(Geometry geometry, Measure1 float8, Measure2 float8, Offsets float8 default 0.0)
RETURNS geometry
AS 'MODULE_PATHNAME', 'LWGEOM_locate_between_m'
LANGUAGE 'C' IMMUTABLE STRICT;
CREATE OR REPLACE FUNCTION ST_LocateAlong(geometry, float8)
CREATE OR REPLACE FUNCTION ST_LocateAlong(Geometry geometry, Measure float8, Offsets float8 default 0.0)
RETURNS geometry
AS $$ SELECT ST_LocateBetween($1, $2, $2) $$
LANGUAGE 'sql' IMMUTABLE STRICT;
AS 'MODULE_PATHNAME', 'ST_LocateAlong'
LANGUAGE 'C' IMMUTABLE STRICT;
-- LRS with offset parameter
CREATE OR REPLACE FUNCTION ST_LocateBetween(geometry, float8, float8, float8)
RETURNS geometry
AS 'MODULE_PATHNAME', 'LWGEOM_locate_between_m'
LANGUAGE 'C' IMMUTABLE STRICT;
-- LRS with offset parameter
CREATE OR REPLACE FUNCTION ST_LocateAlong(geometry, float8, float8)
RETURNS geometry
AS $$ SELECT ST_LocateBetween($1, $2, $2) $$
LANGUAGE 'sql' IMMUTABLE STRICT;
---------------------------------------------------------------
-- END
---------------------------------------------------------------