/************************************************************************ * * * C-Wrapper for GEOS library * * Copyright (C) 2010 2011 Sandro Santilli * Copyright (C) 2005-2006 Refractions Research Inc. * * This is free software; you can redistribute and/or modify it under * the terms of the GNU Lesser General Public Licence as published * by the Free Software Foundation. * See the COPYING file for more information. * * Author: Sandro Santilli * Thread Safety modifications: Chuck Thibert * ***********************************************************************/ #include // for FINITE #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // This should go away #include // finite #include #include #include #include #include #include #include #include #include #ifdef _MSC_VER #pragma warning(disable : 4099) #endif // Some extra magic to make type declarations in geos_c.h work - // for cross-checking of types in header. #define GEOSGeometry geos::geom::Geometry #define GEOSPreparedGeometry geos::geom::prep::PreparedGeometry #define GEOSCoordSequence geos::geom::CoordinateSequence #define GEOSBufferParams geos::operation::buffer::BufferParameters #define GEOSSTRtree geos::index::strtree::STRtree #define GEOSWKTReader_t geos::io::WKTReader #define GEOSWKTWriter_t geos::io::WKTWriter #define GEOSWKBReader_t geos::io::WKBReader #define GEOSWKBWriter_t geos::io::WKBWriter #include "geos_c.h" // Intentional, to allow non-standard C elements like C99 functions to be // imported through C++ headers of C library, like . using namespace std; /// Define this if you want operations triggering Exceptions to /// be printed. /// (will use the NOTIFY channel - only implemented for GEOSUnion so far) /// #undef VERBOSE_EXCEPTIONS #include // import the most frequently used definitions globally using geos::geom::Geometry; using geos::geom::LineString; using geos::geom::Polygon; using geos::geom::CoordinateSequence; using geos::geom::GeometryFactory; using geos::io::WKTReader; using geos::io::WKTWriter; using geos::io::WKBReader; using geos::io::WKBWriter; using geos::operation::overlay::OverlayOp; using geos::operation::overlay::overlayOp; using geos::operation::geounion::CascadedPolygonUnion; using geos::operation::buffer::BufferParameters; using geos::operation::buffer::BufferBuilder; using geos::util::IllegalArgumentException; using geos::algorithm::distance::DiscreteHausdorffDistance; typedef std::auto_ptr GeomAutoPtr; typedef struct GEOSContextHandleInternal { const GeometryFactory *geomFactory; GEOSMessageHandler NOTICE_MESSAGE; GEOSMessageHandler ERROR_MESSAGE; int WKBOutputDims; int WKBByteOrder; int initialized; } GEOSContextHandleInternal_t; // CAPI_ItemVisitor is used internally by the CAPI STRtree // wrappers. It's defined here just to keep it out of the // extern "C" block. class CAPI_ItemVisitor : public geos::index::ItemVisitor { GEOSQueryCallback callback; void *userdata; public: CAPI_ItemVisitor (GEOSQueryCallback cb, void *ud) : ItemVisitor(), callback(cb), userdata(ud) {} void visitItem (void *item) { callback(item, userdata); } }; //## PROTOTYPES ############################################# extern "C" const char GEOS_DLL *GEOSjtsport(); extern "C" char GEOS_DLL *GEOSasText(Geometry *g1); // --- Custom memory allocators -------------------------------- { GEOSAllocator geos_alloc = std::malloc; GEOSFreer geos_free = std::free; GEOSAllocator GEOS_setAllocator(GEOSAllocator nf) { GEOSAllocator of = geos_alloc; geos_alloc = nf; geos::util::CustomAllocators::setAllocator(geos_alloc); return of; } GEOSFreer GEOS_setFreer(GEOSFreer nf) { GEOSFreer of = geos_free; geos_free = nf; geos::util::CustomAllocators::setFreer(geos_free); return of; } void* operator new (std::size_t size, const std::nothrow_t&) throw () { //cout << "new(" << size << ") called" << endl; return geos_alloc(size); } void operator delete (void *ptr) throw () { //cout << "delete(" << ptr << ") called" << endl; if ( ptr ) geos_free(ptr); } void* operator new (std::size_t size) throw (std::bad_alloc) { if ( void* ret = operator new (size, std::nothrow) ) return ret; throw std::bad_alloc(); } // ---------------------------------------------------------------- } namespace { // anonymous char* gstrdup_s(const char* str, const std::size_t size) { char* out = static_cast(geos_alloc(size + 1)); if (0 != out) { // as no strlen call necessary, memcpy may be faster than strcpy std::memcpy(out, str, size + 1); } assert(0 != out); // we haven't been checking allocation before ticket #371 if (0 == out) { throw(std::runtime_error("Failed to allocate memory for duplicate string")); } return out; } char* gstrdup(std::string const& str) { return gstrdup_s(str.c_str(), str.size()); } } // namespace anonymous extern "C" { GEOSContextHandle_t initGEOS_r(GEOSMessageHandler nf, GEOSMessageHandler ef) { GEOSContextHandleInternal_t *handle = 0; void *extHandle = 0; extHandle = geos_alloc(sizeof(GEOSContextHandleInternal_t)); if (0 != extHandle) { handle = static_cast(extHandle); handle->NOTICE_MESSAGE = nf; handle->ERROR_MESSAGE = ef; handle->geomFactory = GeometryFactory::getDefaultInstance(); handle->WKBOutputDims = 2; handle->WKBByteOrder = getMachineByteOrder(); handle->initialized = 1; } return static_cast(extHandle); } GEOSMessageHandler GEOSContext_setNoticeHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf) { GEOSMessageHandler f; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } f = handle->NOTICE_MESSAGE; handle->NOTICE_MESSAGE = nf; return f; } GEOSMessageHandler GEOSContext_setErrorHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf) { GEOSMessageHandler f; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } f = handle->ERROR_MESSAGE; handle->ERROR_MESSAGE = nf; return f; } void finishGEOS_r(GEOSContextHandle_t extHandle) { // Fix up freeing handle w.r.t. malloc above geos_free(extHandle); extHandle = NULL; } void GEOSFree_r (GEOSContextHandle_t extHandle, void* buffer) { assert(0 != extHandle); geos_free(buffer); } //----------------------------------------------------------- // relate()-related functions // return 0 = false, 1 = true, 2 = error occured //----------------------------------------------------------- char GEOSDisjoint_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) { return 2; } try { bool result = g1->disjoint(g2); return result; } // TODO: mloskot is going to replace these double-catch block // with a macro to remove redundant code in this and // following functions. catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSTouches_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->touches(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSIntersects_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->intersects(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSCrosses_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->crosses(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSWithin_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->within(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } // call g1->contains(g2) // returns 0 = false // 1 = true // 2 = error was trapped char GEOSContains_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->contains(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSOverlaps_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->overlaps(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSCovers_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->covers(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSCoveredBy_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->coveredBy(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } //------------------------------------------------------------------- // low-level relate functions //------------------------------------------------------------------ char GEOSRelatePattern_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, const char *pat) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { std::string s(pat); bool result = g1->relate(g2, s); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSRelatePatternMatch_r(GEOSContextHandle_t extHandle, const char *mat, const char *pat) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { using geos::geom::IntersectionMatrix; std::string m(mat); std::string p(pat); IntersectionMatrix im(m); bool result = im.matches(p); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char * GEOSRelate_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::geom::IntersectionMatrix; IntersectionMatrix* im = g1->relate(g2); if (0 == im) { return 0; } char *result = gstrdup(im->toString()); delete im; im = 0; return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } char * GEOSRelateBoundaryNodeRule_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, int bnr) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::operation::relate::RelateOp; using geos::geom::IntersectionMatrix; using geos::algorithm::BoundaryNodeRule; IntersectionMatrix* im; switch (bnr) { case GEOSRELATE_BNR_MOD2: /* same as OGC */ im = RelateOp::relate(g1, g2, BoundaryNodeRule::MOD2_BOUNDARY_RULE); break; case GEOSRELATE_BNR_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::ENDPOINT_BOUNDARY_RULE); break; case GEOSRELATE_BNR_MULTIVALENT_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::MULTIVALENT_ENDPOINT_BOUNDARY_RULE); break; case GEOSRELATE_BNR_MONOVALENT_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::MONOVALENT_ENDPOINT_BOUNDARY_RULE); break; default: handle->ERROR_MESSAGE("Invalid boundary node rule %d", bnr); return 0; break; } if (0 == im) return 0; char *result = gstrdup(im->toString()); delete im; im = 0; return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } //----------------------------------------------------------------- // isValid //----------------------------------------------------------------- char GEOSisValid_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { using geos::operation::valid::IsValidOp; using geos::operation::valid::TopologyValidationError; IsValidOp ivo(g1); TopologyValidationError *err = ivo.getValidationError(); if ( err ) { handle->NOTICE_MESSAGE("%s", err->toString().c_str()); return 0; } else { return 1; } } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char * GEOSisValidReason_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::operation::valid::IsValidOp; using geos::operation::valid::TopologyValidationError; char* result = 0; char const* const validstr = "Valid Geometry"; IsValidOp ivo(g1); TopologyValidationError *err = ivo.getValidationError(); if (0 != err) { std::ostringstream ss; ss.precision(15); ss << err->getCoordinate(); const std::string errloc = ss.str(); std::string errmsg(err->getMessage()); errmsg += "[" + errloc + "]"; result = gstrdup(errmsg); } else { result = gstrdup(std::string(validstr)); } return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } char GEOSisValidDetail_r(GEOSContextHandle_t extHandle, const Geometry *g, int flags, char** reason, Geometry ** location) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::operation::valid::IsValidOp; using geos::operation::valid::TopologyValidationError; IsValidOp ivo(g); if ( flags & GEOSVALID_ALLOW_SELFTOUCHING_RING_FORMING_HOLE ) { ivo.setSelfTouchingRingFormingHoleValid(true); } TopologyValidationError *err = ivo.getValidationError(); if (0 != err) { if ( location ) { *location = handle->geomFactory->createPoint(err->getCoordinate()); } if ( reason ) { std::string errmsg(err->getMessage()); *reason = gstrdup(errmsg); } return 0; } if ( location ) *location = 0; if ( reason ) *reason = 0; return 1; /* valid */ } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; /* exception */ } //----------------------------------------------------------------- // general purpose //----------------------------------------------------------------- char GEOSEquals_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->equals(g2); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSEqualsExact_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double tolerance) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = g1->equalsExact(g2, tolerance); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } int GEOSDistance_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double *dist) { assert(0 != dist); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { *dist = g1->distance(g2); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSHausdorffDistance_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double *dist) { assert(0 != dist); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { *dist = DiscreteHausdorffDistance::distance(*g1, *g2); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSHausdorffDistanceDensify_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2, double densifyFrac, double *dist) { assert(0 != dist); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { *dist = DiscreteHausdorffDistance::distance(*g1, *g2, densifyFrac); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSArea_r(GEOSContextHandle_t extHandle, const Geometry *g, double *area) { assert(0 != area); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { *area = g->getArea(); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSLength_r(GEOSContextHandle_t extHandle, const Geometry *g, double *length) { assert(0 != length); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { *length = g->getLength(); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSGeomFromWKT_r(GEOSContextHandle_t extHandle, const char *wkt) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const std::string wktstring(wkt); WKTReader r(static_cast(handle->geomFactory)); Geometry *g = r.read(wktstring); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } char * GEOSGeomToWKT_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { char *result = gstrdup(g1->toString()); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } // Remember to free the result! unsigned char * GEOSGeomToWKB_buf_r(GEOSContextHandle_t extHandle, const Geometry *g, size_t *size) { assert(0 != size); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } using geos::io::WKBWriter; try { int byteOrder = handle->WKBByteOrder; WKBWriter w(handle->WKBOutputDims, byteOrder); std::ostringstream os(std::ios_base::binary); w.write(*g, os); std::string wkbstring(os.str()); const std::size_t len = wkbstring.length(); unsigned char* result = 0; result = static_cast(geos_alloc(len)); if (0 != result) { std::memcpy(result, wkbstring.c_str(), len); *size = len; } return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeomFromWKB_buf_r(GEOSContextHandle_t extHandle, const unsigned char *wkb, size_t size) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } using geos::io::WKBReader; try { std::string wkbstring(reinterpret_cast(wkb), size); // make it binary ! WKBReader r(*(static_cast(handle->geomFactory))); std::istringstream is(std::ios_base::binary); is.str(wkbstring); is.seekg(0, std::ios::beg); // rewind reader pointer Geometry *g = r.read(is); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* Read/write wkb hex values. Returned geometries are owned by the caller.*/ unsigned char * GEOSGeomToHEX_buf_r(GEOSContextHandle_t extHandle, const Geometry *g, size_t *size) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } using geos::io::WKBWriter; try { int byteOrder = handle->WKBByteOrder; WKBWriter w(handle->WKBOutputDims, byteOrder); std::ostringstream os(std::ios_base::binary); w.writeHEX(*g, os); std::string hexstring(os.str()); char *result = gstrdup(hexstring); if (0 != result) { *size = hexstring.length(); } return reinterpret_cast(result); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeomFromHEX_buf_r(GEOSContextHandle_t extHandle, const unsigned char *hex, size_t size) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } using geos::io::WKBReader; try { std::string hexstring(reinterpret_cast(hex), size); WKBReader r(*(static_cast(handle->geomFactory))); std::istringstream is(std::ios_base::binary); is.str(hexstring); is.seekg(0, std::ios::beg); // rewind reader pointer Geometry *g = r.readHEX(is); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } char GEOSisEmpty_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { return g1->isEmpty(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSisSimple_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { return g1->isSimple(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 2; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 2; } } char GEOSisRing_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { const LineString *ls = dynamic_cast(g); if ( ls ) { return (ls->isRing()); } else { return 0; } } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 2; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 2; } } //free the result of this char * GEOSGeomType_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { std::string s = g1->getGeometryType(); char *result = gstrdup(s); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } // Return postgis geometry type index int GEOSGeomTypeId_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { return g1->getGeometryTypeId(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } //------------------------------------------------------------------- // GEOS functions that return geometries //------------------------------------------------------------------- Geometry * GEOSEnvelope_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *g3 = g1->getEnvelope(); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSIntersection_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g1->intersection(g2); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSBuffer_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadrantsegments) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *g3 = g1->buffer(width, quadrantsegments); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSBufferWithStyle_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int endCapStyle, int joinStyle, double mitreLimit) { using geos::operation::buffer::BufferParameters; using geos::operation::buffer::BufferOp; using geos::util::IllegalArgumentException; if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { BufferParameters bp; bp.setQuadrantSegments(quadsegs); if ( endCapStyle > BufferParameters::CAP_SQUARE ) { throw IllegalArgumentException("Invalid buffer endCap style"); } bp.setEndCapStyle( static_cast(endCapStyle) ); if ( joinStyle > BufferParameters::JOIN_BEVEL ) { throw IllegalArgumentException("Invalid buffer join style"); } bp.setJoinStyle( static_cast(joinStyle) ); bp.setMitreLimit(mitreLimit); BufferOp op(g1, bp); Geometry *g3 = op.getResultGeometry(width); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSOffsetCurve_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int joinStyle, double mitreLimit) { if ( 0 == extHandle ) return NULL; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return NULL; try { BufferParameters bp; bp.setEndCapStyle( BufferParameters::CAP_FLAT ); bp.setQuadrantSegments(quadsegs); if ( joinStyle > BufferParameters::JOIN_BEVEL ) { throw IllegalArgumentException("Invalid buffer join style"); } bp.setJoinStyle( static_cast(joinStyle) ); bp.setMitreLimit(mitreLimit); bool isLeftSide = true; if ( width < 0 ) { isLeftSide = false; width = -width; } BufferBuilder bufBuilder (bp); Geometry *g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* @deprecated in 3.3.0 */ Geometry * GEOSSingleSidedBuffer_r(GEOSContextHandle_t extHandle, const Geometry *g1, double width, int quadsegs, int joinStyle, double mitreLimit, int leftSide) { if ( 0 == extHandle ) return NULL; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return NULL; try { BufferParameters bp; bp.setEndCapStyle( BufferParameters::CAP_FLAT ); bp.setQuadrantSegments(quadsegs); if ( joinStyle > BufferParameters::JOIN_BEVEL ) { throw IllegalArgumentException("Invalid buffer join style"); } bp.setJoinStyle( static_cast(joinStyle) ); bp.setMitreLimit(mitreLimit); bool isLeftSide = leftSide == 0 ? false : true; BufferBuilder bufBuilder (bp); Geometry *g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSConvexHull_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *g3 = g1->convexHull(); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSDifference_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g1->difference(g2); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSBoundary_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *g3 = g1->getBoundary(); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSSymDifference_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g1->symDifference(g2); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return NULL; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return NULL; } } Geometry * GEOSUnion_r(GEOSContextHandle_t extHandle, const Geometry *g1, const Geometry *g2) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g1->Union(g2); } catch (const std::exception &e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSUnion with following inputs:" << std::endl; s << "A: "<toString() << std::endl; s << "B: "<toString() << std::endl; handle->NOTICE_MESSAGE("%s", s.str().c_str()); #endif // VERBOSE_EXCEPTIONS handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSUnaryUnion_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { GeomAutoPtr g3 ( g->Union() ); return g3.release(); } catch (const std::exception &e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSUnaryUnion with following inputs:" << std::endl; s << "A: "<toString() << std::endl; s << "B: "<toString() << std::endl; handle->NOTICE_MESSAGE("%s", s.str().c_str()); #endif // VERBOSE_EXCEPTIONS handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSNode_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { std::auto_ptr g3 = geos::noding::GeometryNoder::node(*g); return g3.release(); } catch (const std::exception &e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSUnaryUnion with following inputs:" << std::endl; s << "A: "<toString() << std::endl; s << "B: "<toString() << std::endl; handle->NOTICE_MESSAGE("%s", s.str().c_str()); #endif // VERBOSE_EXCEPTIONS handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSUnionCascaded_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const geos::geom::MultiPolygon *p = dynamic_cast(g1); if ( ! p ) { handle->ERROR_MESSAGE("Invalid argument (must be a MultiPolygon)"); return NULL; } using geos::operation::geounion::CascadedPolygonUnion; return CascadedPolygonUnion::Union(p); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSPointOnSurface_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *ret = g1->getInteriorPoint(); if ( ! ret ) { const GeometryFactory* gf = handle->geomFactory; // return an empty collection return gf->createGeometryCollection(); } return ret; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } //------------------------------------------------------------------- // memory management functions //------------------------------------------------------------------ void GEOSGeom_destroy_r(GEOSContextHandle_t extHandle, Geometry *a) { GEOSContextHandleInternal_t *handle = 0; // FIXME: mloskot: Does this try-catch around delete means that // destructors in GEOS may throw? If it does, this is a serious // violation of "never throw an exception from a destructor" principle try { delete a; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } void GEOSSetSRID_r(GEOSContextHandle_t extHandle, Geometry *g, int srid) { assert(0 != g); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } g->setSRID(srid); } int GEOSGetNumCoordinates_r(GEOSContextHandle_t extHandle, const Geometry *g) { assert(0 != g); if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { return static_cast(g->getNumPoints()); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } /* * Return -1 on exception, 0 otherwise. * Converts Geometry to normal form (or canonical form). */ int GEOSNormalize_r(GEOSContextHandle_t extHandle, Geometry *g) { assert(0 != g); if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { g->normalize(); return 0; // SUCCESS } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } int GEOSGetNumInteriorRings_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { const Polygon *p = dynamic_cast(g1); if ( ! p ) { handle->ERROR_MESSAGE("Argument is not a Polygon"); return -1; } return static_cast(p->getNumInteriorRing()); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } // returns -1 on error and 1 for non-multi geometries int GEOSGetNumGeometries_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { return static_cast(g1->getNumGeometries()); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } /* * Call only on GEOMETRYCOLLECTION or MULTI*. * Return a pointer to the internal Geometry. */ const Geometry * GEOSGetGeometryN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g1->getGeometryN(n); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on LINESTRING * Returns NULL on exception */ Geometry * GEOSGeomGetPointN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getPointN(n); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on LINESTRING */ Geometry * GEOSGeomGetStartPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getStartPoint(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on LINESTRING */ Geometry * GEOSGeomGetEndPoint_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getEndPoint(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on LINESTRING * return 2 on exception, 1 on true, 0 on false */ char GEOSisClosed_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return 2; } return ls->isClosed(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } /* * Call only on LINESTRING * return 0 on exception, otherwise 1 */ int GEOSGeomGetLength_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *length) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return 0; } *length = ls->getLength(); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } /* * Call only on LINESTRING */ int GEOSGeomGetNumPoints_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } try { using geos::geom::LineString; const LineString *ls = dynamic_cast(g1); if ( ! ls ) { handle->ERROR_MESSAGE("Argument is not a LineString"); return -1; } return static_cast(ls->getNumPoints()); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } /* * For POINT * returns 0 on exception, otherwise 1 */ int GEOSGeomGetX_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *x) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::geom::Point; const Point *po = dynamic_cast(g1); if ( ! po ) { handle->ERROR_MESSAGE("Argument is not a Point"); return 0; } *x = po->getX(); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } /* * For POINT * returns 0 on exception, otherwise 1 */ int GEOSGeomGetY_r(GEOSContextHandle_t extHandle, const Geometry *g1, double *y) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::geom::Point; const Point *po = dynamic_cast(g1); if ( ! po ) { handle->ERROR_MESSAGE("Argument is not a Point"); return 0; } *y = po->getY(); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } /* * Call only on polygon * Return a copy of the internal Geometry. */ const Geometry * GEOSGetExteriorRing_r(GEOSContextHandle_t extHandle, const Geometry *g1) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const Polygon *p = dynamic_cast(g1); if ( ! p ) { handle->ERROR_MESSAGE("Invalid argument (must be a Polygon)"); return NULL; } return p->getExteriorRing(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on polygon * Return a pointer to internal storage, do not destroy it. */ const Geometry * GEOSGetInteriorRingN_r(GEOSContextHandle_t extHandle, const Geometry *g1, int n) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const Polygon *p = dynamic_cast(g1); if ( ! p ) { handle->ERROR_MESSAGE("Invalid argument (must be a Polygon)"); return NULL; } return p->getInteriorRingN(n); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGetCentroid_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { Geometry *ret = g->getCentroid(); if (0 == ret) { const GeometryFactory *gf = handle->geomFactory; return gf->createGeometryCollection(); } return ret; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createEmptyCollection_r(GEOSContextHandle_t extHandle, int type) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } #ifdef GEOS_DEBUG char buf[256]; sprintf(buf, "createCollection: requested type %d, ngeoms: %d", type, ngeoms); handle->NOTICE_MESSAGE("%s", buf);// TODO: Can handle->NOTICE_MESSAGE format that directly? #endif try { const GeometryFactory* gf = handle->geomFactory; Geometry *g = 0; switch (type) { case GEOS_GEOMETRYCOLLECTION: g = gf->createGeometryCollection(); break; case GEOS_MULTIPOINT: g = gf->createMultiPoint(); break; case GEOS_MULTILINESTRING: g = gf->createMultiLineString(); break; case GEOS_MULTIPOLYGON: g = gf->createMultiPolygon(); break; default: handle->ERROR_MESSAGE("Unsupported type request for GEOSGeom_createEmptyCollection_r"); g = 0; } return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSGeom_createCollection_r(GEOSContextHandle_t extHandle, int type, Geometry **geoms, unsigned int ngeoms) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } #ifdef GEOS_DEBUG char buf[256]; sprintf(buf, "PostGIS2GEOS_collection: requested type %d, ngeoms: %d", type, ngeoms); handle->NOTICE_MESSAGE("%s", buf);// TODO: Can handle->NOTICE_MESSAGE format that directly? #endif try { const GeometryFactory* gf = handle->geomFactory; std::vector* vgeoms = new std::vector(geoms, geoms + ngeoms); Geometry *g = 0; switch (type) { case GEOS_GEOMETRYCOLLECTION: g = gf->createGeometryCollection(vgeoms); break; case GEOS_MULTIPOINT: g = gf->createMultiPoint(vgeoms); break; case GEOS_MULTILINESTRING: g = gf->createMultiLineString(vgeoms); break; case GEOS_MULTIPOLYGON: g = gf->createMultiPolygon(vgeoms); break; default: handle->ERROR_MESSAGE("Unsupported type request for PostGIS2GEOS_collection"); g = 0; } return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSPolygonize_r(GEOSContextHandle_t extHandle, const Geometry * const * g, unsigned int ngeoms) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } Geometry *out = 0; try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr; for (std::size_t i = 0; i < ngeoms; ++i) { plgnzr.add(g[i]); } #if GEOS_DEBUG handle->NOTICE_MESSAGE("geometry vector added to polygonizer"); #endif std::vector *polys = plgnzr.getPolygons(); assert(0 != polys); #if GEOS_DEBUG handle->NOTICE_MESSAGE("output polygons got"); #endif // We need a vector of Geometry pointers, not Polygon pointers. // STL vector doesn't allow transparent upcast of this // nature, so we explicitly convert. // (it's just a waste of processor and memory, btw) // // XXX mloskot: Why not to extent GeometryFactory to accept // vector of polygons or extend Polygonizer to return list of Geometry* // or add a wrapper which semantic is similar to: // std::vector > std::vector *polyvec = new std::vector(polys->size()); for (std::size_t i = 0; i < polys->size(); ++i) { (*polyvec)[i] = (*polys)[i]; } delete polys; polys = 0; const GeometryFactory *gf = handle->geomFactory; // The below takes ownership of the passed vector, // so we must *not* delete it out = gf->createGeometryCollection(polyvec); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return out; } Geometry * GEOSPolygonizer_getCutEdges_r(GEOSContextHandle_t extHandle, const Geometry * const * g, unsigned int ngeoms) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } Geometry *out = 0; try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr; for (std::size_t i = 0; i < ngeoms; ++i) { plgnzr.add(g[i]); } #if GEOS_DEBUG handle->NOTICE_MESSAGE("geometry vector added to polygonizer"); #endif const std::vector& lines = plgnzr.getCutEdges(); #if GEOS_DEBUG handle->NOTICE_MESSAGE("output polygons got"); #endif // We need a vector of Geometry pointers, not Polygon pointers. // STL vector doesn't allow transparent upcast of this // nature, so we explicitly convert. // (it's just a waste of processor and memory, btw) // XXX mloskot: See comment for GEOSPolygonize_r std::vector *linevec = new std::vector(lines.size()); for (std::size_t i = 0, n=lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone(); } const GeometryFactory *gf = handle->geomFactory; // The below takes ownership of the passed vector, // so we must *not* delete it out = gf->createGeometryCollection(linevec); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return out; } Geometry * GEOSPolygonize_full_r(GEOSContextHandle_t extHandle, const Geometry* g, Geometry** cuts, Geometry** dangles, Geometry** invalid) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr; for (std::size_t i = 0; i getNumGeometries(); ++i) { plgnzr.add(g->getGeometryN(i)); } #if GEOS_DEBUG handle->NOTICE_MESSAGE("geometry vector added to polygonizer"); #endif const GeometryFactory *gf = handle->geomFactory; if ( cuts ) { const std::vector& lines = plgnzr.getCutEdges(); std::vector *linevec = new std::vector(lines.size()); for (std::size_t i = 0, n=lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone(); } // The below takes ownership of the passed vector, // so we must *not* delete it *cuts = gf->createGeometryCollection(linevec); } if ( dangles ) { const std::vector& lines = plgnzr.getDangles(); std::vector *linevec = new std::vector(lines.size()); for (std::size_t i = 0, n=lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone(); } // The below takes ownership of the passed vector, // so we must *not* delete it *dangles = gf->createGeometryCollection(linevec); } if ( invalid ) { const std::vector& lines = plgnzr.getInvalidRingLines(); std::vector *linevec = new std::vector(lines.size()); for (std::size_t i = 0, n=lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone(); } // The below takes ownership of the passed vector, // so we must *not* delete it *invalid = gf->createGeometryCollection(linevec); } std::vector *polys = plgnzr.getPolygons(); std::vector *polyvec = new std::vector(polys->size()); for (std::size_t i = 0; i < polys->size(); ++i) { (*polyvec)[i] = (*polys)[i]; } delete polys; return gf->createGeometryCollection(polyvec); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 0; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 0; } } Geometry * GEOSLineMerge_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } Geometry *out = 0; try { using geos::operation::linemerge::LineMerger; LineMerger lmrgr; lmrgr.add(g); std::vector* lines = lmrgr.getMergedLineStrings(); assert(0 != lines); #if GEOS_DEBUG handle->NOTICE_MESSAGE("output lines got"); #endif std::vector*geoms = new std::vector(lines->size()); for (std::vector::size_type i = 0; i < lines->size(); ++i) { (*geoms)[i] = (*lines)[i]; } delete lines; lines = 0; const GeometryFactory *gf = handle->geomFactory; out = gf->buildGeometry(geoms); // XXX: old version //out = gf->createGeometryCollection(geoms); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return out; } int GEOSGetSRID_r(GEOSContextHandle_t extHandle, const Geometry *g) { assert(0 != g); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { return g->getSRID(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } const char* GEOSversion() { return GEOS_CAPI_VERSION; } const char* GEOSjtsport() { return GEOS_JTS_PORT; } char GEOSHasZ_r(GEOSContextHandle_t extHandle, const Geometry *g) { assert(0 != g); if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } if (g->isEmpty()) { return false; } assert(0 != g->getCoordinate()); double az = g->getCoordinate()->z; //handle->ERROR_MESSAGE("ZCoord: %g", az); return static_cast(FINITE(az)); } int GEOS_getWKBOutputDims_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } return handle->WKBOutputDims; } int GEOS_setWKBOutputDims_r(GEOSContextHandle_t extHandle, int newdims) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } if ( newdims < 2 || newdims > 3 ) { handle->ERROR_MESSAGE("WKB output dimensions out of range 2..3"); } const int olddims = handle->WKBOutputDims; handle->WKBOutputDims = newdims; return olddims; } int GEOS_getWKBByteOrder_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } return handle->WKBByteOrder; } int GEOS_setWKBByteOrder_r(GEOSContextHandle_t extHandle, int byteOrder) { if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } const int oldByteOrder = handle->WKBByteOrder; handle->WKBByteOrder = byteOrder; return oldByteOrder; } CoordinateSequence * GEOSCoordSeq_create_r(GEOSContextHandle_t extHandle, unsigned int size, unsigned int dims) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->getCoordinateSequenceFactory()->create(size, dims); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSCoordSeq_setOrdinate_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs, unsigned int idx, unsigned int dim, double val) { assert(0 != cs); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { cs->setOrdinate(idx, dim, val); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_setX_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val) { return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 0, val); } int GEOSCoordSeq_setY_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val) { return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 1, val); } int GEOSCoordSeq_setZ_r(GEOSContextHandle_t extHandle, CoordinateSequence *s, unsigned int idx, double val) { return GEOSCoordSeq_setOrdinate_r(extHandle, s, idx, 2, val); } CoordinateSequence * GEOSCoordSeq_clone_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs) { assert(0 != cs); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return cs->clone(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSCoordSeq_getOrdinate_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs, unsigned int idx, unsigned int dim, double *val) { assert(0 != cs); assert(0 != val); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { double d = cs->getOrdinate(idx, dim); *val = d; return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_getX_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val) { return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 0, val); } int GEOSCoordSeq_getY_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val) { return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 1, val); } int GEOSCoordSeq_getZ_r(GEOSContextHandle_t extHandle, const CoordinateSequence *s, unsigned int idx, double *val) { return GEOSCoordSeq_getOrdinate_r(extHandle, s, idx, 2, val); } int GEOSCoordSeq_getSize_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs, unsigned int *size) { assert(0 != cs); assert(0 != size); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { const std::size_t sz = cs->getSize(); *size = static_cast(sz); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_getDimensions_r(GEOSContextHandle_t extHandle, const CoordinateSequence *cs, unsigned int *dims) { assert(0 != cs); assert(0 != dims); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { const std::size_t dim = cs->getDimension(); *dims = static_cast(dim); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } void GEOSCoordSeq_destroy_r(GEOSContextHandle_t extHandle, CoordinateSequence *s) { GEOSContextHandleInternal_t *handle = 0; try { delete s; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } const CoordinateSequence * GEOSGeom_getCoordSeq_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::geom::Point; const LineString *ls = dynamic_cast(g); if ( ls ) { return ls->getCoordinatesRO(); } const Point *p = dynamic_cast(g); if ( p ) { return p->getCoordinatesRO(); } handle->ERROR_MESSAGE("Geometry must be a Point or LineString"); return 0; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSGeom_createEmptyPoint_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createPoint(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createPoint_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createPoint(cs); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSGeom_createLinearRing_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createLinearRing(cs); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createEmptyLineString_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createLineString(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createLineString_r(GEOSContextHandle_t extHandle, CoordinateSequence *cs) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createLineString(cs); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createEmptyPolygon_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { const GeometryFactory *gf = handle->geomFactory; return gf->createPolygon(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_createPolygon_r(GEOSContextHandle_t extHandle, Geometry *shell, Geometry **holes, unsigned int nholes) { // FIXME: holes must be non-nullptr or may be nullptr? //assert(0 != holes); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::geom::LinearRing; std::vector *vholes = new std::vector(holes, holes + nholes); LinearRing *nshell = dynamic_cast(shell); if ( ! nshell ) { handle->ERROR_MESSAGE("Shell is not a LinearRing"); return NULL; } const GeometryFactory *gf = handle->geomFactory; return gf->createPolygon(nshell, vholes); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSGeom_clone_r(GEOSContextHandle_t extHandle, const Geometry *g) { assert(0 != g); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { return g->clone(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSGeom_getDimensions_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { return (int) g->getDimension(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSGeom_getCoordinateDimension_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { return g->getCoordinateDimension(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSSimplify_r(GEOSContextHandle_t extHandle, const Geometry *g1, double tolerance) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using namespace geos::simplify; Geometry::AutoPtr g(DouglasPeuckerSimplifier::simplify(g1, tolerance)); return g.release(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry * GEOSTopologyPreserveSimplify_r(GEOSContextHandle_t extHandle, const Geometry *g1, double tolerance) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using namespace geos::simplify; Geometry::AutoPtr g(TopologyPreservingSimplifier::simplify(g1, tolerance)); return g.release(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* WKT Reader */ WKTReader * GEOSWKTReader_create_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::io::WKTReader; return new WKTReader((GeometryFactory*)handle->geomFactory); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } void GEOSWKTReader_destroy_r(GEOSContextHandle_t extHandle, WKTReader *reader) { GEOSContextHandleInternal_t *handle = 0; try { delete reader; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } Geometry* GEOSWKTReader_read_r(GEOSContextHandle_t extHandle, WKTReader *reader, const char *wkt) { assert(0 != reader); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { const std::string wktstring(wkt); Geometry *g = reader->read(wktstring); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } /* WKT Writer */ WKTWriter * GEOSWKTWriter_create_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { using geos::io::WKTWriter; return new WKTWriter(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } void GEOSWKTWriter_destroy_r(GEOSContextHandle_t extHandle, WKTWriter *Writer) { GEOSContextHandleInternal_t *handle = 0; try { delete Writer; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } char* GEOSWKTWriter_write_r(GEOSContextHandle_t extHandle, WKTWriter *writer, const Geometry *geom) { assert(0 != writer); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { std::string sgeom(writer->write(geom)); char *result = gstrdup(sgeom); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } void GEOSWKTWriter_setTrim_r(GEOSContextHandle_t extHandle, WKTWriter *writer, char trim) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } writer->setTrim(0 != trim); } void GEOSWKTWriter_setRoundingPrecision_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int precision) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } writer->setRoundingPrecision(precision); } void GEOSWKTWriter_setOutputDimension_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int dim) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } try { writer->setOutputDimension(dim); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } int GEOSWKTWriter_getOutputDimension_r(GEOSContextHandle_t extHandle, WKTWriter *writer) { assert(0 != writer); if ( 0 == extHandle ) { return -1; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return -1; } int dim = -1; try { dim = writer->getOutputDimension(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return dim; } void GEOSWKTWriter_setOld3D_r(GEOSContextHandle_t extHandle, WKTWriter *writer, int useOld3D) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } writer->setOld3D(0 != useOld3D); } /* WKB Reader */ WKBReader * GEOSWKBReader_create_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } using geos::io::WKBReader; try { return new WKBReader(*(GeometryFactory*)handle->geomFactory); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } void GEOSWKBReader_destroy_r(GEOSContextHandle_t extHandle, WKBReader *reader) { GEOSContextHandleInternal_t *handle = 0; try { delete reader; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } Geometry* GEOSWKBReader_read_r(GEOSContextHandle_t extHandle, WKBReader *reader, const unsigned char *wkb, size_t size) { assert(0 != reader); assert(0 != wkb); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { std::string wkbstring(reinterpret_cast(wkb), size); // make it binary ! std::istringstream is(std::ios_base::binary); is.str(wkbstring); is.seekg(0, std::ios::beg); // rewind reader pointer Geometry *g = reader->read(is); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry* GEOSWKBReader_readHEX_r(GEOSContextHandle_t extHandle, WKBReader *reader, const unsigned char *hex, size_t size) { assert(0 != reader); assert(0 != hex); if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } try { std::string hexstring(reinterpret_cast(hex), size); std::istringstream is(std::ios_base::binary); is.str(hexstring); is.seekg(0, std::ios::beg); // rewind reader pointer Geometry *g = reader->readHEX(is); return g; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } /* WKB Writer */ WKBWriter * GEOSWKBWriter_create_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { using geos::io::WKBWriter; return new WKBWriter(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } void GEOSWKBWriter_destroy_r(GEOSContextHandle_t extHandle, WKBWriter *Writer) { GEOSContextHandleInternal_t *handle = 0; try { delete Writer; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } /* The caller owns the result */ unsigned char* GEOSWKBWriter_write_r(GEOSContextHandle_t extHandle, WKBWriter *writer, const Geometry *geom, size_t *size) { assert(0 != writer); assert(0 != geom); assert(0 != size); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { std::ostringstream os(std::ios_base::binary); writer->write(*geom, os); std::string wkbstring(os.str()); const std::size_t len = wkbstring.length(); unsigned char *result = NULL; result = (unsigned char*) geos_alloc(len); std::memcpy(result, wkbstring.c_str(), len); *size = len; return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* The caller owns the result */ unsigned char* GEOSWKBWriter_writeHEX_r(GEOSContextHandle_t extHandle, WKBWriter *writer, const Geometry *geom, size_t *size) { assert(0 != writer); assert(0 != geom); assert(0 != size); if ( 0 == extHandle ) { return NULL; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return NULL; } try { std::ostringstream os(std::ios_base::binary); writer->writeHEX(*geom, os); std::string wkbstring(os.str()); const std::size_t len = wkbstring.length(); unsigned char *result = NULL; result = (unsigned char*) geos_alloc(len); std::memcpy(result, wkbstring.c_str(), len); *size = len; return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSWKBWriter_getOutputDimension_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer) { assert(0 != writer); if ( 0 == extHandle ) { return 0; } int ret = 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { ret = writer->getOutputDimension(); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } return ret; } void GEOSWKBWriter_setOutputDimension_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, int newDimension) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { writer->setOutputDimension(newDimension); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } } int GEOSWKBWriter_getByteOrder_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer) { assert(0 != writer); if ( 0 == extHandle ) { return 0; } int ret = 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { ret = writer->getByteOrder(); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } return ret; } void GEOSWKBWriter_setByteOrder_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, int newByteOrder) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { writer->setByteOrder(newByteOrder); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } } char GEOSWKBWriter_getIncludeSRID_r(GEOSContextHandle_t extHandle, const GEOSWKBWriter* writer) { assert(0 != writer); if ( 0 == extHandle ) { return -1; } int ret = -1; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { int srid = writer->getIncludeSRID(); ret = srid; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } return static_cast(ret); } void GEOSWKBWriter_setIncludeSRID_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, const char newIncludeSRID) { assert(0 != writer); if ( 0 == extHandle ) { return; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 != handle->initialized ) { try { writer->setIncludeSRID(newIncludeSRID); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } } //----------------------------------------------------------------- // Prepared Geometry //----------------------------------------------------------------- const geos::geom::prep::PreparedGeometry* GEOSPrepare_r(GEOSContextHandle_t extHandle, const Geometry *g) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } const geos::geom::prep::PreparedGeometry* prep = 0; try { prep = geos::geom::prep::PreparedGeometryFactory::prepare(g); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return prep; } void GEOSPreparedGeom_destroy_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *a) { GEOSContextHandleInternal_t *handle = 0; try { delete a; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } char GEOSPreparedContains_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->contains(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedContainsProperly_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->containsProperly(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedCoveredBy_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->coveredBy(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedCovers_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->covers(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedCrosses_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->crosses(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedDisjoint_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->disjoint(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedIntersects_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->intersects(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedOverlaps_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->overlaps(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedTouches_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->touches(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } char GEOSPreparedWithin_r(GEOSContextHandle_t extHandle, const geos::geom::prep::PreparedGeometry *pg, const Geometry *g) { assert(0 != pg); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = pg->within(g); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } //----------------------------------------------------------------- // STRtree //----------------------------------------------------------------- geos::index::strtree::STRtree * GEOSSTRtree_create_r(GEOSContextHandle_t extHandle, size_t nodeCapacity) { if ( 0 == extHandle ) { return 0; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 0; } geos::index::strtree::STRtree *tree = 0; try { tree = new geos::index::strtree::STRtree(nodeCapacity); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return tree; } void GEOSSTRtree_insert_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree *tree, const geos::geom::Geometry *g, void *item) { GEOSContextHandleInternal_t *handle = 0; assert(tree != 0); assert(g != 0); try { tree->insert(g->getEnvelopeInternal(), item); } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } void GEOSSTRtree_query_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree *tree, const geos::geom::Geometry *g, GEOSQueryCallback callback, void *userdata) { GEOSContextHandleInternal_t *handle = 0; assert(tree != 0); assert(g != 0); assert(callback != 0); try { CAPI_ItemVisitor visitor(callback, userdata); tree->query(g->getEnvelopeInternal(), visitor); } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } void GEOSSTRtree_iterate_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree *tree, GEOSQueryCallback callback, void *userdata) { GEOSContextHandleInternal_t *handle = 0; assert(tree != 0); assert(callback != 0); try { CAPI_ItemVisitor visitor(callback, userdata); tree->iterate(visitor); } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } char GEOSSTRtree_remove_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree *tree, const geos::geom::Geometry *g, void *item) { assert(0 != tree); assert(0 != g); if ( 0 == extHandle ) { return 2; } GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { bool result = tree->remove(g->getEnvelopeInternal(), item); return result; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } void GEOSSTRtree_destroy_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree *tree) { GEOSContextHandleInternal_t *handle = 0; try { delete tree; } catch (const std::exception &e) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { if ( 0 == extHandle ) { return; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } double GEOSProject_r(GEOSContextHandle_t extHandle, const Geometry *g, const Geometry *p) { if ( 0 == extHandle ) return -1.0; GEOSContextHandleInternal_t *handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) return -1.0; const geos::geom::Point* point = dynamic_cast(p); if (!point) { handle->ERROR_MESSAGE("third argument of GEOSProject_r must be Point*"); return -1.0; } const geos::geom::Coordinate* inputPt = p->getCoordinate(); try { return geos::linearref::LengthIndexedLine(g).project(*inputPt); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return -1.0; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return -1.0; } } Geometry* GEOSInterpolate_r(GEOSContextHandle_t extHandle, const Geometry *g, double d) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) return 0; try { geos::linearref::LengthIndexedLine lil(g); geos::geom::Coordinate coord = lil.extractPoint(d); const GeometryFactory *gf = handle->geomFactory; Geometry* point = gf->createPoint(coord); return point; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 0; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 0; } } double GEOSProjectNormalized_r(GEOSContextHandle_t extHandle, const Geometry *g, const Geometry *p) { double length; GEOSLength_r(extHandle, g, &length); return GEOSProject_r(extHandle, g, p) / length; } Geometry* GEOSInterpolateNormalized_r(GEOSContextHandle_t extHandle, const Geometry *g, double d) { double length; GEOSLength_r(extHandle, g, &length); return GEOSInterpolate_r(extHandle, g, d * length); } GEOSGeometry* GEOSGeom_extractUniquePoints_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) return 0; using namespace geos::geom; using namespace geos::util; try { /* 1: extract points */ std::vector coords; UniqueCoordinateArrayFilter filter(coords); g->apply_ro(&filter); /* 2: for each point, create a geometry and put into a vector */ std::vector* points = new std::vector(); points->reserve(coords.size()); const GeometryFactory* factory = g->getFactory(); for (std::vector::iterator it=coords.begin(), itE=coords.end(); it != itE; ++it) { Geometry* point = factory->createPoint(*(*it)); points->push_back(point); } /* 3: create a multipoint */ return factory->createMultiPoint(points); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 0; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 0; } } int GEOSOrientationIndex_r(GEOSContextHandle_t extHandle, double Ax, double Ay, double Bx, double By, double Px, double Py) { GEOSContextHandleInternal_t *handle = 0; using geos::geom::Coordinate; using geos::algorithm::CGAlgorithms; if ( 0 == extHandle ) { return 2; } handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) { return 2; } try { Coordinate A(Ax, Ay); Coordinate B(Bx, By); Coordinate P(Px, Py); return CGAlgorithms::orientationIndex(A, B, P); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 2; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 2; } } GEOSGeometry * GEOSSharedPaths_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g1, const GEOSGeometry* g2) { using namespace geos::operation::sharedpaths; if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) return 0; SharedPathsOp::PathList forw, back; try { SharedPathsOp::sharedPathsOp(*g1, *g2, forw, back); } catch (const std::exception &e) { SharedPathsOp::clearEdges(forw); SharedPathsOp::clearEdges(back); handle->ERROR_MESSAGE("%s", e.what()); return 0; } catch (...) { SharedPathsOp::clearEdges(forw); SharedPathsOp::clearEdges(back); handle->ERROR_MESSAGE("Unknown exception thrown"); return 0; } // Now forw and back have the geoms we want to use to construct // our output GeometryCollections... const GeometryFactory* factory = g1->getFactory(); size_t count; std::auto_ptr< std::vector > out1( new std::vector() ); count = forw.size(); out1->reserve(count); for (size_t i=0; ipush_back(forw[i]); } std::auto_ptr out1g ( factory->createMultiLineString(out1.release()) ); std::auto_ptr< std::vector > out2( new std::vector() ); count = back.size(); out2->reserve(count); for (size_t i=0; ipush_back(back[i]); } std::auto_ptr out2g ( factory->createMultiLineString(out2.release()) ); std::auto_ptr< std::vector > out( new std::vector() ); out->reserve(2); out->push_back(out1g.release()); out->push_back(out2g.release()); std::auto_ptr outg ( factory->createGeometryCollection(out.release()) ); return outg.release(); } GEOSGeometry * GEOSSnap_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g1, const GEOSGeometry* g2, double tolerance) { using namespace geos::operation::overlay::snap; if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = reinterpret_cast(extHandle); if ( handle->initialized == 0 ) return 0; try{ GeometrySnapper snapper( *g1 ); std::auto_ptr ret = snapper.snapTo(*g2, tolerance); return ret.release(); } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); return 0; } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); return 0; } } BufferParameters * GEOSBufferParams_create_r(GEOSContextHandle_t extHandle) { if ( 0 == extHandle ) return NULL; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return NULL; try { BufferParameters *p = new BufferParameters(); return p; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } void GEOSBufferParams_destroy_r(GEOSContextHandle_t extHandle, BufferParameters* p) { (void)extHandle; delete p; } int GEOSBufferParams_setEndCapStyle_r(GEOSContextHandle_t extHandle, GEOSBufferParams* p, int style) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return 0; try { if ( style > BufferParameters::CAP_SQUARE ) { throw IllegalArgumentException("Invalid buffer endCap style"); } p->setEndCapStyle(static_cast(style)); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSBufferParams_setJoinStyle_r(GEOSContextHandle_t extHandle, GEOSBufferParams* p, int style) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return 0; try { if ( style > BufferParameters::JOIN_BEVEL ) { throw IllegalArgumentException("Invalid buffer join style"); } p->setJoinStyle(static_cast(style)); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSBufferParams_setMitreLimit_r(GEOSContextHandle_t extHandle, GEOSBufferParams* p, double limit) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return 0; try { p->setMitreLimit(limit); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSBufferParams_setQuadrantSegments_r(GEOSContextHandle_t extHandle, GEOSBufferParams* p, int segs) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return 0; try { p->setQuadrantSegments(segs); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSBufferParams_setSingleSided_r(GEOSContextHandle_t extHandle, GEOSBufferParams* p, int ss) { if ( 0 == extHandle ) return 0; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return 0; try { p->setSingleSided( (ss != 0) ); return 1; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } Geometry * GEOSBufferWithParams_r(GEOSContextHandle_t extHandle, const Geometry *g1, const BufferParameters* bp, double width) { using geos::operation::buffer::BufferOp; if ( 0 == extHandle ) return NULL; GEOSContextHandleInternal_t *handle = 0; handle = reinterpret_cast(extHandle); if ( 0 == handle->initialized ) return NULL; try { BufferOp op(g1, *bp); Geometry *g3 = op.getResultGeometry(width); return g3; } catch (const std::exception &e) { handle->ERROR_MESSAGE("%s", e.what()); } catch (...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } } /* extern "C" */