mirror of
https://git.osgeo.org/gitea/postgis/postgis
synced 2024-10-25 17:42:38 +00:00
Added npoints,numpoints,numgeometries,geometryn
git-svn-id: http://svn.osgeo.org/postgis/trunk@729 b70326c6-7e19-0410-871a-916f4a2858ee
This commit is contained in:
parent
537b7c3777
commit
840e565470
|
@ -19,9 +19,9 @@ FUNC: KEEPING FUNCTION: [box3d(geometry)]
|
|||
FUNC: KEEPING FUNCTION: [box(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [geometry(box3d)]
|
||||
FUNC: KEEPING FUNCTION: [expand(box3d, double precision)]
|
||||
|
||||
FUNC: KEEPING FUNCTION: [asbinary(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [asbinary(geometry, text)]
|
||||
FUNC: KEEPING FUNCTION: [npoints(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [nrings(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [translate(geometry, double precision, double precision, double precision)]
|
||||
FUNC: KEEPING FUNCTION: [dimension(geometry)]
|
||||
|
@ -29,13 +29,10 @@ FUNC: KEEPING FUNCTION: [envelope(geometry)]
|
|||
FUNC: KEEPING FUNCTION: [x(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [y(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [z(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [numpoints(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [pointn(geometry, integer)]
|
||||
FUNC: KEEPING FUNCTION: [exteriorring(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [numinteriorrings(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [interiorringn(geometry, integer)]
|
||||
FUNC: KEEPING FUNCTION: [numgeometries(geometry)]
|
||||
FUNC: KEEPING FUNCTION: [geometryn(geometry, integer)]
|
||||
FUNC: KEEPING FUNCTION: [max_distance(geometry, geometry)]
|
||||
FUNC: KEEPING FUNCTION: [optimistic_overlap(geometry, geometry, double precision)]
|
||||
FUNC: KEEPING FUNCTION: [segmentize(geometry, double precision)]
|
||||
|
|
|
@ -33,8 +33,13 @@ Datum lwgeom_summary(PG_FUNCTION_ARGS);
|
|||
Datum postgis_uses_stats(PG_FUNCTION_ARGS);
|
||||
Datum postgis_scripts_released(PG_FUNCTION_ARGS);
|
||||
Datum postgis_lib_version(PG_FUNCTION_ARGS);
|
||||
Datum lwgeom_npoints(PG_FUNCTION_ARGS);
|
||||
Datum lwgeom_numpoints_linestring(PG_FUNCTION_ARGS);
|
||||
Datum lwgeom_numgeometries_collection(PG_FUNCTION_ARGS);
|
||||
|
||||
char * lwgeom_summary_recursive(char *serialized, int offset);
|
||||
int32 lwgeom_npoints_recursive(char *serialized);
|
||||
int32 lwgeom_numpoints_linestring_recursive(char *serialized);
|
||||
|
||||
// getSRID(lwgeom) :: int4
|
||||
PG_FUNCTION_INFO_V1(LWGEOM_getSRID);
|
||||
|
@ -303,3 +308,179 @@ Datum postgis_uses_stats(PG_FUNCTION_ARGS)
|
|||
PG_RETURN_BOOL(FALSE);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
* Recursively count points in a SERIALIZED lwgeom
|
||||
*/
|
||||
int32
|
||||
lwgeom_npoints_recursive(char *serialized)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
|
||||
int i, j;
|
||||
int npoints=0;
|
||||
|
||||
//now have to do a scan of each object
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
LWLINE *line=NULL;
|
||||
LWPOINT *point=NULL;
|
||||
LWPOLY *poly=NULL;
|
||||
char *subgeom=NULL;
|
||||
|
||||
point = lwgeom_getpoint_inspected(inspected, i);
|
||||
if (point !=NULL)
|
||||
{
|
||||
npoints++;
|
||||
continue;
|
||||
}
|
||||
|
||||
poly = lwgeom_getpoly_inspected(inspected, i);
|
||||
if (poly !=NULL)
|
||||
{
|
||||
for (j=0; j<poly->nrings; j++)
|
||||
{
|
||||
npoints += poly->rings[j]->npoints;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
line = lwgeom_getline_inspected(inspected, i);
|
||||
if (line != NULL)
|
||||
{
|
||||
npoints += line->points->npoints;
|
||||
continue;
|
||||
}
|
||||
|
||||
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
if ( subgeom != NULL )
|
||||
{
|
||||
npoints += lwgeom_npoints_recursive(subgeom);
|
||||
}
|
||||
else
|
||||
{
|
||||
elog(ERROR, "What ? lwgeom_getsubgeometry_inspected returned NULL??");
|
||||
}
|
||||
}
|
||||
return npoints;
|
||||
}
|
||||
|
||||
//number of points in an object
|
||||
PG_FUNCTION_INFO_V1(lwgeom_npoints);
|
||||
Datum lwgeom_npoints(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
int32 npoints = 0;
|
||||
|
||||
npoints = lwgeom_npoints_recursive(SERIALIZED_FORM(geom));
|
||||
|
||||
PG_RETURN_INT32(npoints);
|
||||
}
|
||||
|
||||
// Find first linestring in serialized geometry and return
|
||||
// the number of points in it. If no linestrings are found
|
||||
// return -1.
|
||||
int32
|
||||
lwgeom_numpoints_linestring_recursive(char *serialized)
|
||||
{
|
||||
LWGEOM_INSPECTED *inspected = lwgeom_inspect(serialized);
|
||||
int i;
|
||||
|
||||
for (i=0; i<inspected->ngeometries; i++)
|
||||
{
|
||||
int32 npoints;
|
||||
int type;
|
||||
LWLINE *line=NULL;
|
||||
char *subgeom;
|
||||
|
||||
line = lwgeom_getline_inspected(inspected, i);
|
||||
if (line != NULL)
|
||||
{
|
||||
return line->points->npoints;
|
||||
}
|
||||
|
||||
subgeom = lwgeom_getsubgeometry_inspected(inspected, i);
|
||||
if ( subgeom == NULL )
|
||||
{
|
||||
elog(ERROR, "What ? lwgeom_getsubgeometry_inspected returned NULL??");
|
||||
}
|
||||
|
||||
type = lwgeom_getType(subgeom[0]);
|
||||
|
||||
// MULTILINESTRING && GEOMETRYCOLLECTION are worth checking
|
||||
if ( type != 7 && type != 5 ) continue;
|
||||
|
||||
npoints = lwgeom_numpoints_linestring_recursive(subgeom);
|
||||
if ( npoints == -1 ) continue;
|
||||
return npoints;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
//numpoints(GEOMETRY) -- find the first linestring in GEOMETRY, return
|
||||
//the number of points in it. Return NULL if there is no LINESTRING(..)
|
||||
//in GEOMETRY
|
||||
PG_FUNCTION_INFO_V1(lwgeom_numpoints_linestring);
|
||||
Datum lwgeom_numpoints_linestring(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
int32 ret;
|
||||
ret = lwgeom_numpoints_linestring_recursive(SERIALIZED_FORM(geom));
|
||||
if ( ret == -1 ) PG_RETURN_NULL();
|
||||
PG_RETURN_INT32(ret);
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(lwgeom_numgeometries_collection);
|
||||
Datum lwgeom_numgeometries_collection(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
int type;
|
||||
char *serialized = SERIALIZED_FORM(geom);
|
||||
|
||||
type = lwgeom_getType(geom->type);
|
||||
if ( type >= 4 )
|
||||
{
|
||||
PG_RETURN_INT32(lwgeom_getnumgeometries(serialized));
|
||||
}
|
||||
else
|
||||
{
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
}
|
||||
|
||||
PG_FUNCTION_INFO_V1(lwgeom_geometryn_collection);
|
||||
Datum lwgeom_geometryn_collection(PG_FUNCTION_ARGS)
|
||||
{
|
||||
LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0));
|
||||
LWGEOM *result;
|
||||
int size;
|
||||
int type = lwgeom_getType(geom->type);
|
||||
int32 idx;
|
||||
char *serialized;
|
||||
char *subgeom;
|
||||
|
||||
// call is valid on multi* geoms only
|
||||
if ( type < 4 )
|
||||
{
|
||||
//elog(NOTICE, "geometryn: geom is of type %d, requires >=4", type);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
idx = PG_GETARG_INT32(1);
|
||||
serialized = SERIALIZED_FORM(geom);
|
||||
|
||||
subgeom = lwgeom_getsubgeometry(serialized, idx);
|
||||
if ( subgeom == NULL )
|
||||
{
|
||||
//elog(NOTICE, "geometryn: subgeom %d does not exist", idx);
|
||||
PG_RETURN_NULL();
|
||||
}
|
||||
|
||||
// we have it, not it's time to make an LWGEOM
|
||||
size = lwgeom_seralizedformlength_simple(subgeom);
|
||||
result = palloc(size);
|
||||
memcpy(result, &size, 4);
|
||||
memcpy(SERIALIZED_FORM(result), subgeom, size);
|
||||
PG_RETURN_POINTER(result);
|
||||
|
||||
}
|
||||
|
|
|
@ -11,6 +11,9 @@
|
|||
--
|
||||
-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||
-- $Log$
|
||||
-- Revision 1.9 2004/08/24 09:34:33 strk
|
||||
-- Added npoints,numpoints,numgeometries,geometryn
|
||||
--
|
||||
-- Revision 1.8 2004/08/23 15:57:56 strk
|
||||
-- versioning functions completed
|
||||
--
|
||||
|
@ -808,7 +811,6 @@ CREATEFUNCTION setSRID(geometry,int4)
|
|||
AS '@MODULE_FILENAME@','LWGEOM_setSRID'
|
||||
LANGUAGE 'C' WITH (isstrict,iscachable);
|
||||
|
||||
|
||||
CREATEFUNCTION asText(geometry)
|
||||
RETURNS TEXT
|
||||
AS '@MODULE_FILENAME@','LWGEOM_asText'
|
||||
|
@ -829,6 +831,29 @@ CREATEFUNCTION summary(geometry)
|
|||
AS '@MODULE_FILENAME@', 'lwgeom_summary'
|
||||
LANGUAGE 'C' WITH (isstrict);
|
||||
|
||||
CREATEFUNCTION npoints(geometry)
|
||||
RETURNS int4
|
||||
AS '@MODULE_FILENAME@', 'lwgeom_npoints'
|
||||
LANGUAGE 'C' WITH (isstrict);
|
||||
|
||||
-- OGC
|
||||
CREATEFUNCTION numpoints(geometry)
|
||||
RETURNS int4
|
||||
AS '@MODULE_FILENAME@', 'lwgeom_numpoints_linestring'
|
||||
LANGUAGE 'C' WITH (isstrict);
|
||||
|
||||
-- OGC
|
||||
CREATEFUNCTION numgeometries(geometry)
|
||||
RETURNS int4
|
||||
AS '@MODULE_FILENAME@', 'lwgeom_numgeometries_collection'
|
||||
LANGUAGE 'C' WITH (isstrict);
|
||||
|
||||
-- OGC
|
||||
CREATEFUNCTION geometryn(geometry,integer)
|
||||
RETURNS geometry
|
||||
AS '@MODULE_FILENAME@', 'lwgeom_geometryn_collection'
|
||||
LANGUAGE 'C' WITH (isstrict);
|
||||
|
||||
|
||||
CREATEFUNCTION geometrytype(geometry)
|
||||
RETURNS text
|
||||
|
|
Loading…
Reference in a new issue