From 758ecf2bd9f10bd3caf8d7db0452b284458184cf Mon Sep 17 00:00:00 2001 From: David Blasby Date: Fri, 1 Aug 2003 23:58:08 +0000 Subject: [PATCH] added the functionality to convert GEOS->PostGIS geometries. Added those geos functions to postgis. git-svn-id: http://svn.osgeo.org/postgis/trunk@283 b70326c6-7e19-0410-871a-916f4a2858ee --- Attic/postgis_sql_common.sql.in | 43 ++ postgis_geos.c | 713 +++++++++++++++++++++++++++++++- postgis_geos_wrapper.cpp | 311 +++++++++++++- 3 files changed, 1065 insertions(+), 2 deletions(-) diff --git a/Attic/postgis_sql_common.sql.in b/Attic/postgis_sql_common.sql.in index 0555bd56f..b5d440eda 100644 --- a/Attic/postgis_sql_common.sql.in +++ b/Attic/postgis_sql_common.sql.in @@ -12,6 +12,10 @@ -- -- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -- $Log$ +-- Revision 1.12 2003/08/01 23:58:08 dblasby +-- added the functionality to convert GEOS->PostGIS geometries. Added those geos +-- functions to postgis. +-- -- Revision 1.11 2003/07/01 18:30:55 pramsey -- Added CVS revision headers. -- @@ -906,6 +910,45 @@ CREATE OPERATOR > ( -- GEOS Functions -- + +CREATE FUNCTION intersection(geometry,geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','intersection' + LANGUAGE 'C' WITH (isstrict); + +CREATE FUNCTION buffer(geometry,float8) + RETURNS geometry + AS '@MODULE_FILENAME@','buffer' + LANGUAGE 'C' WITH (isstrict); + + CREATE FUNCTION convexhull(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','convexhull' + LANGUAGE 'C' WITH (isstrict); + + + CREATE FUNCTION difference(geometry,geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','difference' + LANGUAGE 'C' WITH (isstrict); + + CREATE FUNCTION boundary(geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','boundary' + LANGUAGE 'C' WITH (isstrict); + + CREATE FUNCTION symdifference(geometry,geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','symdifference' + LANGUAGE 'C' WITH (isstrict); + + CREATE FUNCTION GeomUnion(geometry,geometry) + RETURNS geometry + AS '@MODULE_FILENAME@','geomunion' + LANGUAGE 'C' WITH (isstrict); + + + CREATE FUNCTION relate(geometry,geometry) RETURNS text AS '@MODULE_FILENAME@','relate_full' diff --git a/postgis_geos.c b/postgis_geos.c index 3af789bdd..d1d03f2ed 100644 --- a/postgis_geos.c +++ b/postgis_geos.c @@ -1,4 +1,3 @@ - /********************************************************************** * $Id$ * @@ -11,12 +10,19 @@ * ********************************************************************** * $Log$ + * Revision 1.5 2003/08/01 23:58:08 dblasby + * added the functionality to convert GEOS->PostGIS geometries. Added those geos + * functions to postgis. + * * Revision 1.4 2003/07/01 18:30:55 pramsey * Added CVS revision headers. * * **********************************************************************/ + +//-------------------------------------------------------------------------- +// #ifdef USE_GEOS #include "postgres.h" @@ -57,6 +63,8 @@ extern char GEOSrelateContains(Geometry *g1, Geometry*g2); extern char GEOSrelateOverlaps(Geometry *g1, Geometry*g2); extern char *GEOSasText(Geometry *g1); +extern char GEOSisEmpty(Geometry *g1); +extern char *GEOSGeometryType(Geometry *g1); extern void GEOSdeleteChar(char *a); @@ -76,6 +84,26 @@ extern char GEOSisvalid(Geometry *g1); extern char *throw_exception(Geometry *g); +extern Geometry *GEOSIntersection(Geometry *g1, Geometry *g2); + + +extern POINT3D *GEOSGetCoordinate(Geometry *g1); +extern POINT3D *GEOSGetCoordinates(Geometry *g1); +extern int GEOSGetNumCoordinate(Geometry *g1); +extern Geometry *GEOSGetGeometryN(Geometry *g1, int n); +extern Geometry *GEOSGetExteriorRing(Geometry *g1); +extern Geometry *GEOSGetInteriorRingN(Geometry *g1,int n); +extern int GEOSGetNumInteriorRings(Geometry *g1); +extern int GEOSGetSRID(Geometry *g1); +extern int GEOSGetNumGeometries(Geometry *g1); + +extern Geometry *GEOSBuffer(Geometry *g1,double width); +extern Geometry *GEOSConvexHull(Geometry *g1); +extern Geometry *GEOSDifference(Geometry *g1,Geometry *g2); +extern Geometry *GEOSBoundary(Geometry *g1); +extern Geometry *GEOSSymDifference(Geometry *g1,Geometry *g2); +extern Geometry *GEOSUnion(Geometry *g1,Geometry *g2); + @@ -91,10 +119,448 @@ Datum overlaps(PG_FUNCTION_ARGS); Datum isvalid(PG_FUNCTION_ARGS); +Datum buffer(PG_FUNCTION_ARGS); +Datum intersection(PG_FUNCTION_ARGS); +Datum convexhull(PG_FUNCTION_ARGS); +Datum difference(PG_FUNCTION_ARGS); +Datum boundary(PG_FUNCTION_ARGS); +Datum symdifference(PG_FUNCTION_ARGS); +Datum geomunion(PG_FUNCTION_ARGS); + Geometry *POSTGIS2GEOS(GEOMETRY *g); void errorIfGeometryCollection(GEOMETRY *g1, GEOMETRY *g2); +GEOMETRY *GEOS2POSTGIS(Geometry *g, char want3d ); + +POLYGON3D *PolyFromGeometry(Geometry *g, int *size); +LINE3D *LineFromGeometry(Geometry *g, int *size); + +//----------------------------------------------- // return a GEOS Geometry from a POSTGIS GEOMETRY +//---------------------------------------------- + + +//select geomunion('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5))'); +PG_FUNCTION_INFO_V1(geomunion); +Datum geomunion(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + GEOMETRY *geom2 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + Geometry *g1,*g2,*g3; + GEOMETRY *result; + char empty; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g2 = POSTGIS2GEOS(geom2 ); + g3 = GEOSUnion(g1,g2); + + if (g3 == NULL) + { + elog(ERROR,"GEOS union() threw an error!"); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + PG_RETURN_NULL(); //never get here + } + + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS union() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d || geom2->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS union() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + + + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); +} + + +// select symdifference('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5))'); +PG_FUNCTION_INFO_V1(symdifference); +Datum symdifference(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + GEOMETRY *geom2 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + Geometry *g1,*g2,*g3; + GEOMETRY *result; + char empty; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g2 = POSTGIS2GEOS(geom2 ); + g3 = GEOSSymDifference(g1,g2); + + if (g3 == NULL) + { + elog(ERROR,"GEOS symdifference() threw an error!"); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + PG_RETURN_NULL(); //never get here + } + + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS symdifference() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d || geom2->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS symdifference() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + + + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); +} + + +PG_FUNCTION_INFO_V1(boundary); +Datum boundary(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + + Geometry *g1,*g3; + GEOMETRY *result; + char empty; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g3 = GEOSBoundary(g1); + + if (g3 == NULL) + { + elog(ERROR,"GEOS bounary() threw an error!"); + GEOSdeleteGeometry(g1); + PG_RETURN_NULL(); //never get here + } + + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS bounary() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS bounary() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + + + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); +} + +PG_FUNCTION_INFO_V1(convexhull); +Datum convexhull(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + char empty; + Geometry *g1,*g3; + GEOMETRY *result; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g3 = GEOSConvexHull(g1); + + + if (g3 == NULL) + { + elog(ERROR,"GEOS convexhull() threw an error!"); + GEOSdeleteGeometry(g1); + PG_RETURN_NULL(); //never get here + } + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS convexhull() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS convexhull() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); + +} + +PG_FUNCTION_INFO_V1(buffer); +Datum buffer(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + double size = PG_GETARG_FLOAT8(1); + char empty; + Geometry *g1,*g3; + GEOMETRY *result; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g3 = GEOSBuffer(g1,size); + + + if (g3 == NULL) + { + elog(ERROR,"GEOS buffer() threw an error!"); + GEOSdeleteGeometry(g1); + PG_RETURN_NULL(); //never get here + } + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS buffer() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS buffer() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); + +} + + +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5))'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((25 5, 35 5, 35 7, 25 7, 25 5))'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POINT(5 5)'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','LINESTRING(5 5, 10 10)'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','MULTIPOINT(5 5, 7 7, 9 9, 10 10, 11 11)'); +//select intersection('POLYGON(( 0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5 ),(6 6,6.5 6, 6.5 6.5,6 6.5,6 6))'); + + +////select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','MULTIPOINT(5 5, 7 7, 9 9, 10 10, 11 11)'); +// select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','MULTILINESTRING((5 5, 10 10),(1 1, 2 2) )'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','MULTILINESTRING((5 5, 10 10),(1 1, 2 2) )'); +//select intersection('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','MULTIPOLYGON(((5 5, 15 5, 15 7, 5 7, 5 5)),((1 1,1 2,2 2,1 2, 1 1)))'); +PG_FUNCTION_INFO_V1(intersection); +Datum intersection(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + GEOMETRY *geom2 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + Geometry *g1,*g2,*g3; + GEOMETRY *result; + char empty; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g2 = POSTGIS2GEOS(geom2 ); + g3 = GEOSIntersection(g1,g2); + + if (g3 == NULL) + { + elog(ERROR,"GEOS Intersection() threw an error!"); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + PG_RETURN_NULL(); //never get here + } + + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS Intersection() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d || geom2->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS Intersection() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + + + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); +} + +//select difference('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))','POLYGON((5 5, 15 5, 15 7, 5 7, 5 5))'); +PG_FUNCTION_INFO_V1(difference); +Datum difference(PG_FUNCTION_ARGS) +{ + GEOMETRY *geom1 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(0)); + GEOMETRY *geom2 = (GEOMETRY *) PG_DETOAST_DATUM(PG_GETARG_DATUM(1)); + + Geometry *g1,*g2,*g3; + GEOMETRY *result; + char empty; + + initGEOS(MAXIMUM_ALIGNOF); + + g1 = POSTGIS2GEOS(geom1 ); + g2 = POSTGIS2GEOS(geom2 ); + g3 = GEOSDifference(g1,g2); + + if (g3 == NULL) + { + elog(ERROR,"GEOS difference() threw an error!"); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + PG_RETURN_NULL(); //never get here + } + + + empty = GEOSisEmpty(g3); + if (empty ==2) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS difference() threw an error (couldnt test empty on result)!"); + PG_RETURN_NULL(); //never get here + } + if (empty) + { + PG_RETURN_NULL(); + } + +// elog(NOTICE,"result: %s", GEOSasText(g3) ) ; + + result = GEOS2POSTGIS(g3, geom1->is3d || geom2->is3d); + if (result == NULL) + { + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + elog(ERROR,"GEOS difference() threw an error (result postgis geometry formation)!"); + PG_RETURN_NULL(); //never get here + } + + + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + GEOSdeleteGeometry(g3); + + PG_RETURN_POINTER(result); +} + + + +//---------------------------------------------- + void errorIfGeometryCollection(GEOMETRY *g1, GEOMETRY *g2) @@ -464,6 +930,251 @@ if ((g1==NULL) || (g2 == NULL)) } +POLYGON3D *PolyFromGeometry(Geometry *g, int *size) +{ + + int ninteriorrings =GEOSGetNumInteriorRings(g); + POINT3D *pts; + int *pts_per_ring; + int t; + POLYGON3D *poly; + int npoints; + + + npoints = GEOSGetNumCoordinate(g); + pts = GEOSGetCoordinates(g); + if (npoints <3) + { + GEOSdeleteChar( (char*) pts); + return NULL; + } + + pts_per_ring = palloc(sizeof(int) * (ninteriorrings+1)); + pts_per_ring[0] = GEOSGetNumCoordinate(GEOSGetExteriorRing(g)); + + for (t=0;t returns as a 2d polygon Geometry *POSTGIS2GEOS(GEOMETRY *g) { diff --git a/postgis_geos_wrapper.cpp b/postgis_geos_wrapper.cpp index e57bd5722..bf92dedb0 100644 --- a/postgis_geos_wrapper.cpp +++ b/postgis_geos_wrapper.cpp @@ -13,6 +13,8 @@ #include "io.h" //#include "opRelate.h" +using namespace geos; + //WARNING THIS *MUST* BE SET CORRECTLY. @@ -86,9 +88,31 @@ extern "C" char GEOSisvalid(Geometry *g1); extern "C" char *GEOSasText(Geometry *g1); +extern "C" char GEOSisEmpty(Geometry *g1); +extern "C" char *GEOSGeometryType(Geometry *g1); + extern "C" char *throw_exception(Geometry *g); +extern "C" Geometry *GEOSIntersection(Geometry *g1,Geometry *g1); +extern "C" Geometry *GEOSBuffer(Geometry *g1,double width); +extern "C" Geometry *GEOSConvexHull(Geometry *g1); +extern "C" Geometry *GEOSDifference(Geometry *g1,Geometry *g2); +extern "C" Geometry *GEOSBoundary(Geometry *g1); +extern "C" Geometry *GEOSSymDifference(Geometry *g1,Geometry *g2); +extern "C" Geometry *GEOSUnion(Geometry *g1,Geometry *g2); + + +extern "C" POINT3D *GEOSGetCoordinate(Geometry *g1); +extern "C" POINT3D *GEOSGetCoordinates(Geometry *g1); +extern "C" int GEOSGetNumCoordinate(Geometry *g1); +extern "C" Geometry *GEOSGetGeometryN(Geometry *g1, int n); +extern "C" Geometry *GEOSGetExteriorRing(Geometry *g1); +extern "C" Geometry *GEOSGetInteriorRingN(Geometry *g1, int n); +extern "C" int GEOSGetNumInteriorRings(Geometry *g1); +extern "C" int GEOSGetSRID(Geometry *g1); +extern "C" int GEOSGetNumGeometries(Geometry *g1); + //########################################################### @@ -204,6 +228,7 @@ Geometry *PostGIS2GEOS_linestring(LINE3D *line,int SRID, bool is3d) c.y = line->points[t].y; c.z = DoubleNotANumber; coords->setAt( c ,t); + } } @@ -571,6 +596,141 @@ char *GEOSasText(Geometry *g1) } } +char GEOSisEmpty(Geometry *g1) +{ + try + { + return g1->isEmpty(); + } + catch (...) + { + return 2; + } +} + +char *GEOSGeometryType(Geometry *g1) +{ + try + { + string s = g1->getGeometryType(); + + + char *result; + result = (char*) malloc( s.length() + 1); + strcpy(result, s.c_str() ); + return result; + } + catch (...) + { + return NULL; + } +} + + + + +//------------------------------------------------------------------- +// GEOS functions that return geometries +//------------------------------------------------------------------- + +Geometry *GEOSIntersection(Geometry *g1,Geometry *g2) +{ + try + { + Geometry *g3 = g1->intersection(g2); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSBuffer(Geometry *g1,double width) +{ + try + { + Geometry *g3 = g1->buffer(width); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSConvexHull(Geometry *g1) +{ + try + { + Geometry *g3 = g1->convexHull(); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSDifference(Geometry *g1,Geometry *g2) +{ + try + { + Geometry *g3 = g1->difference(g2); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSBoundary(Geometry *g1) +{ + try + { + Geometry *g3 = g1->getBoundary(); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSSymDifference(Geometry *g1,Geometry *g2) +{ + try + { + Geometry *g3 = g1->symDifference(g2); + return g3; + } + catch (...) + { + return NULL; + } +} + +Geometry *GEOSUnion(Geometry *g1,Geometry *g2) +{ + try + { + Geometry *g3 = g1->Union(g2); + return g3; + } + catch (...) + { + return NULL; + } +} + + + + + + + + //------------------------------------------------------------------- // memory management functions //------------------------------------------------------------------ @@ -591,12 +751,161 @@ void GEOSdeleteGeometry(Geometry *a) void GEOSdeleteChar(char *a) { try{ - delete a; + free(a); } catch(...) { // do nothing! } +} + + +//------------------------------------------------------------------- +//GEOS => POSTGIS conversions +//------------------------------------------------------------------- + +// free the result when done! +// g1 must be a point +POINT3D *GEOSGetCoordinate(Geometry *g1) +{ + try{ + POINT3D *result = (POINT3D*) malloc (sizeof(POINT3D)); + Coordinate *c =g1->getCoordinate(); + + result->x = c->x; + result->y = c->y; + result->z = c->z; + return result; + } + catch(...) + { + return NULL; + } + } + +//must free the result when done +// result is an array length g1->getNumCoordinates() +// only call on linestrings or linearrings +POINT3D *GEOSGetCoordinates(Geometry *g1) +{ + try { + int numPoints = g1->getNumPoints(); + POINT3D *result = (POINT3D*) malloc (sizeof(POINT3D) * numPoints ); + int t; + CoordinateList *cl = g1->getCoordinates(); + Coordinate c; + + for (t=0;tgetAt(t); + + result[t].x = c.x; + result[t].y = c.y; + result[t].z = c.z; + } + + return result; + } + catch(...) + { + return NULL; + } + +} + + + +int GEOSGetNumCoordinate(Geometry *g1) +{ + try{ + return g1->getNumPoints(); + } + catch(...) + { + return 0; + } +} + +int GEOSGetNumInteriorRings(Geometry *g1) +{ + try{ + Polygon *p = (Polygon *) g1; + return p->getNumInteriorRing(); + } + catch(...) + { + return 0; + } +} + + +//only call on GCs +int GEOSGetNumGeometries(Geometry *g1) +{ + try{ + GeometryCollection *gc = (GeometryCollection *) g1; + return gc->getNumGeometries(); + } + catch(...) + { + return 0; + } +} + + +//call only on GEOMETRYCOLLECTION or MULTI* +Geometry *GEOSGetGeometryN(Geometry *g1, int n) +{ + try{ + GeometryCollection *gc = (GeometryCollection *) g1; + return gc->getGeometryN(n); + } + catch(...) + { + return NULL; + } +} + + +//call only on polygon +Geometry *GEOSGetExteriorRing(Geometry *g1) +{ + try{ + Polygon *p = (Polygon *) g1; + return p->getExteriorRing(); + } + catch(...) + { + return 0; + } +} + +//call only on polygon +Geometry *GEOSGetInteriorRingN(Geometry *g1,int n) +{ + try{ + Polygon *p = (Polygon *) g1; + return p->getInteriorRingN(n); + } + catch(...) + { + return NULL; + } +} + + +int GEOSGetSRID(Geometry *g1) +{ + try{ + return g1->getSRID(); + } + catch(...) + { + return 0; + } +} + + -- 2.50.1