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:
Sandro Santilli 2004-08-24 09:34:33 +00:00
parent 537b7c3777
commit 840e565470
3 changed files with 208 additions and 5 deletions

View file

@ -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)]

View file

@ -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);
}

View file

@ -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