From: David Blasby Date: Tue, 27 May 2003 22:35:14 +0000 (+0000) Subject: New version of the postgis-GEOS connector. X-Git-Tag: pgis_0_8_0~107 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=bd330b6c231087553709a27aeb47be2ae418454f;p=postgis New version of the postgis-GEOS connector. git-svn-id: http://svn.osgeo.org/postgis/trunk@275 b70326c6-7e19-0410-871a-916f4a2858ee --- diff --git a/Makefile b/Makefile index 5fe5d17b1..33ab7f5d4 100644 --- a/Makefile +++ b/Makefile @@ -3,14 +3,14 @@ #--------------------------------------------------------------- # Set USE_PROJ to 1 for Proj4 reprojection support # -USE_PROJ=0 +USE_PROJ=1 PROJ_DIR=/usr/local #--------------------------------------------------------------- # Set USE_GEOS to 1 for GEOS spatial predicate and operator # support # -USE_GEOS=0 +USE_GEOS=1 GEOS_DIR=/usr/local #--------------------------------------------------------------- @@ -69,7 +69,7 @@ SO_MINOR_VERSION=8 #--------------------------------------------------------------- -override CFLAGS += -g +override CFLAGS += -g -fexceptions override CFLAGS += -I$(srcdir) -DFRONTEND -DSYSCONFDIR='"$(sysconfdir)"' override CFLAGS += -DUSE_VERSION=$(USE_VERSION) diff --git a/postgis_geos.c b/postgis_geos.c index 166bac902..7c4bd4884 100644 --- a/postgis_geos.c +++ b/postgis_geos.c @@ -32,14 +32,14 @@ typedef struct Geometry Geometry; extern const char * createGEOSPoint(POINT3D *pt); extern void initGEOS(int maxalign); extern char *GEOSrelate(Geometry *g1, Geometry*g2); -extern bool GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat); -extern bool GEOSrelateDisjoint(Geometry *g1, Geometry*g2); -extern bool GEOSrelateTouches(Geometry *g1, Geometry*g2); -extern bool GEOSrelateIntersects(Geometry *g1, Geometry*g2); -extern bool GEOSrelateCrosses(Geometry *g1, Geometry*g2); -extern bool GEOSrelateWithin(Geometry *g1, Geometry*g2); -extern bool GEOSrelateContains(Geometry *g1, Geometry*g2); -extern bool GEOSrelateOverlaps(Geometry *g1, Geometry*g2); +extern char GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat); +extern char GEOSrelateDisjoint(Geometry *g1, Geometry*g2); +extern char GEOSrelateTouches(Geometry *g1, Geometry*g2); +extern char GEOSrelateIntersects(Geometry *g1, Geometry*g2); +extern char GEOSrelateCrosses(Geometry *g1, Geometry*g2); +extern char GEOSrelateWithin(Geometry *g1, Geometry*g2); +extern char GEOSrelateContains(Geometry *g1, Geometry*g2); +extern char GEOSrelateOverlaps(Geometry *g1, Geometry*g2); extern char *GEOSasText(Geometry *g1); @@ -56,7 +56,12 @@ extern Geometry *PostGIS2GEOS_multipoint(POINT3D **points,int npoints, int SRID, extern Geometry *PostGIS2GEOS_box3d(BOX3D *box, int SRID); extern Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms,int SRID, bool is3d); -extern bool GEOSisvalid(Geometry *g1); +extern char GEOSisvalid(Geometry *g1); + + + +extern char *throw_exception(Geometry *g); + Datum relate_full(PG_FUNCTION_ARGS); @@ -68,8 +73,6 @@ Datum crosses(PG_FUNCTION_ARGS); Datum within(PG_FUNCTION_ARGS); Datum contains(PG_FUNCTION_ARGS); Datum overlaps(PG_FUNCTION_ARGS); - - Datum isvalid(PG_FUNCTION_ARGS); @@ -95,13 +98,23 @@ Datum isvalid(PG_FUNCTION_ARGS) initGEOS(MAXIMUM_ALIGNOF); g1 = POSTGIS2GEOS(geom1 ); + result = GEOSisvalid(g1); + GEOSdeleteGeometry(g1); + if (result == 2) + { + elog(ERROR,"GEOS isvalid() threw an error!"); + PG_RETURN_NULL(); //never get here + } - GEOSdeleteGeometry(g1); PG_RETURN_BOOL(result); } + +// overlaps(GEOMETRY g1,GEOMETRY g2) +// returns if GEOS::g1->overlaps(g2) returns true +// throws an error (elog(ERROR,...)) if GEOS throws an error PG_FUNCTION_INFO_V1(overlaps); Datum overlaps(PG_FUNCTION_ARGS) { @@ -118,12 +131,16 @@ Datum overlaps(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); - - result = GEOSrelateOverlaps(g1,g2); - GEOSdeleteGeometry(g1); GEOSdeleteGeometry(g2); + result = GEOSrelateOverlaps(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS overlaps() threw an error!"); + PG_RETURN_NULL(); //never get here + } + PG_RETURN_BOOL(result); } @@ -145,11 +162,17 @@ Datum contains(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); result = GEOSrelateContains(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS contains() threw an error!"); + PG_RETURN_NULL(); //never get here + } + - GEOSdeleteGeometry(g1); - GEOSdeleteGeometry(g2); PG_RETURN_BOOL(result); } @@ -171,11 +194,16 @@ Datum within(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); - - result = GEOSrelateWithin(g1,g2); - GEOSdeleteGeometry(g1); GEOSdeleteGeometry(g2); + result = GEOSrelateWithin(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS within() threw an error!"); + PG_RETURN_NULL(); //never get here + } + + PG_RETURN_BOOL(result); } @@ -198,11 +226,17 @@ Datum crosses(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); result = GEOSrelateCrosses(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS crosses() threw an error!"); + PG_RETURN_NULL(); //never get here + } + - GEOSdeleteGeometry(g1); - GEOSdeleteGeometry(g2); PG_RETURN_BOOL(result); } @@ -225,11 +259,17 @@ Datum intersects(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); result = GEOSrelateIntersects(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS intersects() threw an error!"); + PG_RETURN_NULL(); //never get here + } + - GEOSdeleteGeometry(g1); - GEOSdeleteGeometry(g2); PG_RETURN_BOOL(result); } @@ -251,11 +291,17 @@ Datum touches(PG_FUNCTION_ARGS) g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); result = GEOSrelateTouches(g1,g2); + if (result == 2) + { + elog(ERROR,"GEOS touches() threw an error!"); + PG_RETURN_NULL(); //never get here + } + - GEOSdeleteGeometry(g1); - GEOSdeleteGeometry(g2); PG_RETURN_BOOL(result); } @@ -279,10 +325,15 @@ Datum disjoint(PG_FUNCTION_ARGS) result = GEOSrelateDisjoint(g1,g2); - GEOSdeleteGeometry(g1); GEOSdeleteGeometry(g2); + if (result == 2) + { + elog(ERROR,"GEOS disjoin() threw an error!"); + PG_RETURN_NULL(); //never get here + } + PG_RETURN_BOOL(result); } @@ -309,12 +360,16 @@ Datum relate_pattern(PG_FUNCTION_ARGS) PointerGetDatum(PG_GETARG_DATUM(2)))); result = GEOSrelatePattern(g1,g2,patt); - - GEOSdeleteGeometry(g1); GEOSdeleteGeometry(g2); - pfree(patt); + + if (result == 2) + { + elog(ERROR,"GEOS relate_pattern() threw an error!"); + PG_RETURN_NULL(); //never get here + } + PG_RETURN_BOOL(result); @@ -333,24 +388,51 @@ Datum relate_full(PG_FUNCTION_ARGS) int len; char *result; +//elog(NOTICE,"in relate_full()"); + errorIfGeometryCollection(geom1,geom2); -//elog(NOTICE,"in relate_full: \n"); + initGEOS(MAXIMUM_ALIGNOF); -//elog(NOTICE,"making GOES geometries: \n"); +//elog(NOTICE,"GEOS init()"); + g1 = POSTGIS2GEOS(geom1 ); g2 = POSTGIS2GEOS(geom2 ); -// elog(NOTICE,"geometries made, here's what they are: \n"); -//g1 = createGEOSFromText("POINT(1 1)"); -//g2 = createGEOSFromText("POINT(1 1)"); + +//elog(NOTICE,"constructed geometries "); + + + + + +if ((g1==NULL) || (g2 == NULL)) + elog(NOTICE,"g1 or g2 are null"); + //elog(NOTICE,GEOSasText(g1)); //elog(NOTICE,GEOSasText(g2)); -//elog(NOTICE,"calling relate: \n"); - relate_str = GEOSrelate(g1, g2); +//elog(NOTICE,"valid g1 = %i", GEOSisvalid(g1)); +//elog(NOTICE,"valid g2 = %i",GEOSisvalid(g2)); + +//elog(NOTICE,"about to relate()"); + + + relate_str = GEOSrelate(g1, g2); -//elog(NOTICE,"relate finished \n"); +//elog(NOTICE,"finished relate()"); + + GEOSdeleteGeometry(g1); + GEOSdeleteGeometry(g2); + + + + if (relate_str == NULL) + { + //free(relate_str); + elog(ERROR,"GEOS relate() threw an error!"); + PG_RETURN_NULL(); //never get here + } len = strlen(relate_str) + 4; @@ -361,8 +443,7 @@ Datum relate_full(PG_FUNCTION_ARGS) memcpy(result +4, relate_str, len-4); free(relate_str); -// GEOSdeleteGeometry(g1); -// GEOSdeleteGeometry(g2); + PG_RETURN_POINTER(result); } @@ -382,6 +463,7 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) char *obj; int obj_type; int t; + Geometry *result; int32 *offsets1 = (int32 *) ( ((char *) &(g->objType[0] ))+ sizeof(int32) * g->nobjs ) ; @@ -389,15 +471,30 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) { case POINTTYPE: pt = (POINT3D*) ((char *) g +offsets1[0]) ; - return PostGIS2GEOS_point(pt,g->SRID,g->is3d); + result = PostGIS2GEOS_point(pt,g->SRID,g->is3d); + if (result == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } + return result; break; case LINETYPE: line = (LINE3D*) ((char *) g +offsets1[0]) ; - return PostGIS2GEOS_linestring(line,g->SRID,g->is3d); + result = PostGIS2GEOS_linestring(line,g->SRID,g->is3d); + if (result == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } + return result; break; case POLYGONTYPE: poly = (POLYGON3D*) ((char *) g +offsets1[0]) ; - return PostGIS2GEOS_polygon(poly,g->SRID,g->is3d); + result = PostGIS2GEOS_polygon(poly,g->SRID,g->is3d); + if (result == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } + return result; break; case MULTIPOLYGONTYPE: //make an array of POLYGON3Ds @@ -408,6 +505,10 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) } geos= PostGIS2GEOS_multipolygon(polys, g->nobjs, g->SRID,g->is3d); pfree(polys); + if (geos == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } return geos; break; case MULTILINETYPE: @@ -419,6 +520,10 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) } geos= PostGIS2GEOS_multilinestring(lines, g->nobjs, g->SRID,g->is3d); pfree(lines); + if (geos == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } return geos; break; case MULTIPOINTTYPE: @@ -430,11 +535,20 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) } geos= PostGIS2GEOS_multipoint(points, g->nobjs,g->SRID,g->is3d); pfree(points); + if (geos == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } return geos; break; case BBOXONLYTYPE: - return PostGIS2GEOS_box3d(&g->bvol, g->SRID); - break; + result = PostGIS2GEOS_box3d(&g->bvol, g->SRID); + if (result == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } + return result; + break; case COLLECTIONTYPE: //make an array of GEOS Geometrys geoms = (Geometry**) palloc(sizeof (Geometry*) * g->nobjs); @@ -447,19 +561,41 @@ Geometry *POSTGIS2GEOS(GEOMETRY *g) case POINTTYPE: pt = (POINT3D*) obj ; geoms[t] = PostGIS2GEOS_point(pt,g->SRID,g->is3d); + if (geoms[t] == NULL) + { + pfree(geoms); + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + return NULL; + } break; case LINETYPE: line = (LINE3D*) obj ; geoms[t] = PostGIS2GEOS_linestring(line,g->SRID,g->is3d); + if (geoms[t] == NULL) + { + pfree(geoms); + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + return NULL; + } break; case POLYGONTYPE: poly = (POLYGON3D*) obj ; geoms[t] = PostGIS2GEOS_polygon(poly,g->SRID,g->is3d); + if (geoms[t] == NULL) + { + pfree(geoms); + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + return NULL; + } break; } } geos= PostGIS2GEOS_collection(geoms,g->nobjs,g->SRID,g->is3d); pfree(geoms); + if (geos == NULL) + { + elog(ERROR,"Couldnt convert the postgis geometry to GEOS!"); + } return geos; break; diff --git a/postgis_geos_wrapper.cpp b/postgis_geos_wrapper.cpp index 747a8828a..e57bd5722 100644 --- a/postgis_geos_wrapper.cpp +++ b/postgis_geos_wrapper.cpp @@ -52,23 +52,6 @@ typedef struct POINT3D points[1]; // array of actual points } POLYGON3D; -typedef struct -{ - int32 size; // postgres variable-length type requirement - int32 SRID; // spatial reference system id - double offsetX; // for precision grid (future improvement) - double offsetY; // for precision grid (future improvement) - double scale; // for precision grid (future improvement) - int32 type; // this type of geometry - bool is3d; // true if the points are 3d (only for output) - BOX3D bvol; // bounding volume of all the geo objects - int32 nobjs; // how many sub-objects in this object - int32 objType[1]; // type of object - int32 objOffset[1];// offset (in bytes) into this structure where - // the object is located - char objData[1]; // store for actual objects - -} GEOMETRY; //########################################################### @@ -79,14 +62,14 @@ extern "C" void initGEOS(int maxalign); extern "C" void GEOSdeleteChar(char *a); extern "C" void GEOSdeleteGeometry(Geometry *a); -extern "C" bool GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat); -extern "C" bool GEOSrelateDisjoint(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateTouches(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateIntersects(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateCrosses(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateWithin(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateContains(Geometry *g1, Geometry*g2); -extern "C" bool GEOSrelateOverlaps(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat); +extern "C" char GEOSrelateDisjoint(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateTouches(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateIntersects(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateCrosses(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateWithin(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateContains(Geometry *g1, Geometry*g2); +extern "C" char GEOSrelateOverlaps(Geometry *g1, Geometry*g2); extern "C" Geometry *PostGIS2GEOS_point(POINT3D *point,int SRID, bool is3d); @@ -99,13 +82,19 @@ extern "C" Geometry *PostGIS2GEOS_multipoint(POINT3D **points,int npoints, int S extern "C" Geometry *PostGIS2GEOS_box3d(BOX3D *box, int SRID); extern "C" Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms,int SRID, bool is3d); -extern "C" bool GEOSisvalid(Geometry *g1); +extern "C" char GEOSisvalid(Geometry *g1); + + +extern "C" char *GEOSasText(Geometry *g1); + +extern "C" char *throw_exception(Geometry *g); //########################################################### GeometryFactory *geomFactory = NULL; + void initGEOS (int maxalign) { if (geomFactory == NULL) @@ -115,131 +104,201 @@ void initGEOS (int maxalign) } } +// ------------------------------------------------------------------------------ +// geometry constuctors - return NULL if there was an error +//------------------------------------------------------------------------------- + + + //note: you lose the 3d from this! Geometry *PostGIS2GEOS_box3d(BOX3D *box, int SRID) { - Geometry *g; - Envelope *envelope = new Envelope(box->LLB.x,box->URT.x ,box->LLB.y,box->URT.y); - g = geomFactory->toGeometry(envelope,geomFactory->getPrecisionModel(), SRID); - delete envelope; - return g; + try { + Geometry *g; + Envelope *envelope = new Envelope(box->LLB.x,box->URT.x ,box->LLB.y,box->URT.y); + g = geomFactory->toGeometry(envelope,geomFactory->getPrecisionModel(), SRID); + if (g==NULL) + return NULL; + g->setSRID(SRID); + delete envelope; + return g; + } + catch (...) + { + return NULL; + } } Geometry *PostGIS2GEOS_collection(Geometry **geoms, int ngeoms,int SRID, bool is3d) { - Geometry *g; - int t; - vector *subGeos=new vector; + try + { + Geometry *g; + int t; + vector *subGeos=new vector; - for (t =0; t< ngeoms; t++) + for (t =0; t< ngeoms; t++) + { + subGeos->push_back(geoms[t]); + } + g = geomFactory->buildGeometry(subGeos); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) { - subGeos->push_back(geoms[t]); + return NULL; } - g = geomFactory->buildGeometry(subGeos); - g->setSRID(SRID); - return g; - } Geometry *PostGIS2GEOS_point(POINT3D *point,int SRID, bool is3d) { - Coordinate *c; - - if (is3d) - c = new Coordinate(point->x, point->y); - else - c = new Coordinate(point->x, point->y, point->z); - Geometry *g = geomFactory->createPoint(*c); - g->setSRID(SRID); - return g; + try + { + Coordinate *c; + + if (is3d) + c = new Coordinate(point->x, point->y); + else + c = new Coordinate(point->x, point->y, point->z); + Geometry *g = geomFactory->createPoint(*c); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) + { + return NULL; + } } Geometry *PostGIS2GEOS_linestring(LINE3D *line,int SRID, bool is3d) { - int t; - Coordinate c; + try{ - //build coordinatelist & pre-allocate space - BasicCoordinateList *coords = new BasicCoordinateList(line->npoints); - if (is3d) - { - for (t=0;tnpoints;t++) - { - c.x = line->points[t].x; - c.y = line->points[t].y; - c.z = line->points[t].z; - coords->setAt( c ,t); - } + int t; + Coordinate c; - } - else //make 2d points - { - for (t=0;tnpoints;t++) - { - c.x = line->points[t].x; - c.y = line->points[t].y; - c.z = DoubleNotANumber; - coords->setAt( c ,t); - } + //build coordinatelist & pre-allocate space + BasicCoordinateList *coords = new BasicCoordinateList(line->npoints); + if (is3d) + { + for (t=0;tnpoints;t++) + { + c.x = line->points[t].x; + c.y = line->points[t].y; + c.z = line->points[t].z; + coords->setAt( c ,t); + } + + } + else //make 2d points + { + for (t=0;tnpoints;t++) + { + c.x = line->points[t].x; + c.y = line->points[t].y; + c.z = DoubleNotANumber; + coords->setAt( c ,t); + } + } + Geometry *g = geomFactory->createLineString(coords); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) + { + return NULL; } - Geometry *g = geomFactory->createLineString(coords); - g->setSRID(SRID); - return g; } //polygons is an array of pointers to polygons Geometry *PostGIS2GEOS_multipolygon(POLYGON3D **polygons,int npolys, int SRID, bool is3d) { - int t; - vector *subPolys=new vector; - Geometry *g; + try + { + int t; + vector *subPolys=new vector; + Geometry *g; - for (t =0; t< npolys; t++) + for (t =0; t< npolys; t++) + { + subPolys->push_back(PostGIS2GEOS_polygon(polygons[t], SRID,is3d )); + } + g = geomFactory->createMultiPolygon(subPolys); + if (g== NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) { - subPolys->push_back(PostGIS2GEOS_polygon(polygons[t], SRID,is3d )); + return NULL; } - g = geomFactory->createMultiPolygon(subPolys); - g->setSRID(SRID); - return g; } //lines is an array of pointers to line3d Geometry *PostGIS2GEOS_multilinestring(LINE3D **lines,int nlines, int SRID, bool is3d) { - int t; - vector *subLines =new vector; - Geometry *g; + try + { + int t; + vector *subLines =new vector; + Geometry *g; - for (t =0; t< nlines; t++) + for (t =0; t< nlines; t++) + { + subLines->push_back(PostGIS2GEOS_linestring(lines[t], SRID,is3d )); + } + g = geomFactory->createMultiLineString(subLines); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) { - subLines->push_back(PostGIS2GEOS_linestring(lines[t], SRID,is3d )); + return NULL; } - g = geomFactory->createMultiLineString(subLines); - g->setSRID(SRID); - return g; } Geometry *PostGIS2GEOS_multipoint(POINT3D **points,int npoints, int SRID, bool is3d) { - int t; - vector *subPoints =new vector; - Geometry *g; + try + { + int t; + vector *subPoints =new vector; + Geometry *g; - for (t =0; t< npoints; t++) + for (t =0; t< npoints; t++) + { + subPoints->push_back(PostGIS2GEOS_point(points[t], SRID,is3d )); + } + g = geomFactory->createMultiPoint(subPoints); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) { - subPoints->push_back(PostGIS2GEOS_point(points[t], SRID,is3d )); + return NULL; } - g = geomFactory->createMultiPoint(subPoints); - g->setSRID(SRID); - return g; } Geometry *PostGIS2GEOS_polygon(POLYGON3D *polygon,int SRID, bool is3d) { + try + { POINT3D *pts; Coordinate c; int ring,t; @@ -276,7 +335,9 @@ Geometry *PostGIS2GEOS_polygon(POLYGON3D *polygon,int SRID, bool is3d) cl->setAt( c ,t); } } - outerRing = geomFactory->createLinearRing(cl); + outerRing = (LinearRing*) geomFactory->createLinearRing(cl); + if (outerRing == NULL) + return NULL; outerRing->setSRID(SRID); pointOffset = polygon->npoints[0]; @@ -303,99 +364,239 @@ Geometry *PostGIS2GEOS_polygon(POLYGON3D *polygon,int SRID, bool is3d) cl->setAt( c ,t); } } - innerRing = geomFactory->createLinearRing(cl); + innerRing = (LinearRing *) geomFactory->createLinearRing(cl); + if (innerRing == NULL) + return NULL; innerRing->setSRID(SRID); innerRings->push_back(innerRing); pointOffset += polygon->npoints[ring]; } - g = geomFactory->createPolygon(outerRing, innerRings); - g->setSRID(SRID); - return g; + g = geomFactory->createPolygon(outerRing, innerRings); + if (g==NULL) + return NULL; + g->setSRID(SRID); + return g; + } + catch (...) + { + return NULL; + } } +//----------------------------------------------------------- +// relate()-related functions +// return 0 = false, 1 = true, 2 = error occured +//----------------------------------------------------------- - -bool GEOSrelateDisjoint(Geometry *g1, Geometry*g2) +char GEOSrelateDisjoint(Geometry *g1, Geometry*g2) { - return g1->disjoint(g2); + try { + bool result; + result = g1->disjoint(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateTouches(Geometry *g1, Geometry*g2) +char GEOSrelateTouches(Geometry *g1, Geometry*g2) { - return g1->touches(g2); + try { + bool result; + result = g1->touches(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateIntersects(Geometry *g1, Geometry*g2) +char GEOSrelateIntersects(Geometry *g1, Geometry*g2) { - return g1->intersects(g2); + try { + bool result; + result = g1->intersects(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateCrosses(Geometry *g1, Geometry*g2) +char GEOSrelateCrosses(Geometry *g1, Geometry*g2) { - return g1->crosses(g2); + try { + bool result; + result = g1->crosses(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateWithin(Geometry *g1, Geometry*g2) +char GEOSrelateWithin(Geometry *g1, Geometry*g2) { - return g1->within(g2); + try { + bool result; + result = g1->within(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateContains(Geometry *g1, Geometry*g2) +// call g1->contains(g2) +// returns 0 = false +// 1 = true +// 2 = error was trapped +char GEOSrelateContains(Geometry *g1, Geometry*g2) { - return g1->contains(g2); + try { + bool result; + result = g1->contains(g2); + return result; + } + catch (...) + { + return 2; + } } -bool GEOSrelateOverlaps(Geometry *g1, Geometry*g2) +char GEOSrelateOverlaps(Geometry *g1, Geometry*g2) { - return g1->overlaps(g2); + try { + bool result; + result = g1->overlaps(g2); + return result; + } + catch (...) + { + return 2; + } } -//BUG:: this leaks memory, but delete kills the PrecisionModel for ALL the geometries -void GEOSdeleteGeometry(Geometry *a) + +//------------------------------------------------------------------- +// low-level relate functions +//------------------------------------------------------------------ + +char GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat) { -// delete a; + try { + bool result; + string s = pat; + result = g1->relate(g2,pat); + return result; + } + catch (...) + { + return 2; + } } -void GEOSdeleteChar(char *a) +char *GEOSrelate(Geometry *g1, Geometry*g2) { - free(a); -} + try { -bool GEOSrelatePattern(Geometry *g1, Geometry*g2,char *pat) -{ - string s = pat; - return g1->relate(g2,pat); + IntersectionMatrix *im = g1->relate(g2); + + string s; + char *result; + if (im == NULL) + return NULL; + + s= im->toString(); + result = (char*) malloc( s.length() + 1); + strcpy(result, s.c_str() ); + + return result; + } + catch (...) + { + return NULL; + } } -char *GEOSrelate(Geometry *g1, Geometry*g2) -{ - IntersectionMatrix *im = g1->relate(g2); - string s; - char *result; - s= im->toString(); - result = (char*) malloc( s.length() + 1); - strcpy(result, s.c_str() ); +//----------------------------------------------------------------- +// isValid +//----------------------------------------------------------------- - return result; +char GEOSisvalid(Geometry *g1) +{ + try { + bool result; + result =g1->isValid(); + return result; + } + catch (...) + { + return 2; + } + } -bool GEOSisvalid(Geometry *g1) + +//----------------------------------------------------------------- +// general purpose +//----------------------------------------------------------------- + +char *GEOSasText(Geometry *g1) { - return g1->isValid(); + try + { + string s = g1->toString(); + + + char *result; + result = (char*) malloc( s.length() + 1); + strcpy(result, s.c_str() ); + return result; + } + catch (...) + { + return NULL; + } } +//------------------------------------------------------------------- +// memory management functions +//------------------------------------------------------------------ +//BUG:: this leaks memory, but delete kills the PrecisionModel for ALL the geometries +void GEOSdeleteGeometry(Geometry *a) +{ + try{ + // + } + catch(...) + { + // do nothing! + } +} -char *GEOSasText(Geometry *g1) +void GEOSdeleteChar(char *a) { - string s = g1->toString(); + try{ + delete a; + } + catch(...) + { + // do nothing! + } - return (char *) s.c_str() ; }