From 994e1f51bd32f4b58e5a24f7ba6130759fdc3698 Mon Sep 17 00:00:00 2001 From: Sandro Santilli Date: Tue, 24 Aug 2004 10:01:16 +0000 Subject: [PATCH] OGC functions (not implemented by GEOS) moved to lwgeom_ogc.c. Renamed PG-exposed functions to start with LWGEOM git-svn-id: http://svn.osgeo.org/postgis/trunk@730 b70326c6-7e19-0410-871a-916f4a2858ee --- lwgeom/Makefile | 2 +- lwgeom/lwgeom_functions_basic.c | 196 ++--------------------------- lwgeom/lwgeom_ogc.c | 213 ++++++++++++++++++++++++++++++++ lwgeom/lwpostgis.sql.in | 24 ++-- 4 files changed, 241 insertions(+), 194 deletions(-) create mode 100644 lwgeom/lwgeom_ogc.c diff --git a/lwgeom/Makefile b/lwgeom/Makefile index 9faac3760..4b5081e4f 100644 --- a/lwgeom/Makefile +++ b/lwgeom/Makefile @@ -132,7 +132,7 @@ ifeq ($(USE_STATS),1) override CFLAGS += -DUSE_STATS endif -OBJS=lwgeom_api.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box2dfloat4.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o $(GEOS_WRAPPER) +OBJS=lwgeom_api.o lwgeom_ogc.o lwgeom_functions_analytic.o lwgeom_geos.o lwgeom_inout.o lwgeom_estimate.o lwgeom_functions_basic.o lwgeom_gist.o lwgeom_btree.o lwgeom_transform.o stringBuffer.o lwgeom_box2dfloat4.o lex.yy.o wktparse.tab.o lwgparse.o wktunparse.o $(GEOS_WRAPPER) OTHERS=y.output lex.yy.c wktparse.tab.c wktparse.tab.h lwgeom.sql lwpostgis.sql diff --git a/lwgeom/lwgeom_functions_basic.c b/lwgeom/lwgeom_functions_basic.c index d4631615c..6f94e3bfc 100644 --- a/lwgeom/lwgeom_functions_basic.c +++ b/lwgeom/lwgeom_functions_basic.c @@ -24,84 +24,20 @@ #include "wktparse.h" -Datum LWGEOM_getSRID(PG_FUNCTION_ARGS); -Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS); -Datum LWGEOM_setSRID(PG_FUNCTION_ARGS); Datum combine_box2d(PG_FUNCTION_ARGS); -Datum lwgeom_mem_size(PG_FUNCTION_ARGS); -Datum lwgeom_summary(PG_FUNCTION_ARGS); +Datum LWGEOM_mem_size(PG_FUNCTION_ARGS); +Datum LWGEOM_summary(PG_FUNCTION_ARGS); +Datum LWGEOM_npoints(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); + +// internal 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); -Datum LWGEOM_getSRID(PG_FUNCTION_ARGS) -{ - LWGEOM *lwgeom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - int srid = lwgeom_getSRID (lwgeom); - - PG_RETURN_INT32(srid); -} - -//setSRID(lwgeom, int4) :: lwgeom -PG_FUNCTION_INFO_V1(LWGEOM_setSRID); -Datum LWGEOM_setSRID(PG_FUNCTION_ARGS) -{ - LWGEOM *lwgeom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - int newSRID = PG_GETARG_INT32(1); - LWGEOM *result; - - result = lwgeom_setSRID(lwgeom, newSRID); - PG_RETURN_POINTER(result); -} - -//returns a string representation of this geometry's type -PG_FUNCTION_INFO_V1(LWGEOM_getTYPE); -Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS) -{ - LWGEOM *lwgeom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); - char *text_ob = palloc(20+4); - char *result = text_ob+4; - int32 size; - unsigned char type; - - //type = lwgeom_getType(*(lwgeom+4)); - type = lwgeom_getType(lwgeom->type); - - memset(result, 0, 20); - - if (type == POINTTYPE) - strcpy(result,"POINT"); - else if (type == MULTIPOINTTYPE) - strcpy(result,"MULTIPOINT"); - else if (type == LINETYPE) - strcpy(result,"LINESTRING"); - else if (type == MULTILINETYPE) - strcpy(result,"MULTILINESTRING"); - else if (type == POLYGONTYPE) - strcpy(result,"POLYGON"); - else if (type == MULTIPOLYGONTYPE) - strcpy(result,"MULTIPOLYGON"); - else if (type == COLLECTIONTYPE) - strcpy(result,"GEOMETRYCOLLECTION"); - else - strcpy(result,"UNKNOWN"); - - size = strlen(result) +4 ; - - memcpy(text_ob, &size,4); // size of string - - PG_RETURN_POINTER(text_ob); -} +/*------------------------------------------------------------------*/ PG_FUNCTION_INFO_V1(combine_box2d); Datum combine_box2d(PG_FUNCTION_ARGS) @@ -152,8 +88,8 @@ Datum combine_box2d(PG_FUNCTION_ARGS) } //find the size of geometry -PG_FUNCTION_INFO_V1(lwgeom_mem_size); -Datum lwgeom_mem_size(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_mem_size); +Datum LWGEOM_mem_size(PG_FUNCTION_ARGS) { LWGEOM *geom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); int32 size = geom->size; @@ -260,8 +196,8 @@ lwgeom_summary_recursive(char *serialized, int offset) } //get summary info on a GEOMETRY -PG_FUNCTION_INFO_V1(lwgeom_summary); -Datum lwgeom_summary(PG_FUNCTION_ARGS) +PG_FUNCTION_INFO_V1(LWGEOM_summary); +Datum LWGEOM_summary(PG_FUNCTION_ARGS) { LWGEOM *geom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); char *result; @@ -365,8 +301,8 @@ lwgeom_npoints_recursive(char *serialized) } //number of points in an object -PG_FUNCTION_INFO_V1(lwgeom_npoints); -Datum lwgeom_npoints(PG_FUNCTION_ARGS) +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; @@ -376,111 +312,3 @@ Datum lwgeom_npoints(PG_FUNCTION_ARGS) 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; ingeometries; 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); - -} diff --git a/lwgeom/lwgeom_ogc.c b/lwgeom/lwgeom_ogc.c new file mode 100644 index 000000000..a8534cd2c --- /dev/null +++ b/lwgeom/lwgeom_ogc.c @@ -0,0 +1,213 @@ +#include "postgres.h" + +#include +#include +#include +#include +#include + +#include "access/gist.h" +#include "access/itup.h" +#include "access/rtree.h" + +#include "fmgr.h" +#include "utils/elog.h" + + +#include "lwgeom.h" + + +#define DEBUG + +#include "wktparse.h" + +// ---- SRID(geometry) +Datum LWGEOM_getSRID(PG_FUNCTION_ARGS); +// ---- SetSRID(geometry, integer) +Datum LWGEOM_setSRID(PG_FUNCTION_ARGS); +// ---- GeometryType(geometry) +Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS); +// ---- NumPoints(geometry) +Datum LWGEOM_numpoints_linestring(PG_FUNCTION_ARGS); +// ---- NumGeometries(geometry) +Datum LWGEOM_numgeometries_collection(PG_FUNCTION_ARGS); +// ---- GeometryN(geometry, integer) +Datum LWGEOM_geometryn_collection(PG_FUNCTION_ARGS); + + +// internal +int32 lwgeom_numpoints_linestring_recursive(char *serialized); + +/*------------------------------------------------------------------*/ + +// getSRID(lwgeom) :: int4 +PG_FUNCTION_INFO_V1(LWGEOM_getSRID); +Datum LWGEOM_getSRID(PG_FUNCTION_ARGS) +{ + LWGEOM *lwgeom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + int srid = lwgeom_getSRID (lwgeom); + + PG_RETURN_INT32(srid); +} + +//setSRID(lwgeom, int4) :: lwgeom +PG_FUNCTION_INFO_V1(LWGEOM_setSRID); +Datum LWGEOM_setSRID(PG_FUNCTION_ARGS) +{ + LWGEOM *lwgeom = (LWGEOM *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + int newSRID = PG_GETARG_INT32(1); + LWGEOM *result; + + result = lwgeom_setSRID(lwgeom, newSRID); + + PG_RETURN_POINTER(result); +} + +//returns a string representation of this geometry's type +PG_FUNCTION_INFO_V1(LWGEOM_getTYPE); +Datum LWGEOM_getTYPE(PG_FUNCTION_ARGS) +{ + LWGEOM *lwgeom = (LWGEOM *)PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char *text_ob = palloc(20+4); + char *result = text_ob+4; + int32 size; + unsigned char type; + + //type = lwgeom_getType(*(lwgeom+4)); + type = lwgeom_getType(lwgeom->type); + + memset(result, 0, 20); + + if (type == POINTTYPE) + strcpy(result,"POINT"); + else if (type == MULTIPOINTTYPE) + strcpy(result,"MULTIPOINT"); + else if (type == LINETYPE) + strcpy(result,"LINESTRING"); + else if (type == MULTILINETYPE) + strcpy(result,"MULTILINESTRING"); + else if (type == POLYGONTYPE) + strcpy(result,"POLYGON"); + else if (type == MULTIPOLYGONTYPE) + strcpy(result,"MULTIPOLYGON"); + else if (type == COLLECTIONTYPE) + strcpy(result,"GEOMETRYCOLLECTION"); + else + strcpy(result,"UNKNOWN"); + + size = strlen(result) +4 ; + + memcpy(text_ob, &size,4); // size of string + + PG_RETURN_POINTER(text_ob); +} + +// 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; ingeometries; 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); + +} + diff --git a/lwgeom/lwpostgis.sql.in b/lwgeom/lwpostgis.sql.in index 5cac17f4a..a540f4caa 100644 --- a/lwgeom/lwpostgis.sql.in +++ b/lwgeom/lwpostgis.sql.in @@ -11,6 +11,10 @@ -- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- $Log$ +-- Revision 1.10 2004/08/24 10:01:16 strk +-- OGC functions (not implemented by GEOS) moved to lwgeom_ogc.c. +-- Renamed PG-exposed functions to start with LWGEOM +-- -- Revision 1.9 2004/08/24 09:34:33 strk -- Added npoints,numpoints,numgeometries,geometryn -- @@ -821,39 +825,41 @@ CREATEFUNCTION getbbox(geometry) AS '@MODULE_FILENAME@','LWGEOM_to_BOX2DFLOAT4' LANGUAGE 'C' WITH (isstrict,iscachable); +-- DEBUG + CREATEFUNCTION mem_size(geometry) RETURNS int4 - AS '@MODULE_FILENAME@', 'lwgeom_mem_size' + AS '@MODULE_FILENAME@', 'LWGEOM_mem_size' LANGUAGE 'C' WITH (isstrict); CREATEFUNCTION summary(geometry) RETURNS text - AS '@MODULE_FILENAME@', 'lwgeom_summary' + AS '@MODULE_FILENAME@', 'LWGEOM_summary' LANGUAGE 'C' WITH (isstrict); CREATEFUNCTION npoints(geometry) RETURNS int4 - AS '@MODULE_FILENAME@', 'lwgeom_npoints' + AS '@MODULE_FILENAME@', 'LWGEOM_npoints' LANGUAGE 'C' WITH (isstrict); --- OGC +------------------------------------------------------------------------ + CREATEFUNCTION numpoints(geometry) RETURNS int4 - AS '@MODULE_FILENAME@', 'lwgeom_numpoints_linestring' + AS '@MODULE_FILENAME@', 'LWGEOM_numpoints_linestring' LANGUAGE 'C' WITH (isstrict); --- OGC CREATEFUNCTION numgeometries(geometry) RETURNS int4 - AS '@MODULE_FILENAME@', 'lwgeom_numgeometries_collection' + AS '@MODULE_FILENAME@', 'LWGEOM_numgeometries_collection' LANGUAGE 'C' WITH (isstrict); --- OGC CREATEFUNCTION geometryn(geometry,integer) RETURNS geometry - AS '@MODULE_FILENAME@', 'lwgeom_geometryn_collection' + AS '@MODULE_FILENAME@', 'LWGEOM_geometryn_collection' LANGUAGE 'C' WITH (isstrict); +------------------------------------------------------------------------ CREATEFUNCTION geometrytype(geometry) RETURNS text -- 2.40.0