]> granicus.if.org Git - postgis/commitdiff
New version of the postgis-GEOS connector.
authorDavid Blasby <dblasby@gmail.com>
Tue, 27 May 2003 22:35:14 +0000 (22:35 +0000)
committerDavid Blasby <dblasby@gmail.com>
Tue, 27 May 2003 22:35:14 +0000 (22:35 +0000)
git-svn-id: http://svn.osgeo.org/postgis/trunk@275 b70326c6-7e19-0410-871a-916f4a2858ee

Makefile
postgis_geos.c
postgis_geos_wrapper.cpp

index 5fe5d17b1a8dd47715d5395e8ea85673de67bc14..33ab7f5d4834237afe9cb9cea33ea0afa60a8a10 100644 (file)
--- 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)
 
index 166bac902ebe17fe34fea861783e444f2f8eb985..7c4bd4884ae32213a09ad96974c1a16f12a5da42 100644 (file)
@@ -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;
 
index 747a8828a6439dc1433a21209edaadb0bc4e0b18..e57bd57220f9f66f57ebec703115110bc32013c0 100644 (file)
@@ -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<Geometry *> *subGeos=new vector<Geometry *>;
+       try
+       {
+               Geometry *g;
+               int t;
+               vector<Geometry *> *subGeos=new vector<Geometry *>;
 
-       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;t<line->npoints;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;t<line->npoints;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;t<line->npoints;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;t<line->npoints;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<Geometry *> *subPolys=new vector<Geometry *>;
-       Geometry *g;
+       try
+       {
+                       int t;
+                       vector<Geometry *> *subPolys=new vector<Geometry *>;
+                       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<Geometry *> *subLines =new vector<Geometry *>;
-       Geometry *g;
+       try
+       {
+                       int t;
+                       vector<Geometry *> *subLines =new vector<Geometry *>;
+                       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<Geometry *> *subPoints =new vector<Geometry *>;
-       Geometry *g;
+       try
+       {
+                       int t;
+                       vector<Geometry *> *subPoints =new vector<Geometry *>;
+                       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() ;
 }