#include #include #include #include #pragma GCC java_exceptions #include #include #include #include #include //#define DEBUG_JARRAY 1 using namespace com::vividsolutions::jts::geom; using namespace com::vividsolutions::jts::io; using namespace com::vividsolutions::jts; using namespace java::lang; using namespace std; //for getting things to align properly double are on 8byte align on solaris machines, and 4bytes on intel //---- Definitions found in lwgeom.h (and postgis) #define TYPE_NDIMS(t) ((((t)&0x20)>>5)+(((t)&0x10)>>4)+2) #define TYPE_HASZ(t) ( ((t)&0x20)>>5 ) typedef unsigned int uint32; typedef int int32; typedef struct { double xmin, ymin, zmin; double xmax, ymax, zmax; } BOX3D; typedef struct { float xmin, ymin, xmax, ymax; } BOX2DFLOAT4; typedef struct { double x,y,z; } POINT3D; typedef struct { char *serialized_pointlist; unsigned char dims; uint32 npoints; } POINTARRAY; typedef struct { unsigned char type; BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *point; // hide 2d/3d (this will be an array of 1 point) } LWPOINT; // "light-weight point" // LINETYPE typedef struct { unsigned char type; BOX2DFLOAT4 *bbox; uint32 SRID; POINTARRAY *points; // array of POINT3D } LWLINE; //"light-weight line" // POLYGONTYPE typedef struct { unsigned char type; BOX2DFLOAT4 *bbox; uint32 SRID; int nrings; POINTARRAY **rings; // list of rings (list of points) } LWPOLY; // "light-weight polygon" extern "C" int getPoint3dz_p(POINTARRAY *pa, int n, POINT3D *); //---- End of definitions found in lwgeom.h #define POINTTYPE 1 #define LINETYPE 2 #define POLYGONTYPE 3 #define MULTIPOINTTYPE 4 #define MULTILINETYPE 5 #define MULTIPOLYGONTYPE 6 #define COLLECTIONTYPE 7 //########################################################### typedef void (*noticefunc)(const char *fmt, ...); extern "C" char *JTSrelate(Geometry *g1, Geometry*g2); extern "C" void initJTS(noticefunc); extern "C" void finishJTS(void); extern "C" void JTSSetSRID(Geometry *g, int SRID); extern "C" void JTSdeleteChar(char *a); extern "C" void JTSdeleteGeometry(Geometry *a); extern "C" char JTSrelatePattern(Geometry *g1, Geometry*g2,char *pat); extern "C" char JTSrelateDisjoint(Geometry *g1, Geometry*g2); extern "C" char JTSrelateTouches(Geometry *g1, Geometry*g2); extern "C" char JTSrelateIntersects(Geometry *g1, Geometry*g2); extern "C" char JTSrelateCrosses(Geometry *g1, Geometry*g2); extern "C" char JTSrelateWithin(Geometry *g1, Geometry*g2); extern "C" char JTSrelateContains(Geometry *g1, Geometry*g2); extern "C" char JTSrelateOverlaps(Geometry *g1, Geometry*g2); extern "C" Geometry *JTSPolygonize(Geometry **geoms, unsigned int ngeoms); extern "C" Geometry *JTSLineMerge(Geometry *geoms); extern "C" char *JTSversion(); extern "C" char *JTSjtsport(); extern "C" int JTSGeometryTypeId(Geometry *g1); extern "C" char JTSisvalid(Geometry *g1); /* Converters */ extern "C" Geometry *PostGIS2JTS_collection(int type, Geometry **geoms, int ngeoms, int SRID, bool is3d); extern "C" Geometry *PostGIS2JTS_point(const LWPOINT *point); extern "C" Geometry *PostGIS2JTS_linestring(const LWLINE *line); extern "C" Geometry *PostGIS2JTS_polygon(const LWPOLY *polygon); extern "C" char *JTSasText(Geometry *g1); extern "C" char JTSisEmpty(Geometry *g1); extern "C" char *JTSGeometryType(Geometry *g1); extern "C" char *throw_exception(Geometry *g); extern "C" Geometry *JTSIntersection(Geometry *g1,Geometry *g1); extern "C" Geometry *JTSBuffer(Geometry *g1,double width,int quadsegs); extern "C" Geometry *JTSConvexHull(Geometry *g1); extern "C" Geometry *JTSDifference(Geometry *g1,Geometry *g2); extern "C" Geometry *JTSBoundary(Geometry *g1); extern "C" Geometry *JTSSymDifference(Geometry *g1,Geometry *g2); extern "C" Geometry *JTSUnion(Geometry *g1,Geometry *g2); extern "C" POINT3D *JTSGetCoordinate(Geometry *g1); extern "C" POINT3D *JTSGetCoordinates(Geometry *g1); extern "C" int JTSGetNumCoordinate(Geometry *g1); extern "C" Geometry *JTSGetGeometryN(Geometry *g1, int n); extern "C" Geometry *JTSGetExteriorRing(Geometry *g1); extern "C" Geometry *JTSGetInteriorRingN(Geometry *g1, int n); extern "C" int JTSGetNumInteriorRings(Geometry *g1); extern "C" int JTSGetSRID(Geometry *g1); extern "C" int JTSGetNumGeometries(Geometry *g1); extern "C" char JTSisSimple(Geometry *g1); extern "C" char JTSequals(Geometry *g1, Geometry*g2); extern "C" char JTSisRing(Geometry *g1); extern "C" Geometry *JTSpointonSurface(Geometry *g1); extern "C" Geometry *JTSGetCentroid(Geometry *g1, int *failure); extern "C" bool JTSHasZ(Geometry *g1); extern "C" Geometry * JTSGeometryFromWKT(const char *wkt); //########################################################### char * StringToChar(String *s); static GeometryFactory *jtsGeomFactory = NULL; static noticefunc NOTICE_MESSAGE; void initJTS(noticefunc nf) { if (jtsGeomFactory == NULL) { JvCreateJavaVM(NULL); JvAttachCurrentThread(NULL, NULL); JvInitClass(&Geometry::class$); JvInitClass(&GeometryFactory::class$); JvInitClass(&Coordinate::class$); JvInitClass(&JTSVersion::class$); // NOTE: SRID will have to be changed after geometry creation jtsGeomFactory = new GeometryFactory( new PrecisionModel(), -1); } NOTICE_MESSAGE = nf; } void finishJTS(void) { //System::gc(); JvDetachCurrentThread(); } Geometry * JTSGeometryFromWKT(const char *wkt) { try { NOTICE_MESSAGE("JTSGeometryFromWKT called"); static WKTReader *r = new WKTReader; jstring wkt_j = JvNewStringLatin1(wkt); Geometry *g = r->read(wkt_j); return g; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //----------------------------------------------------------- // relate()-related functions // return 0 = false, 1 = true, 2 = error occured //----------------------------------------------------------- char JTSrelateDisjoint(Geometry *g1, Geometry*g2) { try { bool result; result = g1->disjoint(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSrelateTouches(Geometry *g1, Geometry*g2) { try { bool result; result = g1->touches(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSrelateIntersects(Geometry *g1, Geometry*g2) { try { bool result; result = g1->intersects(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSrelateCrosses(Geometry *g1, Geometry*g2) { try { bool result; result = g1->crosses(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSrelateWithin(Geometry *g1, Geometry*g2) { try { bool result; result = g1->within(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } // call g1->contains(g2) // returns 0 = false // 1 = true // 2 = error was trapped char JTSrelateContains(Geometry *g1, Geometry*g2) { try { bool result; result = g1->contains(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSrelateOverlaps(Geometry *g1, Geometry*g2) { try { bool result; result = g1->overlaps(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } //------------------------------------------------------------------- // low-level relate functions //------------------------------------------------------------------ char JTSrelatePattern(Geometry *g1, Geometry*g2,char *pat) { try { bool result; string s = pat; result = g1->relate(g2,JvNewStringLatin1(pat)); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char * JTSrelate(Geometry *g1, Geometry*g2) { try { IntersectionMatrix *im = g1->relate(g2); if (im == NULL) return NULL; jstring s = im->toString(); return StringToChar(s); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //----------------------------------------------------------------- // isValid //----------------------------------------------------------------- char JTSisvalid(Geometry *g1) { #if JTS_FIRST_INTERFACE <= 3 && JTS_LAST_INTERFACE >= 3 IsValidOp ivo(g1); #endif bool result; try { #if JTS_FIRST_INTERFACE <= 3 && JTS_LAST_INTERFACE >= 3 result = ivo.isValid(); if ( result == 0 ) { TopologyValidationError *err = ivo.getValidationError(); if ( err ) { NOTICE_MESSAGE(StringToChar(err->getMessage())); } } #else // JTS_INTERFACE 3 not supported result = g1->isValid(); #endif return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } //----------------------------------------------------------------- // general purpose //----------------------------------------------------------------- char JTSequals(Geometry *g1, Geometry*g2) { try { bool result; result = g1->equals(g2); return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char * JTSasText(Geometry *g1) { try { NOTICE_MESSAGE("JTSasText called"); jstring s = g1->toString(); return StringToChar(s); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } char JTSisEmpty(Geometry *g1) { try { return g1->isEmpty(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSisSimple(Geometry *g1) { try { return g1->isSimple(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } char JTSisRing(Geometry *g1) { try { return (( (LinearRing*)g1)->isRing()); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 2; } } //free the result of this char * JTSGeometryType(Geometry *g1) { try { jstring s = g1->getGeometryType(); return StringToChar(s); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //------------------------------------------------------------------- // JTS functions that return geometries //------------------------------------------------------------------- Geometry * JTSIntersection(Geometry *g1,Geometry *g2) { try { Geometry *g3 = g1->intersection(g2); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSBuffer(Geometry *g1, double width, int quadrantsegments) { try { Geometry *g3 = g1->buffer(width, quadrantsegments); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSConvexHull(Geometry *g1) { try { Geometry *g3 = g1->convexHull(); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSDifference(Geometry *g1,Geometry *g2) { try { Geometry *g3 = g1->difference(g2); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSBoundary(Geometry *g1) { try { Geometry *g3 = g1->getBoundary(); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSSymDifference(Geometry *g1,Geometry *g2) { try { Geometry *g3 = g1->symDifference(g2); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSUnion(Geometry *g1,Geometry *g2) { try { Geometry *g3 = g1->union$(g2); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSpointonSurface(Geometry *g1) { try { Geometry *g3 = g1->getInteriorPoint(); return g3; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //------------------------------------------------------------------- // memory management functions //------------------------------------------------------------------ //BUG:: this leaks memory, but delete kills the PrecisionModel for ALL the geometries void JTSdeleteGeometry(Geometry *a) { cerr<<"Don't call JTSdeleteGeometry, the GC will do.."<setSRID(SRID); } void JTSdeleteChar(char *a) { free(a); } //------------------------------------------------------------------- //JTS => POSTGIS conversions //------------------------------------------------------------------- // free the result when done! // g1 must be a point POINT3D * JTSGetCoordinate(Geometry *g1) { try{ POINT3D *result = (POINT3D*) malloc (sizeof(POINT3D)); const Coordinate *c =g1->getCoordinate(); result->x = c->x; result->y = c->y; result->z = c->z; return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //must free the result when done // result is an array length g1->getNumCoordinates() POINT3D * JTSGetCoordinates(Geometry *g1) { try { int numPoints = g1->getNumPoints(); POINT3D *result = (POINT3D*)malloc(sizeof(POINT3D)*numPoints); JArray *cl = g1->getCoordinates(); Coordinate **coords = elements(cl); Coordinate *c; for (int t=0; tx; result[t].y = c->y; result[t].z = c->z; } return result; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } int JTSGetNumCoordinate(Geometry *g1) { try{ return g1->getNumPoints(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 0; } } int JTSGetNumInteriorRings(Geometry *g1) { try{ Polygon *p = (Polygon *) g1; return p->getNumInteriorRing(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 0; } } //only call on GCs (or multi*) int JTSGetNumGeometries(Geometry *g1) { try { GeometryCollection *gc = (GeometryCollection *) g1; return gc->getNumGeometries(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 0; } } //call only on GEOMETRYCOLLECTION or MULTI* Geometry * JTSGetGeometryN(Geometry *g1, int n) { try{ return ((GeometryCollection *)g1)->getGeometryN(n); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //call only on polygon Geometry * JTSGetExteriorRing(Geometry *g1) { try{ Polygon *p = (Polygon *) g1; return p->getExteriorRing(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } //call only on polygon Geometry * JTSGetInteriorRingN(Geometry *g1,int n) { try { Polygon *p = (Polygon *) g1; return p->getInteriorRingN(n); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * JTSPolygonize(Geometry **g, unsigned int ngeoms) { NOTICE_MESSAGE("JTS Polygonize unimplemented"); return NULL; } Geometry * JTSLineMerge(Geometry *g) { NOTICE_MESSAGE("JTS LineMerge unimplemented"); return NULL; } Geometry * JTSGetCentroid(Geometry *g, int *failure) { try{ Geometry *ret = g->getCentroid(); *failure = 0; return ret; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } int JTSGetSRID(Geometry *g1) { try { return g1->getSRID(); } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return 0; } } char * JTSversion() { //char *res = strdup("unknown"); JTSVersion *v = JTSVersion::CURRENT_VERSION; if ( ! v ) return "UNDEFINED"; return StringToChar(v->toString()); //return res; } bool JTSHasZ(Geometry *g) { //double az = g->getCoordinate()->z; //return (finite(az) && az != DoubleNotANumber); return false; } int JTSGeometryTypeId(Geometry *g1) { jstring s = g1->getGeometryType(); char *type = StringToChar(s); if ( ! strcmp(type, "Point") ) return POINTTYPE; if ( ! strcmp(type, "Polygon") ) return POLYGONTYPE; if ( ! strcmp(type, "LineString") ) return LINETYPE; if ( ! strcmp(type, "LinearRing") ) return LINETYPE; if ( ! strcmp(type, "MultiLineString") ) return MULTILINETYPE; if ( ! strcmp(type, "MultiPoint") ) return MULTIPOINTTYPE; if ( ! strcmp(type, "MultiPolygon") ) return MULTIPOLYGONTYPE; if ( ! strcmp(type, "GeometryCollection") ) return COLLECTIONTYPE; else { NOTICE_MESSAGE("JTSGeometryTypeId: unknown geometry type: %s", type); return -1; // unknown type } } char * StringToChar(String *s) { int len = JvGetStringUTFLength(s); char *result = (char *)malloc(len+1); JvGetStringUTFRegion(s, 0, len, result); result[len] = '\0'; return result; } /* CONVERTERS */ Geometry * PostGIS2JTS_point(const LWPOINT *lwpoint) { POINT3D point; int SRID; bool is3d; #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_point got lwpoint[%p]", lwpoint); NOTICE_MESSAGE(buf); #endif if ( lwpoint == NULL ) { NOTICE_MESSAGE("PostGIS2GEOS_point got a NULL lwpoint"); return NULL; } getPoint3dz_p(lwpoint->point, 0, &point); SRID = lwpoint->SRID; is3d = TYPE_HASZ(lwpoint->type); try { Coordinate *c; if (is3d) c = new Coordinate(point.x, point.y, point.z); else c = new Coordinate(point.x, point.y); Geometry *g = jtsGeomFactory->createPoint(c); if (g==NULL) return NULL; g->setSRID(SRID); return g; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } /* * This function must return an all-new allocated object */ Geometry * PostGIS2JTS_linestring(const LWLINE *lwline) { POINTARRAY *pa = lwline->points; bool is3d = TYPE_HASZ(pa->dims); int SRID = lwline->SRID; #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_line got lwline[%p]", lwline); NOTICE_MESSAGE(buf); #endif try{ uint32 t; JArray*coordlist; POINT3D p; // build Coordinate[] jobjectArray vc = JvNewObjectArray(pa->npoints, &Coordinate::class$, NULL); #ifdef DEBUG_JARRAY //std::cout<<"PostGIS2JTS_linestring: vc Jarray: "<npoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x, p.y, p.z); } } else //make 2d points { for (t=0; tnpoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x, p.y); } } coordlist = reinterpret_cast*>(vc); CoordinateSequence *coords = jtsGeomFactory->getCoordinateSequenceFactory()->create(coordlist); Geometry *g = jtsGeomFactory->createLineString(coords); if (g==NULL) return NULL; g->setSRID(SRID); return g; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * PostGIS2JTS_polygon(const LWPOLY *lwpoly) { POINTARRAY *pa; int SRID = lwpoly->SRID; bool is3d = TYPE_HASZ(lwpoly->type); #ifdef DEBUG_POSTGIS2GEOS char buf[256]; sprintf(buf, "PostGIS2GEOS_poly got lwpoly[%p]", lwpoly); NOTICE_MESSAGE(buf); #endif try { //Coordinate *c; uint32 t; int ring; Geometry *g; LinearRing *outerRing; LinearRing *innerRing; CoordinateSequence *cl; POINT3D p; // make outerRing pa = lwpoly->rings[0]; jobjectArray vc = JvNewObjectArray(pa->npoints, &Coordinate::class$, NULL); #ifdef DEBUG_JARRAY std::cout<<"PostGIS2JTS_polygon: vc Jarray: "<npoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x,p.y,p.z); } } else { for(t=0; tnpoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x,p.y); #ifdef DEBUG_JARRAY std::cout<<" elements(vc)["<*coordlist = reinterpret_cast*>(vc); cl = jtsGeomFactory->getCoordinateSequenceFactory()->create(coordlist); coordlist=NULL; vc=NULL; outerRing = jtsGeomFactory->createLinearRing(cl); cl = NULL; if (outerRing == NULL) return NULL; outerRing->setSRID(SRID); jobjectArray innerRings = JvNewObjectArray(lwpoly->nrings-1, &Geometry::class$, NULL); #ifdef DEBUG_JARRAY std::cout<<"PostGIS2JTS_polygon: innerRings Jarray: "<nrings; ring++) { pa = lwpoly->rings[ring]; vc = JvNewObjectArray(pa->npoints, &Coordinate::class$, NULL); if (is3d) { for(t=0; tnpoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x,p.y,p.z); } } else { for(t=0; tnpoints; t++) { getPoint3dz_p(pa, t, &p); elements(vc)[t] = new Coordinate(p.x,p.y); } } coordlist = reinterpret_cast*>(vc); cl = jtsGeomFactory->getCoordinateSequenceFactory()->create(coordlist); innerRing = (LinearRing *) jtsGeomFactory->createLinearRing(cl); if (innerRing == NULL) { return NULL; } innerRing->setSRID(SRID); elements(innerRings)[ring-1] = innerRing; } JArray*holesList = reinterpret_cast*>(innerRings); g = jtsGeomFactory->createPolygon(outerRing, holesList); if (g==NULL) return NULL; g->setSRID(SRID); return g; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } } Geometry * PostGIS2JTS_collection(int type, Geometry **geoms, int ngeoms, int SRID, bool is3d) { #ifdef DEBUG_POSTGIS2JTS char buf[256]; sprintf(buf, "PostGIS2JTS_collection: requested type %d, ngeoms: %d", type, ngeoms); NOTICE_MESSAGE(buf); #endif try { Geometry *g; int t; jobjectArray subGeoms = JvNewObjectArray(ngeoms, &Geometry::class$, NULL); #ifdef DEBUG_JARRAY //std::cout<<"PostGIS2JTS_collection: subGeoms Jarray: "<createGeometryCollection((JArray*)subGeoms); break; case MULTIPOINTTYPE: g = jtsGeomFactory->createMultiPoint((JArray*)subGeoms); break; case MULTILINETYPE: g = jtsGeomFactory->createMultiLineString((JArray*)subGeoms); break; case MULTIPOLYGONTYPE: g = jtsGeomFactory->createMultiPolygon((JArray*)subGeoms); break; default: NOTICE_MESSAGE("Unsupported type request for PostGIS2JTS_collection"); g = NULL; } if (g==NULL) return NULL; g->setSRID(SRID); return g; } catch (Throwable *t) { NOTICE_MESSAGE(StringToChar(t->getMessage())); return NULL; } }