EVOLUTION-MANAGER
Edit File: geos_ts_c.cpp
/************************************************************************ * * * C-Wrapper for GEOS library * * Copyright (C) 2010-2012 Sandro Santilli <strk@kbt.io> * 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 <strk@kbt.io> * Thread Safety modifications: Chuck Thibert <charles.thibert@ingres.com> * ***********************************************************************/ #include <geos/geom/Coordinate.h> #include <geos/geom/Geometry.h> #include <geos/geom/prep/PreparedGeometry.h> #include <geos/geom/prep/PreparedGeometryFactory.h> #include <geos/geom/GeometryCollection.h> #include <geos/geom/Polygon.h> #include <geos/geom/Point.h> #include <geos/geom/MultiPoint.h> #include <geos/geom/MultiLineString.h> #include <geos/geom/MultiPolygon.h> #include <geos/geom/LinearRing.h> #include <geos/geom/LineSegment.h> #include <geos/geom/LineString.h> #include <geos/geom/PrecisionModel.h> #include <geos/geom/GeometryFactory.h> #include <geos/geom/CoordinateSequenceFactory.h> #include <geos/geom/FixedSizeCoordinateSequence.h> #include <geos/geom/Coordinate.h> #include <geos/geom/IntersectionMatrix.h> #include <geos/geom/Envelope.h> #include <geos/index/strtree/STRtree.h> #include <geos/index/strtree/GeometryItemDistance.h> #include <geos/index/ItemVisitor.h> #include <geos/io/WKTReader.h> #include <geos/io/WKBReader.h> #include <geos/io/WKTWriter.h> #include <geos/io/WKBWriter.h> #include <geos/algorithm/BoundaryNodeRule.h> #include <geos/algorithm/MinimumBoundingCircle.h> #include <geos/algorithm/MinimumDiameter.h> #include <geos/algorithm/Orientation.h> #include <geos/algorithm/distance/DiscreteHausdorffDistance.h> #include <geos/algorithm/distance/DiscreteFrechetDistance.h> #include <geos/simplify/DouglasPeuckerSimplifier.h> #include <geos/simplify/TopologyPreservingSimplifier.h> #include <geos/noding/GeometryNoder.h> #include <geos/noding/Noder.h> #include <geos/operation/buffer/BufferBuilder.h> #include <geos/operation/buffer/BufferOp.h> #include <geos/operation/buffer/BufferParameters.h> #include <geos/operation/distance/DistanceOp.h> #include <geos/operation/distance/IndexedFacetDistance.h> #include <geos/operation/linemerge/LineMerger.h> #include <geos/operation/overlay/OverlayOp.h> #include <geos/operation/overlay/snap/GeometrySnapper.h> #include <geos/operation/intersection/Rectangle.h> #include <geos/operation/intersection/RectangleIntersection.h> #include <geos/operation/polygonize/Polygonizer.h> #include <geos/operation/polygonize/BuildArea.h> #include <geos/operation/relate/RelateOp.h> #include <geos/operation/sharedpaths/SharedPathsOp.h> #include <geos/operation/union/CascadedPolygonUnion.h> #include <geos/operation/union/CoverageUnion.h> #include <geos/operation/valid/IsValidOp.h> #include <geos/operation/valid/MakeValid.h> #include <geos/precision/GeometryPrecisionReducer.h> #include <geos/linearref/LengthIndexedLine.h> #include <geos/triangulate/DelaunayTriangulationBuilder.h> #include <geos/triangulate/VoronoiDiagramBuilder.h> #include <geos/util.h> #include <geos/util/IllegalArgumentException.h> #include <geos/util/Interrupt.h> #include <geos/util/UniqueCoordinateArrayFilter.h> #include <geos/util/Machine.h> #include <geos/version.h> // This should go away #include <cmath> // finite #include <cstdarg> #include <cstddef> #include <cstdio> #include <cstdlib> #include <cstring> #include <fstream> #include <iostream> #include <sstream> #include <string> #include <memory> #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 <cmath>. 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 <geos/export.h> #include <geos/precision/MinimumClearance.h> // import the most frequently used definitions globally using geos::geom::Geometry; using geos::geom::LineString; using geos::geom::LinearRing; using geos::geom::MultiLineString; using geos::geom::MultiPolygon; using geos::geom::Polygon; using geos::geom::CoordinateSequence; using geos::geom::GeometryCollection; 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::distance::IndexedFacetDistance; using geos::operation::buffer::BufferParameters; using geos::operation::buffer::BufferBuilder; using geos::precision::GeometryPrecisionReducer; using geos::util::IllegalArgumentException; using geos::algorithm::distance::DiscreteHausdorffDistance; using geos::algorithm::distance::DiscreteFrechetDistance; typedef std::unique_ptr<Geometry> GeomPtr; typedef struct GEOSContextHandle_HS { const GeometryFactory* geomFactory; char msgBuffer[1024]; GEOSMessageHandler noticeMessageOld; GEOSMessageHandler_r noticeMessageNew; void* noticeData; GEOSMessageHandler errorMessageOld; GEOSMessageHandler_r errorMessageNew; void* errorData; int WKBOutputDims; int WKBByteOrder; int initialized; GEOSContextHandle_HS() : geomFactory(0), noticeMessageOld(0), noticeMessageNew(0), noticeData(0), errorMessageOld(0), errorMessageNew(0), errorData(0) { memset(msgBuffer, 0, sizeof(msgBuffer)); geomFactory = GeometryFactory::getDefaultInstance(); WKBOutputDims = 2; WKBByteOrder = getMachineByteOrder(); setNoticeHandler(NULL); setErrorHandler(NULL); initialized = 1; } GEOSMessageHandler setNoticeHandler(GEOSMessageHandler nf) { GEOSMessageHandler f = noticeMessageOld; noticeMessageOld = nf; noticeMessageNew = NULL; noticeData = NULL; return f; } GEOSMessageHandler setErrorHandler(GEOSMessageHandler nf) { GEOSMessageHandler f = errorMessageOld; errorMessageOld = nf; errorMessageNew = NULL; errorData = NULL; return f; } GEOSMessageHandler_r setNoticeHandler(GEOSMessageHandler_r nf, void* userData) { GEOSMessageHandler_r f = noticeMessageNew; noticeMessageOld = NULL; noticeMessageNew = nf; noticeData = userData; return f; } GEOSMessageHandler_r setErrorHandler(GEOSMessageHandler_r ef, void* userData) { GEOSMessageHandler_r f = errorMessageNew; errorMessageOld = NULL; errorMessageNew = ef; errorData = userData; return f; } void NOTICE_MESSAGE(string fmt, ...) { if(NULL == noticeMessageOld && NULL == noticeMessageNew) { return; } va_list args; va_start(args, fmt); int result = vsnprintf(msgBuffer, sizeof(msgBuffer) - 1, fmt.c_str(), args); va_end(args); if(result > 0) { if(noticeMessageOld) { noticeMessageOld("%s", msgBuffer); } else { noticeMessageNew(msgBuffer, noticeData); } } } void ERROR_MESSAGE(string fmt, ...) { if(NULL == errorMessageOld && NULL == errorMessageNew) { return; } va_list args; va_start(args, fmt); int result = vsnprintf(msgBuffer, sizeof(msgBuffer) - 1, fmt.c_str(), args); va_end(args); if(result > 0) { if(errorMessageOld) { errorMessageOld("%s", msgBuffer); } else { errorMessageNew(msgBuffer, errorData); } } } } 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) override { callback(item, userdata); } }; //## PROTOTYPES ############################################# extern "C" const char GEOS_DLL* GEOSjtsport(); extern "C" char GEOS_DLL* GEOSasText(Geometry* g1); namespace { // anonymous char* gstrdup_s(const char* str, const std::size_t size) { char* out = static_cast<char*>(malloc(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) { GEOSContextHandle_t handle = GEOS_init_r(); if(0 != handle) { GEOSContext_setNoticeHandler_r(handle, nf); GEOSContext_setErrorHandler_r(handle, ef); } return handle; } GEOSContextHandle_t GEOS_init_r() { GEOSContextHandleInternal_t* handle = new GEOSContextHandleInternal_t(); geos::util::Interrupt::cancel(); return static_cast<GEOSContextHandle_t>(handle); } GEOSMessageHandler GEOSContext_setNoticeHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf) { GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } return handle->setNoticeHandler(nf); } GEOSMessageHandler GEOSContext_setErrorHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler nf) { GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } return handle->setErrorHandler(nf); } GEOSMessageHandler_r GEOSContext_setNoticeMessageHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler_r nf, void* userData) { GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } return handle->setNoticeHandler(nf, userData); } GEOSMessageHandler_r GEOSContext_setErrorMessageHandler_r(GEOSContextHandle_t extHandle, GEOSMessageHandler_r ef, void* userData) { GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } return handle->setErrorHandler(ef, userData); } void finishGEOS_r(GEOSContextHandle_t extHandle) { // Fix up freeing handle w.r.t. malloc above delete extHandle; extHandle = NULL; } void GEOS_finish_r(GEOSContextHandle_t extHandle) { finishGEOS_r(extHandle); } void GEOSFree_r(GEOSContextHandle_t extHandle, void* buffer) { assert(0 != extHandle); free(buffer); } //----------------------------------------------------------- // relate()-related functions // return 0 = false, 1 = true, 2 = error occurred //----------------------------------------------------------- char GEOSDisjoint_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2) { if(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::geom::IntersectionMatrix; auto im = g1->relate(g2); if(im == nullptr) { return 0; } char* result = gstrdup(im->toString()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::operation::relate::RelateOp; using geos::geom::IntersectionMatrix; using geos::algorithm::BoundaryNodeRule; std::unique_ptr<IntersectionMatrix> im; switch(bnr) { case GEOSRELATE_BNR_MOD2: /* same as OGC */ im = RelateOp::relate(g1, g2, BoundaryNodeRule::getBoundaryRuleMod2()); break; case GEOSRELATE_BNR_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::getBoundaryEndPoint()); break; case GEOSRELATE_BNR_MULTIVALENT_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::getBoundaryMultivalentEndPoint()); break; case GEOSRELATE_BNR_MONOVALENT_ENDPOINT: im = RelateOp::relate(g1, g2, BoundaryNodeRule::getBoundaryMonovalentEndPoint()); break; default: handle->ERROR_MESSAGE("Invalid boundary node rule %d", bnr); return 0; break; } if(0 == im) { return 0; } char* result = gstrdup(im->toString()); 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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 2; } 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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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 GEOSDistanceIndexed_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double* dist) { assert(0 != dist); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { *dist = IndexedFacetDistance::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 GEOSHausdorffDistance_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double* dist) { assert(0 != dist); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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 GEOSFrechetDistance_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double* dist) { assert(0 != dist); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { *dist = DiscreteFrechetDistance::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 GEOSFrechetDistanceDensify_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2, double densifyFrac, double* dist) { assert(0 != dist); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { *dist = DiscreteFrechetDistance::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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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; } CoordinateSequence* GEOSNearestPoints_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { if(g1->isEmpty() || g2->isEmpty()) { return 0; } return geos::operation::distance::DistanceOp::nearestPoints(g1, g2).release(); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSGeomFromWKT_r(GEOSContextHandle_t extHandle, const char* wkt) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const std::string wktstring(wkt); WKTReader r(static_cast<GeometryFactory const*>(handle->geomFactory)); auto g = r.read(wktstring); return g.release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<unsigned char*>(malloc(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } using geos::io::WKBReader; try { std::string wkbstring(reinterpret_cast<const char*>(wkb), size); // make it binary ! WKBReader r(*(static_cast<GeometryFactory const*>(handle->geomFactory))); std::istringstream is(std::ios_base::binary); is.str(wkbstring); is.seekg(0, std::ios::beg); // rewind reader pointer auto g = r.read(is); return g.release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<unsigned char*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } using geos::io::WKBReader; try { std::string hexstring(reinterpret_cast<const char*>(hex), size); WKBReader r(*(static_cast<GeometryFactory const*>(handle->geomFactory))); std::istringstream is(std::ios_base::binary); is.str(hexstring); is.seekg(0, std::ios::beg); // rewind reader pointer auto g = r.readHEX(is); return g.release(); } 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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 2; } try { const LineString* ls = dynamic_cast<const LineString*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* g3 = g1->getEnvelope().release(); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* g3 = g1->intersection(g2).release(); g3->setSRID(g1->getSRID()); return g3; } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* g3 = g1->buffer(width, quadrantsegments).release(); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<BufferParameters::EndCapStyle>(endCapStyle) ); if(joinStyle > BufferParameters::JOIN_BEVEL) { throw IllegalArgumentException("Invalid buffer join style"); } bp.setJoinStyle( static_cast<BufferParameters::JoinStyle>(joinStyle) ); bp.setMitreLimit(mitreLimit); BufferOp op(g1, bp); Geometry* g3 = op.getResultGeometry(width); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<BufferParameters::JoinStyle>(joinStyle) ); bp.setMitreLimit(mitreLimit); bool isLeftSide = true; if(width < 0) { isLeftSide = false; width = -width; } BufferBuilder bufBuilder(bp); Geometry* g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<BufferParameters::JoinStyle>(joinStyle) ); bp.setMitreLimit(mitreLimit); bool isLeftSide = leftSide == 0 ? false : true; BufferBuilder bufBuilder(bp); Geometry* g3 = bufBuilder.bufferLineSingleSided(g1, width, isLeftSide); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* g3 = g1->convexHull().release(); g3->setSRID(g1->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSMinimumRotatedRectangle_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { geos::algorithm::MinimumDiameter m(g); Geometry* g3 = m.getMinimumRectangle().release(); g3->setSRID(g->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSMinimumWidth_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { geos::algorithm::MinimumDiameter m(g); Geometry* g3 = m.getDiameter().release(); g3->setSRID(g->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSMinimumClearanceLine_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { geos::precision::MinimumClearance mc(g); Geometry *g3 = mc.getLine().release(); g3->setSRID(g->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSMinimumClearance_r(GEOSContextHandle_t extHandle, const Geometry* g, double* d) { if(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 2; } try { geos::precision::MinimumClearance mc(g); double res = mc.getDistance(); *d = res; return 0; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 2; } Geometry* GEOSDifference_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* g2) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry *g3 = g1->difference(g2).release(); g3->setSRID(g1->getSRID()); return g3; } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* g3 = g1->getBoundary().release(); g3->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry *g3 = g1->symDifference(g2).release(); g3->setSRID(g1->getSRID()); return g3; } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry *g3 = g1->Union(g2).release(); g3->setSRID(g1->getSRID()); return g3; } catch(const std::exception& e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSUnion_r with following inputs:" << std::endl; s << "A: " << g1->toString() << std::endl; s << "B: " << g2->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* GEOSCoverageUnion_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry *g3 = geos::operation::geounion::CoverageUnion::Union(g).release(); g3->setSRID(g->getSRID()); return g3; } catch(const std::exception& e) { 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { GeomPtr g3(g->Union()); g3->setSRID(g->getSRID()); return g3.release(); } catch(const std::exception& e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSUnaryUnion_r with following inputs:" << std::endl; s << "A: " << g1->toString() << std::endl; s << "B: " << g2->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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { std::unique_ptr<Geometry> g3 = geos::noding::GeometryNoder::node(*g); g3->setSRID(g->getSRID()); return g3.release(); } catch(const std::exception& e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSNode_r with following inputs:" << std::endl; s << "A: " << g1->toString() << std::endl; s << "B: " << g2->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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const geos::geom::MultiPolygon* p = dynamic_cast<const geos::geom::MultiPolygon*>(g1); if(! p) { handle->ERROR_MESSAGE("Invalid argument (must be a MultiPolygon)"); return NULL; } using geos::operation::geounion::CascadedPolygonUnion; Geometry *g3 = CascadedPolygonUnion::Union(p); g3->setSRID(g1->getSRID()); return g3; } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { auto ret = g1->getInteriorPoint(); if(ret == nullptr) { const GeometryFactory* gf = handle->geomFactory; // return an empty point return gf->createPoint().release(); } ret->setSRID(g1->getSRID()); return ret.release(); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSClipByRect_r(GEOSContextHandle_t extHandle, const Geometry* g, double xmin, double ymin, double xmax, double ymax) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::operation::intersection::Rectangle; using geos::operation::intersection::RectangleIntersection; Rectangle rect(xmin, ymin, xmax, ymax); std::unique_ptr<Geometry> g3 = RectangleIntersection::clip(*g, rect); g3->setSRID(g->getSRID()); return g3.release(); } catch(const std::exception& e) { #if VERBOSE_EXCEPTIONS std::ostringstream s; s << "Exception on GEOSClipByRect_r with following inputs:" << std::endl; s << "A: " << g1->toString() << std::endl; s << "B: " << g2->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; } //------------------------------------------------------------------- // 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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } void GEOSGeom_setUserData_r(GEOSContextHandle_t extHandle, Geometry* g, void* userData) { assert(0 != g); if(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } g->setUserData(userData); } void GEOSSetSRID_r(GEOSContextHandle_t extHandle, Geometry* g, int srid) { assert(0 != g); if(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } g->setSRID(srid); } int GEOSGetNumCoordinates_r(GEOSContextHandle_t extHandle, const Geometry* g) { assert(0 != g); if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } try { return static_cast<int>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } try { const Polygon* p = dynamic_cast<const Polygon*>(g1); if(! p) { handle->ERROR_MESSAGE("Argument is not a Polygon"); return -1; } return static_cast<int>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } try { return static_cast<int>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::geom::LineString; const LineString* ls = dynamic_cast<const LineString*>(g1); if(! ls) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getPointN(n).release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::geom::LineString; const LineString* ls = dynamic_cast<const LineString*>(g1); if(! ls) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getStartPoint().release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::geom::LineString; const LineString* ls = dynamic_cast<const LineString*>(g1); if(! ls) { handle->ERROR_MESSAGE("Argument is not a LineString"); return NULL; } return ls->getEndPoint().release(); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } /* * Call only on LINESTRING or MULTILINESTRING * return 2 on exception, 1 on true, 0 on false */ char GEOSisClosed_r(GEOSContextHandle_t extHandle, const Geometry* g1) { if(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 2; } try { using geos::geom::LineString; using geos::geom::MultiLineString; const LineString* ls = dynamic_cast<const LineString*>(g1); if(ls) { return ls->isClosed(); } const MultiLineString* mls = dynamic_cast<const MultiLineString*>(g1); if(mls) { return mls->isClosed(); } handle->ERROR_MESSAGE("Argument is not a LineString or MultiLineString"); return 2; } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { using geos::geom::LineString; const LineString* ls = dynamic_cast<const LineString*>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } try { using geos::geom::LineString; const LineString* ls = dynamic_cast<const LineString*>(g1); if(! ls) { handle->ERROR_MESSAGE("Argument is not a LineString"); return -1; } return static_cast<int>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { using geos::geom::Point; const Point* po = dynamic_cast<const Point*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { using geos::geom::Point; const Point* po = dynamic_cast<const Point*>(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; } /* * For POINT * returns 0 on exception, otherwise 1 */ int GEOSGeomGetZ_r(GEOSContextHandle_t extHandle, const Geometry* g1, double* z) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { using geos::geom::Point; const Point* po = dynamic_cast<const Point*>(g1); if(! po) { handle->ERROR_MESSAGE("Argument is not a Point"); return 0; } *z = po->getZ(); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const Polygon* p = dynamic_cast<const Polygon*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const Polygon* p = dynamic_cast<const Polygon*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { Geometry* ret = g->getCentroid().release(); if(0 == ret) { const GeometryFactory* gf = handle->geomFactory; return gf->createPoint().release(); } ret->setSRID(g->getSRID()); return ret; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSMinimumBoundingCircle_r(GEOSContextHandle_t extHandle, const Geometry* g, double* radius, Geometry** center) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { geos::algorithm::MinimumBoundingCircle mc(g); std::unique_ptr<Geometry> ret = mc.getCircle(); const GeometryFactory* gf = handle->geomFactory; if(!ret) { if (center) *center = NULL; if (radius) *radius = 0.0; return gf->createPolygon().release(); } if (center) *center = static_cast<Geometry*>(gf->createPoint(mc.getCentre())); if (radius) *radius = mc.getRadius(); ret->setSRID(g->getSRID()); return ret.release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } #ifdef GEOS_DEBUG char buf[256]; sprintf(buf, "createCollection: requested type %d", type); handle->NOTICE_MESSAGE("%s", buf);// TODO: Can handle->NOTICE_MESSAGE format that directly? #endif try { const GeometryFactory* gf = handle->geomFactory; std::unique_ptr<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.release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<Geometry*>* vgeoms = new std::vector<Geometry*>(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"); delete vgeoms; 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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 auto 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<as_polygon<Geometry*> > std::vector<Geometry*>* polyvec = new std::vector<Geometry*>(polys->size()); for(std::size_t i = 0; i < polys->size(); ++i) { (*polyvec)[i] = (*polys)[i].release(); } 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* GEOSPolygonize_valid_r(GEOSContextHandle_t extHandle, const Geometry* const* g, unsigned int ngeoms) { if(nullptr == extHandle) { return nullptr; } GEOSContextHandleInternal_t* handle = nullptr; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return nullptr; } Geometry* out = nullptr; try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr(true); int srid = 0; for(std::size_t i = 0; i < ngeoms; ++i) { plgnzr.add(g[i]); srid = g[i]->getSRID(); } auto polys = plgnzr.getPolygons(); if (polys->empty()) { out = handle->geomFactory->createGeometryCollection().release(); } else if (polys->size() == 1) { out = (*polys)[0].release(); } else { auto geoms = new std::vector<Geometry *>(polys->size()); for (size_t i = 0; i < polys->size(); i++) { (*geoms)[i] = (*polys)[i].release(); } out = handle->geomFactory->createMultiPolygon(geoms); } out->setSRID(srid); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return out; } Geometry* GEOSBuildArea_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return nullptr; } GEOSContextHandleInternal_t* handle = nullptr; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return nullptr; } Geometry* out = nullptr; try { using geos::operation::polygonize::BuildArea; BuildArea builder; out = builder.build(g).release(); out->setSRID(g->getSRID()); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return out; } Geometry* GEOSMakeValid_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return nullptr; } GEOSContextHandleInternal_t* handle = nullptr; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return nullptr; } Geometry* out = nullptr; try { // BuildArea using geos::operation::valid::MakeValid; MakeValid makeValid; out = makeValid.build(g).release(); out->setSRID(g->getSRID()); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } Geometry* out = 0; try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr; int srid = 0; for(std::size_t i = 0; i < ngeoms; ++i) { plgnzr.add(g[i]); srid = g[i]->getSRID(); } #if GEOS_DEBUG handle->NOTICE_MESSAGE("geometry vector added to polygonizer"); #endif const std::vector<const LineString*>& 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<Geometry*>* linevec = new std::vector<Geometry*>(lines.size()); for(std::size_t i = 0, n = lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone().release(); } const GeometryFactory* gf = handle->geomFactory; // The below takes ownership of the passed vector, // so we must *not* delete it out = gf->createGeometryCollection(linevec); out->setSRID(srid); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { // Polygonize using geos::operation::polygonize::Polygonizer; Polygonizer plgnzr; for(std::size_t i = 0; i < g->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<const LineString*>& lines = plgnzr.getCutEdges(); std::vector<Geometry*>* linevec = new std::vector<Geometry*>(lines.size()); for(std::size_t i = 0, n = lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone().release(); } // The below takes ownership of the passed vector, // so we must *not* delete it *cuts = gf->createGeometryCollection(linevec); } if(dangles) { const std::vector<const LineString*>& lines = plgnzr.getDangles(); std::vector<Geometry*>* linevec = new std::vector<Geometry*>(lines.size()); for(std::size_t i = 0, n = lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone().release(); } // The below takes ownership of the passed vector, // so we must *not* delete it *dangles = gf->createGeometryCollection(linevec); } if(invalid) { const std::vector<std::unique_ptr<LineString>>& lines = plgnzr.getInvalidRingLines(); std::vector<Geometry*>* linevec = new std::vector<Geometry*>(lines.size()); for(std::size_t i = 0, n = lines.size(); i < n; ++i) { (*linevec)[i] = lines[i]->clone().release(); } // The below takes ownership of the passed vector, // so we must *not* delete it *invalid = gf->createGeometryCollection(linevec); } auto polys = plgnzr.getPolygons(); std::vector<Geometry*>* polyvec = new std::vector<Geometry*>(polys->size()); for(std::size_t i = 0; i < polys->size(); ++i) { (*polyvec)[i] = (*polys)[i].release(); } Geometry* out = gf->createGeometryCollection(polyvec); out->setSRID(g->getSRID()); return out; } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } Geometry* out = 0; try { using geos::operation::linemerge::LineMerger; LineMerger lmrgr; lmrgr.add(g); std::vector<LineString*>* lines = lmrgr.getMergedLineStrings(); assert(0 != lines); #if GEOS_DEBUG handle->NOTICE_MESSAGE("output lines got"); #endif std::vector<Geometry*>* geoms = new std::vector<Geometry*>(lines->size()); for(std::vector<Geometry*>::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); out->setSRID(g->getSRID()); // 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; } Geometry* GEOSReverse_r(GEOSContextHandle_t extHandle, const Geometry* g) { assert(0 != g); if(nullptr == extHandle) { return nullptr; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return nullptr; } try { Geometry* g3 = g->reverse().release(); g3->setSRID(g->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return nullptr; } void* GEOSGeom_getUserData_r(GEOSContextHandle_t extHandle, const Geometry* g) { assert(0 != g); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { return g->getUserData(); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSGetSRID_r(GEOSContextHandle_t extHandle, const Geometry* g) { assert(0 != g); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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() { static char version[256]; sprintf(version, "%s ", GEOS_CAPI_VERSION); return version; } const char* GEOSjtsport() { return GEOS_JTS_PORT; } char GEOSHasZ_r(GEOSContextHandle_t extHandle, const Geometry* g) { assert(0 != g); if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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<char>(std::isfinite(az)); } int GEOS_getWKBOutputDims_r(GEOSContextHandle_t extHandle) { if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } return handle->WKBOutputDims; } int GEOS_setWKBOutputDims_r(GEOSContextHandle_t extHandle, int newdims) { if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } return handle->WKBByteOrder; } int GEOS_setWKBByteOrder_r(GEOSContextHandle_t extHandle, int byteOrder) { if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { switch (size) { case 1: return new geos::geom::FixedSizeCoordinateSequence<1>(dims); case 2: return new geos::geom::FixedSizeCoordinateSequence<2>(dims); default: { const GeometryFactory *gf = handle->geomFactory; return gf->getCoordinateSequenceFactory()->create(size, dims).release(); } } } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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); } int GEOSCoordSeq_setXY_r(GEOSContextHandle_t extHandle, CoordinateSequence* cs, unsigned int idx, double x, double y) { assert(0 != cs); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { cs->setAt({x, y}, idx); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_setXYZ_r(GEOSContextHandle_t extHandle, CoordinateSequence* cs, unsigned int idx, double x, double y, double z) { assert(0 != cs); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { cs->setAt({x, y, z}, idx); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } CoordinateSequence* GEOSCoordSeq_clone_r(GEOSContextHandle_t extHandle, const CoordinateSequence* cs) { assert(0 != cs); if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { return cs->clone().release(); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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_getXY_r(GEOSContextHandle_t extHandle, const CoordinateSequence* cs, unsigned int idx, double* x, double* y) { assert(0 != cs); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { auto& c = cs->getAt(idx); *x = c.x; *y = c.y; return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_getXYZ_r(GEOSContextHandle_t extHandle, const CoordinateSequence* cs, unsigned int idx, double* x, double* y, double* z) { assert(0 != cs); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { auto& c = cs->getAt(idx); *x = c.x; *y = c.y; *z = c.z; return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_getSize_r(GEOSContextHandle_t extHandle, const CoordinateSequence* cs, unsigned int* size) { assert(0 != cs); assert(0 != size); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { const std::size_t sz = cs->getSize(); *size = static_cast<unsigned int>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { const std::size_t dim = cs->getDimension(); *dims = static_cast<unsigned int>(dim); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSCoordSeq_isCCW_r(GEOSContextHandle_t extHandle, const CoordinateSequence* cs, char* val) { assert(cs != nullptr); assert(val != nullptr); if(extHandle == nullptr) { return 0; } GEOSContextHandleInternal_t* handle = nullptr; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { *val = geos::algorithm::Orientation::isCCW(cs); 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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } const CoordinateSequence* GEOSGeom_getCoordSeq_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { using geos::geom::Point; const LineString* ls = dynamic_cast<const LineString*>(g); if(ls) { return ls->getCoordinatesRO(); } const Point* p = dynamic_cast<const Point*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const GeometryFactory* gf = handle->geomFactory; return gf->createPoint().release(); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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_createPointFromXY_r(GEOSContextHandle_t extHandle, double x, double y) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { const GeometryFactory* gf = handle->geomFactory; geos::geom::Coordinate c(x, y); return gf->createPoint(c); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const GeometryFactory* gf = handle->geomFactory; return gf->createLineString().release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const GeometryFactory* gf = handle->geomFactory; return gf->createPolygon().release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using geos::geom::LinearRing; auto vholes = geos::detail::make_unique<std::vector<LinearRing*>>(nholes); for (size_t i = 0; i < nholes; i++) { (*vholes)[i] = dynamic_cast<LinearRing*>(holes[i]); if ((*vholes)[i] == nullptr) { handle->ERROR_MESSAGE("Hole is not a LinearRing"); return NULL; } } LinearRing* nshell = dynamic_cast<LinearRing*>(shell); if(! nshell) { handle->ERROR_MESSAGE("Shell is not a LinearRing"); return NULL; } const GeometryFactory* gf = handle->geomFactory; return gf->createPolygon(nshell, vholes.release()); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { return g->clone().release(); } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } GEOSGeometry* GEOSGeom_setPrecision_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g, double gridSize, int flags) { using namespace geos::geom; assert(0 != g); if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { const PrecisionModel* pm = g->getPrecisionModel(); double cursize = pm->isFloating() ? 0 : 1.0 / pm->getScale(); std::unique_ptr<PrecisionModel> newpm; if(gridSize != 0) { newpm.reset(new PrecisionModel(1.0 / gridSize)); } else { newpm.reset(new PrecisionModel()); } GeometryFactory::Ptr gf = GeometryFactory::create(newpm.get(), g->getSRID()); Geometry* ret; if(gridSize != 0 && cursize != gridSize) { // We need to snap the geometry GeometryPrecisionReducer reducer(*gf); reducer.setPointwise(flags & GEOS_PREC_NO_TOPO); reducer.setRemoveCollapsedComponents(!(flags & GEOS_PREC_KEEP_COLLAPSED)); ret = reducer.reduce(*g).release(); } else { // No need or willing to snap, just change the factory ret = gf->createGeometry(g); } return ret; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } double GEOSGeom_getPrecision_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g) { using namespace geos::geom; assert(0 != g); if(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return -1; } try { const PrecisionModel* pm = g->getPrecisionModel(); double cursize = pm->isFloating() ? 0 : 1.0 / pm->getScale(); return cursize; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return -1; } int GEOSGeom_getDimensions_r(GEOSContextHandle_t extHandle, const Geometry* g) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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; } int GEOSGeom_getXMin_r(GEOSContextHandle_t extHandle, const Geometry* g, double* value) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(g->isEmpty()) { return 0; } *value = g->getEnvelopeInternal()->getMinX(); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSGeom_getXMax_r(GEOSContextHandle_t extHandle, const Geometry* g, double* value) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(g->isEmpty()) { return 0; } *value = g->getEnvelopeInternal()->getMaxX(); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSGeom_getYMin_r(GEOSContextHandle_t extHandle, const Geometry* g, double* value) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(g->isEmpty()) { return 0; } *value = g->getEnvelopeInternal()->getMinY(); return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } int GEOSGeom_getYMax_r(GEOSContextHandle_t extHandle, const Geometry* g, double* value) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(g->isEmpty()) { return 0; } *value = g->getEnvelopeInternal()->getMaxY(); return 1; } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using namespace geos::simplify; Geometry::Ptr g3(DouglasPeuckerSimplifier::simplify(g1, tolerance)); g3->setSRID(g1->getSRID()); return g3.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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { using namespace geos::simplify; Geometry::Ptr g3(TopologyPreservingSimplifier::simplify(g1, tolerance)); g3->setSRID(g1->getSRID()); return g3.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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { const std::string wktstring(wkt); return reader->read(wktstring).release(); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } writer->setRoundingPrecision(precision); } void GEOSWKTWriter_setOutputDimension_r(GEOSContextHandle_t extHandle, WKTWriter* writer, int dim) { assert(0 != writer); if(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } writer->setOld3D(0 != useOld3D); } /* WKB Reader */ WKBReader* GEOSWKBReader_create_r(GEOSContextHandle_t extHandle) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } struct membuf : public std::streambuf { membuf(char* s, std::size_t n) { setg(s, s, s + n); } }; Geometry* GEOSWKBReader_read_r(GEOSContextHandle_t extHandle, WKBReader* reader, const unsigned char* wkb, size_t size) { assert(0 != reader); assert(0 != wkb); if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { //std::string wkbstring(reinterpret_cast<const char*>(wkb), size); // make it binary ! //std::istringstream is(std::ios_base::binary); //is.str(wkbstring); //is.seekg(0, std::ios::beg); // rewind reader pointer // http://stackoverflow.com/questions/2079912/simpler-way-to-create-a-c-memorystream-from-char-size-t-without-copying-t membuf mb((char*)wkb, size); istream is(&mb); return reader->read(is).release(); } 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { std::string hexstring(reinterpret_cast<const char*>(hex), size); std::istringstream is(std::ios_base::binary); is.str(hexstring); is.seekg(0, std::ios::beg); // rewind reader pointer return reader->readHEX(is).release(); } 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { std::ostringstream os(std::ios_base::binary); writer->write(*geom, os); const std::string& wkbstring = os.str(); const std::size_t len = wkbstring.length(); unsigned char* result = NULL; result = (unsigned char*) malloc(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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*) malloc(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(nullptr == extHandle) { return 0; } int ret = 0; GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } int ret = 0; GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1; } int ret = -1; GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 != handle->initialized) { try { int srid = writer->getIncludeSRID(); ret = srid; } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } } return static_cast<char>(ret); } void GEOSWKBWriter_setIncludeSRID_r(GEOSContextHandle_t extHandle, GEOSWKBWriter* writer, const char newIncludeSRID) { assert(0 != writer); if(nullptr == extHandle) { return; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } const geos::geom::prep::PreparedGeometry* prep = 0; try { prep = geos::geom::prep::PreparedGeometryFactory::prepare(g).release(); } 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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("Unknown exception thrown"); } } const GEOSGeometry* GEOSSTRtree_nearest_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree* tree, const geos::geom::Geometry* geom) { return (const GEOSGeometry*) GEOSSTRtree_nearest_generic_r(extHandle, tree, geom, geom, nullptr, nullptr); } const void* GEOSSTRtree_nearest_generic_r(GEOSContextHandle_t extHandle, geos::index::strtree::STRtree* tree, const void* item, const geos::geom::Geometry* itemEnvelope, GEOSDistanceCallback distancefn, void* userdata) { using namespace geos::index::strtree; GEOSContextHandleInternal_t* handle = 0; struct CustomItemDistance : public ItemDistance { CustomItemDistance(GEOSDistanceCallback p_distancefn, void* p_userdata) : m_distancefn(p_distancefn), m_userdata(p_userdata) {} GEOSDistanceCallback m_distancefn; void* m_userdata; double distance(const ItemBoundable* item1, const ItemBoundable* item2) override { const void* a = item1->getItem(); const void* b = item2->getItem(); double d; if(!m_distancefn(a, b, &d, m_userdata)) { throw std::runtime_error(std::string("Failed to compute distance.")); } return d; } }; try { if(distancefn) { CustomItemDistance itemDistance(distancefn, userdata); return tree->nearestNeighbour(itemEnvelope->getEnvelopeInternal(), item, &itemDistance); } else { GeometryItemDistance itemDistance = GeometryItemDistance(); return tree->nearestNeighbour(itemEnvelope->getEnvelopeInternal(), item, &itemDistance); } } catch(const std::exception& e) { if(nullptr == extHandle) { return NULL; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return NULL; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } 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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 2; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return; } handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { if(nullptr == extHandle) { return; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return -1.0; } GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(handle->initialized == 0) { return -1.0; } const geos::geom::Point* point = dynamic_cast<const geos::geom::Point*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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); point->setSRID(g->getSRID()); 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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(handle->initialized == 0) { return 0; } using namespace geos::geom; using namespace geos::util; try { /* 1: extract points */ std::vector<const Coordinate*> coords; UniqueCoordinateArrayFilter filter(coords); g->apply_ro(&filter); /* 2: for each point, create a geometry and put into a vector */ std::vector<Geometry*>* points = new std::vector<Geometry*>(); points->reserve(coords.size()); const GeometryFactory* factory = g->getFactory(); for(std::vector<const Coordinate*>::iterator it = coords.begin(), itE = coords.end(); it != itE; ++it) { Geometry* point = factory->createPoint(*(*it)); points->push_back(point); } /* 3: create a multipoint */ Geometry* out = factory->createMultiPoint(points); out->setSRID(g->getSRID()); return out; } 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::Orientation; if(nullptr == extHandle) { return 2; } handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 2; } try { Coordinate A(Ax, Ay); Coordinate B(Bx, By); Coordinate P(Px, Py); return Orientation::index(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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::unique_ptr< std::vector<Geometry*> > out1( new std::vector<Geometry*>() ); count = forw.size(); out1->reserve(count); for(size_t i = 0; i < count; ++i) { out1->push_back(forw[i]); } std::unique_ptr<Geometry> out1g( factory->createMultiLineString(out1.release()) ); std::unique_ptr< std::vector<Geometry*> > out2( new std::vector<Geometry*>() ); count = back.size(); out2->reserve(count); for(size_t i = 0; i < count; ++i) { out2->push_back(back[i]); } std::unique_ptr<Geometry> out2g( factory->createMultiLineString(out2.release()) ); std::unique_ptr< std::vector<Geometry*> > out( new std::vector<Geometry*>() ); out->reserve(2); out->push_back(out1g.release()); out->push_back(out2g.release()); std::unique_ptr<Geometry> outg( factory->createGeometryCollection(out.release()) ); outg->setSRID(g1->getSRID()); return outg.release(); } GEOSGeometry* GEOSSnap_r(GEOSContextHandle_t extHandle, const GEOSGeometry* g1, const GEOSGeometry* g2, double tolerance) { using namespace geos::operation::overlay::snap; if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(handle->initialized == 0) { return 0; } try { GeometrySnapper snapper(*g1); std::unique_ptr<Geometry> ret = snapper.snapTo(*g2, tolerance); ret->setSRID(g1->getSRID()); 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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(style > BufferParameters::CAP_SQUARE) { throw IllegalArgumentException("Invalid buffer endCap style"); } p->setEndCapStyle(static_cast<BufferParameters::EndCapStyle>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { if(style > BufferParameters::JOIN_BEVEL) { throw IllegalArgumentException("Invalid buffer join style"); } p->setJoinStyle(static_cast<BufferParameters::JoinStyle>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(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(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } try { BufferOp op(g1, *bp); Geometry* g3 = op.getResultGeometry(width); g3->setSRID(g1->getSRID()); return g3; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSDelaunayTriangulation_r(GEOSContextHandle_t extHandle, const Geometry* g1, double tolerance, int onlyEdges) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } using geos::triangulate::DelaunayTriangulationBuilder; try { DelaunayTriangulationBuilder builder; builder.setTolerance(tolerance); builder.setSites(*g1); if(onlyEdges) { Geometry* out = builder.getEdges(*g1->getFactory()).release(); out->setSRID(g1->getSRID()); return out; } else { Geometry* out = builder.getTriangles(*g1->getFactory()).release(); out->setSRID(g1->getSRID()); return out; } } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } Geometry* GEOSVoronoiDiagram_r(GEOSContextHandle_t extHandle, const Geometry* g1, const Geometry* env, double tolerance, int onlyEdges) { if(nullptr == extHandle) { return NULL; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return NULL; } using geos::triangulate::VoronoiDiagramBuilder; try { VoronoiDiagramBuilder builder; builder.setSites(*g1); builder.setTolerance(tolerance); if(env) { builder.setClipEnvelope(env->getEnvelopeInternal()); } if(onlyEdges) { Geometry* out = builder.getDiagramEdges(*g1->getFactory()).release(); out->setSRID(g1->getSRID()); return out; } else { Geometry* out = builder.getDiagram(*g1->getFactory()).release(); out->setSRID(g1->getSRID()); return out; } } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return NULL; } int GEOSSegmentIntersection_r(GEOSContextHandle_t extHandle, double ax0, double ay0, double ax1, double ay1, double bx0, double by0, double bx1, double by1, double* cx, double* cy) { if(nullptr == extHandle) { return 0; } GEOSContextHandleInternal_t* handle = 0; handle = reinterpret_cast<GEOSContextHandleInternal_t*>(extHandle); if(0 == handle->initialized) { return 0; } try { geos::geom::LineSegment a(ax0, ay0, ax1, ay1); geos::geom::LineSegment b(bx0, by0, bx1, by1); geos::geom::Coordinate isect = a.intersection(b); if(isect.isNull()) { return -1; } *cx = isect.x; *cy = isect.y; return 1; } catch(const std::exception& e) { handle->ERROR_MESSAGE("%s", e.what()); } catch(...) { handle->ERROR_MESSAGE("Unknown exception thrown"); } return 0; } } /* extern "C" */