Datum ST_LocateBetweenElevations(PG_FUNCTION_ARGS) { GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0); double from = PG_GETARG_FLOAT8(1); double to = PG_GETARG_FLOAT8(2); LWCOLLECTION *geom_out = NULL; LWGEOM *line_in = NULL; static char ordinate = 'Z'; /* Z */ static double offset = 0.0; if ( ! gserialized_has_z(geom_in) ) { elog(ERROR,"This function only accepts LINESTRING or MULTILINESTRING with Z dimensions."); PG_RETURN_NULL(); } line_in = lwgeom_from_gserialized(geom_in); geom_out = lwgeom_clip_to_ordinate_range(line_in, ordinate, from, to, offset); lwgeom_free(line_in); PG_FREE_IF_COPY(geom_in, 0); if ( ! geom_out ) { elog(ERROR,"lwline_clip_to_ordinate_range returned null"); PG_RETURN_NULL(); } PG_RETURN_POINTER(geometry_serialize((LWGEOM*)geom_out)); }
Datum ST_LocateBetween(PG_FUNCTION_ARGS) { GSERIALIZED *geom_in = PG_GETARG_GSERIALIZED_P(0); double from = PG_GETARG_FLOAT8(1); double to = PG_GETARG_FLOAT8(2); double offset = PG_GETARG_FLOAT8(3); LWCOLLECTION *geom_out = NULL; LWGEOM *line_in = NULL; static char ordinate = 'M'; /* M */ if ( ! gserialized_has_m(geom_in) ) { elog(ERROR,"This function only accepts geometries that have an M dimension."); PG_RETURN_NULL(); } /* This should be a call to ST_LocateAlong! */ if ( to == from ) { PG_RETURN_DATUM(DirectFunctionCall3(ST_LocateAlong, PG_GETARG_DATUM(0), PG_GETARG_DATUM(1), PG_GETARG_DATUM(3))); } line_in = lwgeom_from_gserialized(geom_in); geom_out = lwgeom_clip_to_ordinate_range(line_in, ordinate, from, to, offset); lwgeom_free(line_in); PG_FREE_IF_COPY(geom_in, 0); if ( ! geom_out ) { elog(ERROR,"lwline_clip_to_ordinate_range returned null"); PG_RETURN_NULL(); } PG_RETURN_POINTER(geometry_serialize((LWGEOM*)geom_out)); }
LWCOLLECTION* lwgeom_locate_between(const LWGEOM *lwin, double from, double to, double offset) { if ( ! lwgeom_has_m(lwin) ) lwerror("Input geometry does not have a measure dimension"); return lwgeom_clip_to_ordinate_range(lwin, 'M', from, to, offset); }