From 6db0bb486a3ef7838a98fb7406a0dfbb057f70e2 Mon Sep 17 00:00:00 2001 From: Benjamin Trigona-Harany Date: Sun, 10 Nov 2019 09:42:15 -0800 Subject: gis/ossim: Updated for version 2.10.0. --- gis/ossim/0498f7.patch | 24 + gis/ossim/c0d975.patch | 127 ++++ gis/ossim/c45639.patch | 1646 ++++++++++++++++++++++++++++++++++++++++++++ gis/ossim/ossim.SlackBuild | 7 +- gis/ossim/ossim.info | 6 +- 5 files changed, 1805 insertions(+), 5 deletions(-) create mode 100644 gis/ossim/0498f7.patch create mode 100644 gis/ossim/c0d975.patch create mode 100644 gis/ossim/c45639.patch (limited to 'gis/ossim') diff --git a/gis/ossim/0498f7.patch b/gis/ossim/0498f7.patch new file mode 100644 index 000000000000..7dd026a5bd26 --- /dev/null +++ b/gis/ossim/0498f7.patch @@ -0,0 +1,24 @@ +From 0498f71e811ff3068ba491929c09aa5137ea0cca Mon Sep 17 00:00:00 2001 +From: Garrett Potts +Date: Thu, 31 Oct 2019 07:08:03 -0400 +Subject: [PATCH] Added missing headers + +--- + src/init/ossimInit.cpp | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/src/init/ossimInit.cpp b/src/init/ossimInit.cpp +index 9aeec9de..2c2ec2c1 100644 +--- a/src/init/ossimInit.cpp ++++ b/src/init/ossimInit.cpp +@@ -66,7 +66,9 @@ + #include + #include + #include +- ++#include ++#include ++#include + using namespace std; + + static ossimTrace traceExec = ossimTrace("ossimInit:exec"); diff --git a/gis/ossim/c0d975.patch b/gis/ossim/c0d975.patch new file mode 100644 index 000000000000..31423b557a0d --- /dev/null +++ b/gis/ossim/c0d975.patch @@ -0,0 +1,127 @@ +From c0d97536f9ac967941b6ca48a6a7a4dde44f4ee3 Mon Sep 17 00:00:00 2001 +From: Garrett Potts +Date: Thu, 31 Oct 2019 07:42:32 -0400 +Subject: [PATCH] Fixed a core dump + +--- + src/base/ossimPolyArea2d.cpp | 10 ++++--- + src/init/ossimInit.cpp | 52 +++--------------------------------- + 2 files changed, 9 insertions(+), 53 deletions(-) + +diff --git a/src/base/ossimPolyArea2d.cpp b/src/base/ossimPolyArea2d.cpp +index 572d59de..3212b74a 100644 +--- a/src/base/ossimPolyArea2d.cpp ++++ b/src/base/ossimPolyArea2d.cpp +@@ -100,6 +100,7 @@ class ossimPolyArea2dPrivate + void ossimPolyArea2dPrivate::setGeometry(const ossimPolygon &exteriorRing, + const std::vector &interiorRings) + { ++ + deleteGeometry(); + + if (exteriorRing.getNumberOfVertices() < 1) +@@ -107,14 +108,15 @@ void ossimPolyArea2dPrivate::setGeometry(const ossimPolygon &exteriorRing, + GEOSGeometryPtr shell = 0; + std::vector holes; + const std::vector &pts = exteriorRing.getVertexList(); +- int idx = 0; +- int n = (int)pts.size(); ++ ossim_int32 idx = 0; ++ ossim_int32 n = (int)pts.size(); + + bool firstAndLastSame = ((pts[0].x == pts[n - 1].x) && (pts[0].y == pts[n - 1].y)); + if (n > 0) + { + GEOSCoordSequence *shellSeq = GEOSCoordSeq_create( +- exteriorRing.getNumberOfVertices() + ((firstAndLastSame) ? 0 : 1), 2); ++ n + ((firstAndLastSame) ? 0 : 1), 2); ++ + //fill the exterior ring + for (idx = 0; idx < n; idx++) + { +@@ -123,7 +125,7 @@ void ossimPolyArea2dPrivate::setGeometry(const ossimPolygon &exteriorRing, + //if the original polygon didn't have the first and last point the same, make it so + if (!firstAndLastSame) + { +- GEOSCoordSeq_setXY(shellSeq, idx, pts[0].x, pts[0].y); ++ GEOSCoordSeq_setXY(shellSeq, n, pts[0].x, pts[0].y); + } + shell = GEOSGeom_createLinearRing(shellSeq); + //fill the interior rings +diff --git a/src/init/ossimInit.cpp b/src/init/ossimInit.cpp +index 2c2ec2c1..787a49d9 100644 +--- a/src/init/ossimInit.cpp ++++ b/src/init/ossimInit.cpp +@@ -195,6 +195,8 @@ void ossimInit::initialize(ossimArgumentParser& parser) + } + return; + } ++ initGEOS(geosNoticeFunction, geosErrorFunction); ++ + theInstance->parseEnvOptions(parser); + theInstance->parseNotifyOption(parser); + theInstance->parsePrefsOptions(parser); +@@ -253,7 +255,7 @@ void ossimInit::initialize() + } + return; + } +- ++ + int argc = 1; + char* argv[1]; + +@@ -261,54 +263,6 @@ void ossimInit::initialize() + argv[0][0] = '\0'; + initialize(argc, argv); + delete [] argv[0]; +- +-#if 0 +- static std::mutex m; +- std::lock_guard lock(m); +- if(theInitializedFlag) +- { +- if (traceDebug()) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "DEBUG ossimInit::initialize(): Already initialized, returning......" << std::endl; +- } +- return; +- } +- +- theInstance->theAppName = ""; +- theInstance->thePreferences = ossimPreferences::instance(); +- theInstance->initializeDefaultFactories(); +- +- if ( theElevEnabledFlag ) +- { +- theInstance->initializeElevation(); +- } +- +- theInstance->initializeLogFile(); +- +- //--- +- // To do: +- // We need a mechanism to register factories to the "front" or the +- // "back" of factory list so that plugins can override things. For +- // now we will initialize the plugins last... +- //--- +- if(thePluginLoaderEnabledFlag) +- { +- theInstance->initializePlugins(); +- } +- +- if (traceDebug()) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossim preferences file: " +- << theInstance->thePreferences->getPreferencesFilename() +- << "\nVersion: " << version() +- << "\nossimInit::initialize() leaving..." +- << std::endl; +- } +- +- theInitializedFlag = true; +-#endif + } + + void ossimInit::finalize() diff --git a/gis/ossim/c45639.patch b/gis/ossim/c45639.patch new file mode 100644 index 000000000000..10c11aef52ac --- /dev/null +++ b/gis/ossim/c45639.patch @@ -0,0 +1,1646 @@ +From c456397821cf369af4d9ff1fb60a5dfd1bcefc24 Mon Sep 17 00:00:00 2001 +From: Garrett Potts +Date: Wed, 30 Oct 2019 20:43:06 -0400 +Subject: [PATCH] Added new interfaces to support the geos_c api + +--- + include/ossim/base/ossimPolyArea2d.h | 171 ++-- + src/base/ossimPolyArea2d.cpp | 1084 +++++++++++--------------- + src/imaging/ossimImageGeometry.cpp | 2 +- + src/init/ossimInit.cpp | 51 +- + 4 files changed, 570 insertions(+), 738 deletions(-) + +diff --git a/include/ossim/base/ossimPolyArea2d.h b/include/ossim/base/ossimPolyArea2d.h +index ffb1d611..75db23fd 100644 +--- a/include/ossim/base/ossimPolyArea2d.h ++++ b/include/ossim/base/ossimPolyArea2d.h +@@ -5,10 +5,8 @@ + // Author: Garrett Potts + //******************************************************************* + //$Id: ossimPolyArea2d.h 23608 2015-10-28 13:51:35Z gpotts $ +- + #ifndef ossimPolyArea2d_HEADER + #define ossimPolyArea2d_HEADER 1 +- + #include + #include + #include +@@ -16,137 +14,76 @@ + #include + #include + +-class ossimDrect; +-class ossimIrect; +-class OssimPolyArea2dPrivate; ++class ossimPolyArea2dPrivate; + +-namespace geos +-{ +- namespace geom +- { +- class Geometry; +- } +-} +- +-class OSSIM_DLL ossimPolyArea2d : public ossimReferenced ++class OSSIM_DLL ossimPolyArea2d + { + public: +- friend class OssimPolyArea2dPrivate; +- friend OSSIM_DLL std::ostream& operator <<(std::ostream& out, const ossimPolyArea2d& data); +- ++ friend OSSIM_DLL std::ostream &operator<<(std::ostream &out, const ossimPolyArea2d &data); ++ friend class ossimPolyArea2dPrivate; + ossimPolyArea2d(); +- ossimPolyArea2d(const std::vector& polygon); +- ossimPolyArea2d(const std::vector& polygon); +- ossimPolyArea2d(const ossimPolygon& shell, const std::vector& holes); +- +- ossimPolyArea2d(const ossimDpt& p1, +- const ossimDpt& p2, +- const ossimDpt& p3, +- const ossimDpt& p4); +- ossimPolyArea2d(const ossimPolyArea2d& rhs); +- +- ossimPolyArea2d(const ossimIrect& rect); +- ossimPolyArea2d(const ossimDrect& rect); +- ossimPolyArea2d(const ossimPolygon& polygon); ++ ossimPolyArea2d(const std::vector &polygon); ++ ossimPolyArea2d(const std::vector &polygon); ++ ossimPolyArea2d(const ossimPolygon &shell, const std::vector &holes); ++ ++ ossimPolyArea2d(const ossimDpt &p1, ++ const ossimDpt &p2, ++ const ossimDpt &p3, ++ const ossimDpt &p4); ++ ossimPolyArea2d(const ossimPolyArea2d &rhs); ++ ++ ossimPolyArea2d(const ossimIrect &rect); ++ ossimPolyArea2d(const ossimDrect &rect); ++ ossimPolyArea2d(const ossimPolygon &polygon); + ~ossimPolyArea2d(); +- ++ + void clear() + { + clearPolygons(); + } +- const ossimPolyArea2d& operator =(const ossimPolyArea2d& rhs); +- const ossimPolyArea2d& operator =(const ossimPolygon& rhs); +- const ossimPolyArea2d& operator =(const ossimIrect& rect); +- const ossimPolyArea2d& operator =(const ossimDrect& rect); +- const ossimPolyArea2d& operator =(const std::vector& polygon); +- const ossimPolyArea2d& operator =(const std::vector& polygon); +- const ossimPolyArea2d& operator &=(const ossimPolyArea2d& rhs); +- ossimPolyArea2d operator &(const ossimPolyArea2d& rhs)const; +- ossimPolyArea2d operator +(const ossimPolyArea2d& rhs)const; +- const ossimPolyArea2d& operator +=(const ossimPolyArea2d& rhs); +- ossimPolyArea2d operator -(const ossimPolyArea2d& rhs)const; +- const ossimPolyArea2d& operator -=(const ossimPolyArea2d& rhs); +- +- bool intersects(const ossimPolyArea2d& rhs)const; +- +- void add(const ossimPolyArea2d& rhs); +- bool getVisiblePolygons(std::vector& polyList)const; +- bool getPolygonHoles(std::vector& polyList)const; +- +- /** +- * @brief Gets all of the polygons stored with their holes embedded. This +- * may be useful if an operation was performed on the original ossimPolyArea2d +- * that caused multiple polygons to be created internally. +- * +- * For example, if a rectangle is intersected with a U shape, the two top +- * portions of the U would be their own separate polygon. It's also possible +- * for these polygons to contain their own holes. This function will return +- * the two top polygons as separate ossimPolyArea2d objects (with any of +- * their holes embedded inside them). +- * +- * -------------------------------- +- * | | +- * | | +- * | ........ ......... | +- * | . . . . | +- * -.------.-----------.-------.--- +- * . . . . +- * . ............. . +- * . . +- * ............................ +- * +- * @param polylist an empty vector of ossimPolyArea2d that will be filled +- * @return returns true if it successfully places polygons in the input vector +- */ +- bool getCompletePolygons(std::vector& polyList)const; +- +- bool isEmpty()const; +- bool isValid(bool displayValidationError = false)const; +- bool isPointWithin(const ossimDpt& point)const; +- bool isPointWithin(double x, double y)const; +- void getBoundingRect(ossimDrect& rect); +- ++ const ossimPolyArea2d &operator=(const ossimPolyArea2d &rhs); ++ const ossimPolyArea2d &operator=(const ossimPolygon &rhs); ++ const ossimPolyArea2d &operator=(const ossimIrect &rect); ++ const ossimPolyArea2d &operator=(const ossimDrect &rect); ++ const ossimPolyArea2d &operator=(const std::vector &polygon); ++ const ossimPolyArea2d &operator=(const std::vector &polygon); ++ const ossimPolyArea2d &operator&=(const ossimPolyArea2d &rhs); ++ ossimPolyArea2d operator&(const ossimPolyArea2d &rhs) const; ++ ossimPolyArea2d operator+(const ossimPolyArea2d &rhs) const; ++ const ossimPolyArea2d &operator+=(const ossimPolyArea2d &rhs); ++ ossimPolyArea2d operator-(const ossimPolyArea2d &rhs) const; ++ const ossimPolyArea2d &operator-=(const ossimPolyArea2d &rhs); ++ ++ ossim_float64 getArea()const; ++ bool isEmpty() const; ++ void makeValid(); ++ bool isValid(bool displayValidationError = false) const; ++ bool isPointWithin(const ossimDpt &point) const; ++ bool isPointWithin(double x, double y) const; ++ void getBoundingRect(ossimDrect &rect) const; ++ ++ bool intersects(const ossimPolyArea2d &rhs) const; ++ void add(const ossimPolyArea2d &rhs); ++ bool getVisiblePolygons(std::vector &polyList) const; ++ bool getPolygonHoles(std::vector &polyList) const; ++ ++ ossimPolyArea2d &toMultiPolygon(); ++ + /** + * Returns the Well Known Text string + */ +- std::string toString()const; ++ std::string toString() const; ++ bool setFromWkt(const std::string &s); + +- /** +- * @brief Buffers the ossimPolyArea2d shape and returns a copy. This method +- * does not alter polygon. +- * +- * @param distance is the distance to buffer the shape by. Positive values +- * will expand the shape, and negative values will shrink the shape. +- * @return A shape that is a buffered (expanded/contracted) version of this +- * shape +- */ +- ossimPolyArea2d getBufferedShape(double distance=FLT_EPSILON) const; +- +- ossimPolyArea2d& setToBufferedShape(double distance=FLT_EPSILON); ++ bool saveState(ossimKeywordlist &kwl, ++ const char *prefix = 0) const; ++ bool loadState(const ossimKeywordlist &kwl, ++ const char *prefix = 0); + +- ossimPolyArea2d& toMultiPolygon(); +- bool saveState(ossimKeywordlist& kwl, +- const char* prefix=0)const; +- bool loadState(const ossimKeywordlist& kwl, +- const char* prefix=0); +- + protected: +- ++ ossimPolyArea2dPrivate *m_privateData; ++ + void clearPolygons(); +- void recurseVisibleGeometries(ossimPolygon::Vector& polyList, +- const geos::geom::Geometry* geom) const; +- +- void recurseHoles(ossimPolygon::Vector& polyList, +- const geos::geom::Geometry* geom) const; +- +- /** +- * @brief Recurses over the Geometry object to load all complete polygons +- * (a shell and any internal holes) into the ossimPolyArea2d. +- */ +- void recurseCompleteGeometries(std::vector& polyList, +- const geos::geom::Geometry* geom) const; +- +- OssimPolyArea2dPrivate* m_privateData; + }; + + #endif /* #ifndef ossimPolyArea2d_HEADER */ +diff --git a/src/base/ossimPolyArea2d.cpp b/src/base/ossimPolyArea2d.cpp +index fac88637..572d59de 100644 +--- a/src/base/ossimPolyArea2d.cpp ++++ b/src/base/ossimPolyArea2d.cpp +@@ -3,153 +3,167 @@ + // + // $Id: ossimPolyArea2d.cpp 23623 2015-11-13 18:24:28Z gpotts $ + //--- +- + #include +-#include +-#include ++#include ++#include ++#include ++#include + #include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include +-#include + #include +-#include +- +-using namespace std; ++#include ++#include ++#include + +-class MyGeomFactory : public geos::geom::GeometryFactory ++class ossimPolyArea2dPrivate + { + public: +- MyGeomFactory(): +- geos::geom::GeometryFactory(new geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING), +- -1) ++ typedef GEOSGeometry *GEOSGeometryPtr; ++ typedef const GEOSGeometry *ConstGEOSGeometryPtr; ++ ossimPolyArea2dPrivate() : m_geometry(GEOSGeom_createEmptyPolygon()) {} ++ virtual ~ossimPolyArea2dPrivate() { deleteGeometry(); } ++ void deleteGeometry() + { ++ if (m_geometry) ++ GEOSGeom_destroy(m_geometry); ++ m_geometry = 0; ++ } + ++ void setGeometry(GEOSGeometryPtr geom) ++ { ++ if(geom != m_geometry) ++ { ++ deleteGeometry(); ++ m_geometry = geom; ++ } + } +-}; +-class ossimGeometryFactoryWrapper : public ossimReferenced +-{ +-public: +- ossimGeometryFactoryWrapper() +- : m_geomFactory(0) ++ void setGeometry(const ossimPolygon &polygon, const std::vector &holes = std::vector()); ++ ++ void ringToPoints(const ConstGEOSGeometryPtr geom, std::vector &points) const; ++ void recurseVisibleGeometries(ossimPolygon::Vector &polyList) const + { +- //geos::geom::PrecisionModel *pm = +- // new geos::geom::PrecisionModel(geos::geom::PrecisionModel::FLOATING); +- m_geomFactory = new MyGeomFactory();//new geos::geom::GeometryFactory(pm, -1); ++ recurseVisibleGeometries(m_geometry, polyList); + } +- virtual ~ossimGeometryFactoryWrapper(){if(m_geomFactory) delete m_geomFactory;m_geomFactory=0;} +- +- MyGeomFactory* m_geomFactory; +-}; + +-class OssimPolyArea2dPrivate +-{ +-public: +- typedef geos::geom::Geometry* GeometryPtr; +- typedef const geos::geom::Geometry* ConstGeometryPtr; +- +- OssimPolyArea2dPrivate(GeometryPtr geom=0); +- ~OssimPolyArea2dPrivate(); +- +- void deleteGeometry() { if(m_geometry) { delete m_geometry; m_geometry = 0; }} +- void setGeometry(const ossimPolygon& polygon, const vector& holes = vector()); +- void setGeometry(GeometryPtr geom){deleteGeometry();m_geometry=geom;} +- geos::geom::GeometryFactory* geomFactory(){{return m_globalFactory.valid()?m_globalFactory->m_geomFactory:0;}} +- GeometryPtr m_geometry; +- static ossimRefPtr m_globalFactory; +-}; ++ void recurseVisibleGeometries(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const; + +-ossimRefPtr OssimPolyArea2dPrivate::m_globalFactory; ++ void getVisiblePolygons(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const; + +-OssimPolyArea2dPrivate::OssimPolyArea2dPrivate(GeometryPtr geom) +-:m_geometry(geom) +-{ +- static std::mutex globalFactoryMutex; +- ++ bool getVisiblePolygons(ossimPolygon::Vector &polygons) const; ++ ++ void getHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const; ++ bool getPolygonHoles(ossimPolygon::Vector &polygons) const; ++ bool getPolygonHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const; ++ void recurseGeometryHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const; ++ void getBoundingRect(ossimDrect &bounds) const + { +- std::lock_guard lock(globalFactoryMutex); +- if(!m_globalFactory.valid()) ++ bounds.makeNan(); ++ if (!isEmpty()) + { +- m_globalFactory = new ossimGeometryFactoryWrapper(); +- } ++ GEOSGeometry *geom = GEOSEnvelope(m_geometry); ++ ++ if (geom) ++ { ++ ossimPolygon::Vector polys; ++ getVisiblePolygons(geom, polys); ++ for (ossim_int32 idx = 0; idx < polys.size(); ++idx) ++ { ++ if (bounds.isNan()) ++ { ++ polys[idx].getBoundingRect(bounds); ++ } ++ else ++ { ++ ossimDrect tempRect; ++ polys[idx].getBoundingRect(tempRect); ++ bounds = bounds.combine(tempRect); ++ } ++ } ++ GEOSGeom_destroy(geom); ++ geom = 0; ++ } ++ } + } +-} ++ std::string toString() const; ++ bool setFromWkt(const std::string &s); + +-OssimPolyArea2dPrivate::~OssimPolyArea2dPrivate() +-{ +- deleteGeometry(); +-} ++ bool isEmpty() const; ++ bool isValid(bool displayValidationError = false) const; ++ bool isPointWithin(const ossimDpt &pt) const; ++ GEOSGeometryPtr m_geometry; ++}; + +-void OssimPolyArea2dPrivate::setGeometry( +- const ossimPolygon& exteriorRing, const vector& interiorRings) ++void ossimPolyArea2dPrivate::setGeometry(const ossimPolygon &exteriorRing, ++ const std::vector &interiorRings) + { + deleteGeometry(); +- +- geos::geom::CoordinateArraySequence *cas = new geos::geom::CoordinateArraySequence(); +- +- const std::vector& pts = exteriorRing.getVertexList(); + ++ if (exteriorRing.getNumberOfVertices() < 1) ++ return; ++ GEOSGeometryPtr shell = 0; ++ std::vector holes; ++ const std::vector &pts = exteriorRing.getVertexList(); + int idx = 0; + int n = (int)pts.size(); +- +- if(n > 0) ++ ++ bool firstAndLastSame = ((pts[0].x == pts[n - 1].x) && (pts[0].y == pts[n - 1].y)); ++ if (n > 0) + { ++ GEOSCoordSequence *shellSeq = GEOSCoordSeq_create( ++ exteriorRing.getNumberOfVertices() + ((firstAndLastSame) ? 0 : 1), 2); + //fill the exterior ring + for (idx = 0; idx < n; idx++) + { +- cas->add(geos::geom::Coordinate(pts[idx].x, pts[idx].y)); ++ GEOSCoordSeq_setXY(shellSeq, idx, pts[idx].x, pts[idx].y); + } +- + //if the original polygon didn't have the first and last point the same, make it so +- if((pts[0].x != pts[n-1].x) || (pts[0].y!=pts[n-1].y)) ++ if (!firstAndLastSame) + { +- cas->add(geos::geom::Coordinate(pts[0].x, pts[0].y)); ++ GEOSCoordSeq_setXY(shellSeq, idx, pts[0].x, pts[0].y); + } +- ++ shell = GEOSGeom_createLinearRing(shellSeq); + //fill the interior rings +- vector *holes = new vector(); +- for (ossim_uint32 interiorRingIdx = 0; interiorRingIdx < interiorRings.size(); ++interiorRingIdx) ++ if (!interiorRings.empty()) + { +- geos::geom::CoordinateArraySequence *interiorCas = +- new geos::geom::CoordinateArraySequence(); +- const std::vector& vertexPts = interiorRings[interiorRingIdx].getVertexList(); +- for(ossim_uint32 vertexIndex=0; vertexIndex < vertexPts.size(); ++vertexIndex) +- { +- interiorCas->add(geos::geom::Coordinate(vertexPts[vertexIndex].x, +- vertexPts[vertexIndex].y)); +- } +- +- //if the original polygon didn't have the first and last point the same, make it so +- if((vertexPts[0].x != vertexPts[vertexPts.size()-1].x) || +- (vertexPts[0].y!=vertexPts[vertexPts.size()-1].y)) ++ for (ossim_uint32 interiorRingIdx = 0; interiorRingIdx < interiorRings.size(); ++interiorRingIdx) + { +- interiorCas->add(geos::geom::Coordinate(vertexPts[0].x, vertexPts[0].y)); ++ if (interiorRings[interiorRingIdx].getNumberOfVertices() > 0) ++ { ++ const std::vector &vertexPts = interiorRings[interiorRingIdx].getVertexList(); ++ firstAndLastSame = ((vertexPts[0].x == vertexPts[n - 1].x) && (vertexPts[0].y == vertexPts[n - 1].y)); ++ ++ GEOSCoordSequence *ring = GEOSCoordSeq_create( ++ vertexPts.size() + ((firstAndLastSame) ? 0 : 1), 2); ++ for (ossim_uint32 vertexIndex = 0; vertexIndex < vertexPts.size(); ++vertexIndex) ++ { ++ GEOSCoordSeq_setXY(ring, vertexIndex, vertexPts[vertexIndex].x, vertexPts[vertexIndex].y); ++ } ++ ++ //if the original polygon didn't have the first and last point the same, make it so ++ if (!firstAndLastSame) ++ { ++ GEOSCoordSeq_setXY(ring, vertexPts.size(), vertexPts[0].x, vertexPts[0].y); ++ } ++ GEOSGeometryPtr hole = GEOSGeom_createLinearRing(ring); ++ holes.push_back(hole); ++ } + } +- +- geos::geom::LinearRing *hole = geomFactory()->createLinearRing(interiorCas); +- holes->push_back(hole); + } +- +- geos::geom::LinearRing* shell = geomFactory()->createLinearRing(cas); +- if ( shell ) ++ ++ if (shell) + { +- m_geometry = geomFactory()->createPolygon(shell, holes); ++ if (holes.size()) ++ { ++ m_geometry = GEOSGeom_createPolygon(shell, &holes.front(), holes.size()); ++ } ++ else ++ { ++ m_geometry = GEOSGeom_createPolygon(shell, 0, 0); ++ } + } + else + { +@@ -158,708 +172,540 @@ void OssimPolyArea2dPrivate::setGeometry( + } + } + +-void ossimPolyArea2d::recurseVisibleGeometries( +- std::vector& polyList, const geos::geom::Geometry* geom) const ++void ossimPolyArea2dPrivate::ringToPoints(const ConstGEOSGeometryPtr geom, std::vector &points) const + { +- int nGeoms = (int)geom->getNumGeometries(); +- +- if(nGeoms < 2 ) ++ double x, y; ++ if (!geom) ++ return; ++ ossim_int32 nPoints = GEOSGetNumCoordinates(geom); ++ if (nPoints > 0) + { +- const geos::geom::Polygon* poly = dynamic_cast (geom); +- +- if (poly) ++ const GEOSCoordSequence *seq = GEOSGeom_getCoordSeq(geom); ++ ossim_int32 i = 0; ++ for (i = 0; i < nPoints; i++) + { +- const geos::geom::LineString* lineString = dynamic_cast (poly->getExteriorRing()); +- if (lineString) +- { +- int currentPolyIdx = (int)polyList.size(); +- int nPoints = (int)lineString->getNumPoints(); +- int idx = 0; +- +- polyList.push_back(ossimPolygon()); +- +- for (idx=0; idx point(lineString->getPointN(idx)); +- polyList[currentPolyIdx].addPoint(point->getX(), point->getY()); +- } +- } ++ GEOSCoordSeq_getX(seq, i, &x); ++ GEOSCoordSeq_getY(seq, i, &y); ++ points.push_back(ossimDpt(x, y)); + } + } +- else ++} ++ ++void ossimPolyArea2dPrivate::getHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const ++{ ++ int geomType = GEOSGeomTypeId(geom); ++ std::vector points; ++ switch (geomType) + { +- for (int idx=0; idx < nGeoms; ++idx) +- { +- recurseVisibleGeometries(polyList, geom->getGeometryN(idx)); +- } ++ case GEOS_LINESTRING: ++ case GEOS_LINEARRING: ++ { ++ ringToPoints(geom, points); ++ polygons.push_back(ossimPolygon(points)); ++ break; ++ } + } + } + +-void ossimPolyArea2d::recurseHoles(std::vector& polyList, +- const geos::geom::Geometry* geom) const ++void ossimPolyArea2dPrivate::getVisiblePolygons(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const + { +- int nGeoms = (int)geom->getNumGeometries(); +- +- if(nGeoms < 2 ) ++ int geomType = GEOSGeomTypeId(geom); ++ std::vector points; ++ ++ switch (geomType) + { +- const geos::geom::Polygon* poly = dynamic_cast (geom); ++ case GEOS_LINESTRING: ++ case GEOS_LINEARRING: ++ { ++ ringToPoints(geom, points); ++ polygons.push_back(ossimPolygon(points)); ++ break; ++ } ++ case GEOS_POLYGON: ++ { ++ ConstGEOSGeometryPtr geom2 = GEOSGetExteriorRing(geom); ++ ringToPoints(geom2, points); ++ polygons.push_back(ossimPolygon(points)); + +- if (poly) ++ break; ++ } ++ } ++} ++void ossimPolyArea2dPrivate::recurseVisibleGeometries(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const ++{ ++ ossim_int32 nGeoms = GEOSGetNumGeometries(geom); ++ ConstGEOSGeometryPtr geomPtr = 0; ++ if (nGeoms < 2) ++ { ++ geomPtr = GEOSGetGeometryN(geom, 0); ++ if (geomPtr) + { +- ossim_uint32 nInteriorRings = (ossim_uint32)poly->getNumInteriorRing(); +- ossim_uint32 idx = 0; +- +- for(idx = 0; idx < nInteriorRings; ++idx) +- { +- const geos::geom::LineString* lineString = poly->getInteriorRingN(idx); +- if (lineString) +- { +- int currentPolyIdx = (int)polyList.size(); +- int nPoints = (int)lineString->getNumPoints(); +- int idx = 0; +- +- polyList.push_back(ossimPolygon()); +- +- for (idx=0; idx point(lineString->getPointN(idx)); +- polyList[currentPolyIdx].addPoint(point->getX(), point->getY()); +- } +- } +- } ++ getVisiblePolygons(geomPtr, polygons); + } + } + else + { +- int idx = 0; +- +- for (idx=0; idx < nGeoms; idx++) ++ for (int idx = 0; idx < nGeoms; ++idx) + { +- recurseHoles(polyList, geom->getGeometryN(idx)); ++ geomPtr = GEOSGetGeometryN(geom, idx); ++ recurseVisibleGeometries(geomPtr, polygons); + } + } + } + +-void ossimPolyArea2d::recurseCompleteGeometries(std::vector& polyList, +- const geos::geom::Geometry* geom) const ++void ossimPolyArea2dPrivate::recurseGeometryHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const + { +- int nGeoms = (int)geom->getNumGeometries(); +- if(nGeoms < 2 ) ++ ossim_int32 nGeoms = GEOSGetNumGeometries(geom); ++ ConstGEOSGeometryPtr geomPtr = 0; ++ if (nGeoms < 2) + { +- const geos::geom::Polygon* poly = dynamic_cast (geom); ++ ossim_int32 nInteriorRings = GEOSGetNumInteriorRings(geom); ++ ossim_int32 idx = 0; + +- if (poly) ++ for (idx = 0; idx < nInteriorRings; ++idx) + { +- //get exterior shell for the geometry +- ossimPolygon shell; +- const geos::geom::LineString* lineString = +- dynamic_cast (poly->getExteriorRing()); +- if (lineString) +- { +- int nPoints = (int)lineString->getNumPoints(); +- for (int idx = 0; idx point(lineString->getPointN(idx)); +- shell.addPoint(point->getX(), point->getY()); +- } +- } +- +- // Get interior rings for the geometry. +- std::size_t nInteriorRings = poly->getNumInteriorRing(); +- vector holes(nInteriorRings); +- for(std::size_t holeIdx = 0; holeIdx < nInteriorRings; ++holeIdx) +- { +- const geos::geom::LineString* lineString = poly->getInteriorRingN(holeIdx); +- if (lineString) +- { +- std::size_t nPoints = lineString->getNumPoints(); +- for (std::size_t idx = 0; idx point(lineString->getPointN(idx)); +- holes[holeIdx].addPoint(point->getX(), point->getY()); +- } +- } +- } +- polyList.push_back(ossimPolyArea2d(shell, holes)); ++ const GEOSGeometry *ringGeom = GEOSGetInteriorRingN(geom, idx); ++ getHoles(ringGeom, polygons); + } + } + else + { +- int idx = 0; +- +- for (idx=0; idx < nGeoms; idx++) ++ for (int idx = 0; idx < nGeoms; ++idx) + { +- recurseCompleteGeometries(polyList, geom->getGeometryN(idx)); ++ geomPtr = GEOSGetGeometryN(geom, idx); ++ recurseGeometryHoles(geomPtr, polygons); + } + } + } + +-std::ostream& operator <<(std::ostream& out, const ossimPolyArea2d& rhs) ++bool ossimPolyArea2dPrivate::getVisiblePolygons(ossimPolygon::Vector &polygons) const + { +- if(rhs.m_privateData->m_geometry) ++ bool foundPolys = false; ++ if (m_geometry) + { +- out << rhs.m_privateData->m_geometry->toString(); ++ ossim_uint32 sizeBefore = (ossim_uint32)polygons.size(); ++ recurseVisibleGeometries(m_geometry, polygons); ++ foundPolys = (sizeBefore != polygons.size()); + } +- return out; +-} + +-ossimPolyArea2d::ossimPolyArea2d() +- :m_privateData(new OssimPolyArea2dPrivate) +-{ ++ return foundPolys; + } +- +-ossimPolyArea2d::ossimPolyArea2d(const vector& polygon) +- :m_privateData(new OssimPolyArea2dPrivate) ++bool ossimPolyArea2dPrivate::getPolygonHoles(ossimPolygon::Vector &polygons) const + { +- (*this) = polygon; ++ return getPolygonHoles(m_geometry, polygons); + } + +-ossimPolyArea2d::ossimPolyArea2d(const vector& polygon) +- :m_privateData(new OssimPolyArea2dPrivate) ++bool ossimPolyArea2dPrivate::getPolygonHoles(ConstGEOSGeometryPtr geom, ++ ossimPolygon::Vector &polygons) const + { +- (*this) = polygon; +-} ++ bool foundPolys = false; ++ if (m_geometry) ++ { ++ ossim_uint32 sizeBefore = (ossim_uint32)polygons.size(); ++ recurseGeometryHoles(m_geometry, polygons); ++ foundPolys = (sizeBefore != polygons.size()); ++ } + +-ossimPolyArea2d::ossimPolyArea2d(const ossimIrect& rect) +- :m_privateData(new OssimPolyArea2dPrivate) +-{ +- (*this) = rect; ++ return foundPolys; + } + +-ossimPolyArea2d::ossimPolyArea2d(const ossimDrect& rect) +- :m_privateData(new OssimPolyArea2dPrivate) ++std::string ossimPolyArea2dPrivate::toString() const + { +- (*this) = rect; +-} ++ std::string result; + +-ossimPolyArea2d::ossimPolyArea2d(const ossimPolygon& polygon) +- :m_privateData(new OssimPolyArea2dPrivate) +-{ +- (*this) = polygon; +-} ++ if (m_geometry) ++ { ++ GEOSWKTWriter *wktWriter = GEOSWKTWriter_create(); ++ GEOSWKTWriter_setRoundingPrecision(wktWriter, 20); ++ char *wkt_c = GEOSWKTWriter_write(wktWriter, m_geometry); + +-ossimPolyArea2d::ossimPolyArea2d(const ossimPolygon& exteriorRing, const vector& interiorRings) +- :m_privateData(new OssimPolyArea2dPrivate) +-{ +- m_privateData->setGeometry(exteriorRing, interiorRings); +-} ++ result = wkt_c; ++ GEOSWKTWriter_destroy(wktWriter); + +-ossimPolyArea2d::ossimPolyArea2d(const ossimPolyArea2d& rhs) +- :m_privateData(new OssimPolyArea2dPrivate) +-{ +- *this = rhs; +-} ++ GEOSFree(wkt_c); ++ } + +-ossimPolyArea2d::ossimPolyArea2d(const ossimDpt& p1, +- const ossimDpt& p2, +- const ossimDpt& p3, +- const ossimDpt& p4) +- : +- m_privateData(new OssimPolyArea2dPrivate) ++ return result; ++} ++bool ossimPolyArea2dPrivate::setFromWkt(const std::string &s) + { +- ossimPolygon temp(p1,p2,p3,p4); +- *this = temp; ++ bool result = false; ++ ++ GEOSWKTReader *reader = GEOSWKTReader_create(); ++ GEOSGeometry *geom = GEOSWKTReader_read(reader, s.c_str()); ++ result = (geom != 0); ++ setGeometry(geom); ++ ++ GEOSWKTReader_destroy(reader); ++ ++ return result; + } + +-ossimPolyArea2d::~ossimPolyArea2d() ++ ++bool ossimPolyArea2dPrivate::isEmpty() const + { +- if(m_privateData) ++ bool result = true; ++ if (m_geometry) + { +- delete m_privateData; +- m_privateData = 0; ++ result = (GEOSisEmpty(m_geometry) == 1); + } ++ ++ return result; + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimPolyArea2d& rhs) +-{ +- if(this != &rhs) ++bool ossimPolyArea2dPrivate::isValid(bool displayValidationError) const ++{ ++ bool result = false; ++ ++ if (!displayValidationError) + { +- if(rhs.m_privateData->m_geometry) ++ result = GEOSisValid(m_geometry) == 1; ++ } ++ else ++ { ++ char *reason = GEOSisValidReason(m_geometry); ++ if (reason) + { +- m_privateData->setGeometry(rhs.m_privateData->m_geometry->clone()); ++ ossimNotify(ossimNotifyLevel_INFO) ++ << "ossimPolyArea2dPrivate::isValid: " << reason << "\n"; ++ ++ GEOSFree(reason); ++ reason = 0; + } + } +- return *this; ++ ++ return result; ++} ++bool ossimPolyArea2dPrivate::isPointWithin(const ossimDpt &pt) const ++{ ++ bool result = false; ++ ++ if (!isEmpty()) ++ { ++ GEOSCoordSequence *pointSeq = GEOSCoordSeq_create(1, 2); ++ GEOSCoordSeq_setXY(pointSeq, 0, pt.x, pt.y); ++ GEOSGeometry *geom = GEOSGeom_createPoint(pointSeq); ++ result = (GEOSWithin(geom, m_geometry) == 1); ++ ++ GEOSGeom_destroy(geom); ++ } ++ ++ return result; ++} ++ ++ ++ossimPolyArea2d::ossimPolyArea2d() ++ : m_privateData(new ossimPolyArea2dPrivate()) ++{ + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimPolygon& polygon) ++ossimPolyArea2d::ossimPolyArea2d(const std::vector &polygon) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { + m_privateData->setGeometry(polygon); ++} + +- return *this; ++ossimPolyArea2d::ossimPolyArea2d(const std::vector &polygon) ++ : m_privateData(new ossimPolyArea2dPrivate()) ++{ ++ m_privateData->setGeometry(polygon); + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimIrect& rect) ++ossimPolyArea2d::ossimPolyArea2d(const ossimPolygon &shell, const std::vector &holes) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { +- return (*this = ossimPolygon(rect)); ++ m_privateData->setGeometry(shell, holes); + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const ossimDrect& rect) ++ossimPolyArea2d::ossimPolyArea2d(const ossimDpt &p1, ++ const ossimDpt &p2, ++ const ossimDpt &p3, ++ const ossimDpt &p4) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { +- return (*this = ossimPolygon(rect)); ++ m_privateData->setGeometry(ossimPolygon(p1, p2, p3, p4)); + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const vector& polygon) ++ossimPolyArea2d::ossimPolyArea2d(const ossimPolyArea2d &rhs) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { +- std::vector pts; +- int idx = 0; +- int n = (int)polygon.size(); +- for(idx = 0; idx < n;++idx) +- { +- pts.push_back(polygon[idx]); +- } +- +- return (*this = ossimPolygon(pts)); ++ m_privateData->deleteGeometry(); ++ m_privateData->m_geometry = GEOSGeom_clone(rhs.m_privateData->m_geometry); + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator =(const vector& polygon) ++ossimPolyArea2d::ossimPolyArea2d(const ossimIrect &rect) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { +- return (*this = ossimPolygon(polygon)); ++ m_privateData->setGeometry(ossimPolygon(rect)); + } + +-bool ossimPolyArea2d::intersects(const ossimPolyArea2d& rhs)const ++ossimPolyArea2d::ossimPolyArea2d(const ossimDrect &rect) ++ : m_privateData(new ossimPolyArea2dPrivate()) + { +- bool result = false; ++ m_privateData->setGeometry(ossimPolygon(rect)); ++} + +- if(m_privateData->m_geometry&&rhs.m_privateData->m_geometry) ++ossimPolyArea2d::ossimPolyArea2d(const ossimPolygon &polygon) ++ : m_privateData(new ossimPolyArea2dPrivate()) ++{ ++ m_privateData->setGeometry(polygon); ++} ++ ++ossimPolyArea2d::~ossimPolyArea2d() ++{ ++ if (m_privateData) + { +- result = m_privateData->m_geometry->intersects(rhs.m_privateData->m_geometry); ++ delete m_privateData; + } ++ m_privateData = 0; ++} + +- return result; ++void ossimPolyArea2d::clearPolygons() ++{ ++ m_privateData->setGeometry(GEOSGeom_createEmptyPolygon()); + } + +-ossimPolyArea2d ossimPolyArea2d::operator &(const ossimPolyArea2d& rhs)const ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const ossimPolyArea2d &rhs) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) ++ if (&rhs != this) + { +- ossimPolyArea2d result; +- try // GEOS code throws exceptions... +- { +- result.m_privateData->setGeometry(m_privateData->m_geometry->intersection( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator& Caught exception: " << e.what() << std::endl; +- result.clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator& Caught exception!" << std::endl; +- result.clearPolygons(); +- } +- return result; ++ m_privateData->deleteGeometry(); ++ m_privateData->m_geometry = GEOSGeom_clone(rhs.m_privateData->m_geometry); + } ++ + return *this; + } + +-ossimPolyArea2d ossimPolyArea2d::operator +(const ossimPolyArea2d& rhs)const ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const ossimPolygon &rhs) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) +- { +- ossimPolyArea2d result; +- try // GEOS code throws exceptions... +- { +- result.m_privateData->setGeometry(m_privateData->m_geometry->Union( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator+ Caught exception: " << e.what() << std::endl; +- result.clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator+ Caught exception!" << std::endl; +- result.clearPolygons(); +- } +- return result; +- } ++ m_privateData->setGeometry(rhs); ++ + return *this; + } +-ossimPolyArea2d ossimPolyArea2d::operator -(const ossimPolyArea2d& rhs)const ++ ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const ossimIrect &rect) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) +- { +- ossimPolyArea2d result; +- try // GEOS code throws exceptions... +- { +- result.m_privateData->setGeometry(m_privateData->m_geometry->difference( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator- Caught exception: " << e.what() << std::endl; +- result.clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator- Caught exception!" << std::endl; +- result.clearPolygons(); +- } +- return result; +- } ++ m_privateData->setGeometry(ossimPolygon(rect)); ++ + return *this; + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator &=(const ossimPolyArea2d& rhs) ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const ossimDrect &rect) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) +- { +- try // GEOS code throws exceptions... +- { +- m_privateData->setGeometry(m_privateData->m_geometry->intersection( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator&= Caught exception: " << e.what() << std::endl; +- this->clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator&= Caught exception!" << std::endl; +- this->clearPolygons(); +- } +- } ++ m_privateData->setGeometry(ossimPolygon(rect)); ++ + return *this; + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator +=(const ossimPolyArea2d& rhs) ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const std::vector &polygon) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) +- { +- try // GEOS code throws exceptions... +- { +- m_privateData->setGeometry(m_privateData->m_geometry->Union( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator+= Caught exception: " << e.what() << std::endl; +- this->clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator+= Caught exception!" << std::endl; +- this->clearPolygons(); +- } +- } ++ m_privateData->setGeometry(ossimPolygon(polygon)); ++ + return *this; + } + +-const ossimPolyArea2d& ossimPolyArea2d::operator -=(const ossimPolyArea2d& rhs) ++const ossimPolyArea2d &ossimPolyArea2d::operator=(const std::vector &polygon) + { +- if((this!=&rhs) && m_privateData->m_geometry && rhs.m_privateData->m_geometry) +- { +- try // GEOS code throws exceptions... +- { +- m_privateData->setGeometry(m_privateData->m_geometry->difference( +- rhs.m_privateData->m_geometry)); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator-= Caught exception: " << e.what() << std::endl; +- this->clearPolygons(); +- } +- catch( ... ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::operator-= Caught exception!" << std::endl; +- this->clearPolygons(); +- } +- } ++ m_privateData->setGeometry(ossimPolygon(polygon)); ++ + return *this; + } + +-void ossimPolyArea2d::add(const ossimPolyArea2d& rhs) ++const ossimPolyArea2d &ossimPolyArea2d::operator&=(const ossimPolyArea2d &rhs) + { +- if(isEmpty()) +- { +- *this=rhs; +- } +- else +- { +- geos::geom::Geometry* geom = m_privateData->m_geometry->Union(rhs.m_privateData->m_geometry); +- if(geom) m_privateData->setGeometry(geom); +- } ++ GEOSGeometry *geom = GEOSIntersection(m_privateData->m_geometry, rhs.m_privateData->m_geometry); ++ m_privateData->setGeometry(geom); ++ ++ return *this; + } + +-void ossimPolyArea2d::clearPolygons() ++ossimPolyArea2d ossimPolyArea2d::operator&(const ossimPolyArea2d &rhs) const + { +- m_privateData->deleteGeometry(); +-#if 0 +- clearEngine(); +-#endif ++ ossimPolyArea2d result(*this); ++ ++ result &= rhs; ++ ++ return result; + } + +-bool ossimPolyArea2d::getVisiblePolygons(vector& polyList)const ++ossimPolyArea2d ossimPolyArea2d::operator+(const ossimPolyArea2d &rhs) const + { +- bool foundPolys = false; +- if(m_privateData->m_geometry) +- { +- ossim_uint32 sizeBefore = (ossim_uint32)polyList.size(); +- recurseVisibleGeometries(polyList, m_privateData->m_geometry); +- foundPolys = (sizeBefore != polyList.size()); +- } ++ ossimPolyArea2d result(*this); + +- return foundPolys; ++ result += rhs; ++ ++ return result; + } + +-bool ossimPolyArea2d::getPolygonHoles(vector& polyList)const ++const ossimPolyArea2d &ossimPolyArea2d::operator+=(const ossimPolyArea2d &rhs) + { +- bool foundPolys = false; +- if(m_privateData->m_geometry) +- { +- ossim_uint32 sizeBefore = (ossim_uint32)polyList.size(); +- recurseHoles(polyList, m_privateData->m_geometry); +- foundPolys = (sizeBefore != polyList.size()); +- } ++ GEOSGeometry *geom = GEOSUnion(m_privateData->m_geometry, rhs.m_privateData->m_geometry); + +- return foundPolys; ++ m_privateData->setGeometry(geom); ++ ++ return *this; + } + +-bool ossimPolyArea2d::getCompletePolygons(vector& polyList)const ++ossimPolyArea2d ossimPolyArea2d::operator-(const ossimPolyArea2d &rhs) const + { +- bool foundPolys = false; +- if(m_privateData->m_geometry){ +- ossim_uint32 sizeBefore = (ossim_uint32)polyList.size(); +- recurseCompleteGeometries(polyList, m_privateData->m_geometry); +- foundPolys = (sizeBefore != polyList.size()); +- } +- return foundPolys; ++ ossimPolyArea2d result(*this); ++ ++ result -= rhs; ++ ++ return result; + } + +-bool ossimPolyArea2d::isEmpty()const ++const ossimPolyArea2d &ossimPolyArea2d::operator-=(const ossimPolyArea2d &rhs) + { +- bool result = true; +- if (m_privateData&&m_privateData->m_geometry) +- { +- result = m_privateData->m_geometry->isEmpty(); +- } ++ GEOSGeometry *geom = GEOSDifference(m_privateData->m_geometry, rhs.m_privateData->m_geometry); + +- return result; ++ m_privateData->setGeometry(geom); ++ ++ return *this; + } + +-bool ossimPolyArea2d::isValid(bool displayValidationError)const ++ossim_float64 ossimPolyArea2d::getArea()const + { +- bool result = false; ++ double result = 0.0; + +- if(m_privateData&&m_privateData->m_geometry) ++ if(!isEmpty()) + { +- if(displayValidationError) +- { +- geos::operation::valid::IsValidOp validityCheck(m_privateData->m_geometry); +- geos::operation::valid::TopologyValidationError* +- topologyValidationError(validityCheck.getValidationError()); +- // if(topologyValidationError == nullptr) +- if(topologyValidationError == 0) +- { +- result = true; +- } +- else +- { +- ossimNotify(ossimNotifyLevel_INFO) +- << "ossimPolyArea2d::isValid: " << topologyValidationError->toString() << std::endl; +- } +- } +- else +- { +- result = m_privateData->m_geometry->isValid(); +- } ++ GEOSArea(m_privateData->m_geometry, &result); + } +- ++ + return result; + } + +-bool ossimPolyArea2d::isPointWithin(const ossimDpt& point)const ++bool ossimPolyArea2d::isEmpty() const + { +- return isPointWithin(point.x, point.y); ++ return m_privateData->isEmpty(); + } + +-bool ossimPolyArea2d::isPointWithin(double x, double y)const ++bool ossimPolyArea2d::isValid(bool displayValidationError) const + { +- bool result = false; +- +- if(!isEmpty()) +- { +- geos::geom::Coordinate c(x,y); +- geos::geom::Geometry* geom = m_privateData->geomFactory()->createPoint(c); +- +- result = m_privateData->m_geometry->intersects(geom); +- +- delete geom; +- } ++ return m_privateData->isValid(displayValidationError); ++} + +- return result; ++bool ossimPolyArea2d::isPointWithin(const ossimDpt &point) const ++{ ++ return m_privateData->isPointWithin(point); + } + +-void ossimPolyArea2d::getBoundingRect(ossimDrect& rect) ++bool ossimPolyArea2d::isPointWithin(double x, double y) const + { +- rect.makeNan(); ++ return isPointWithin(ossimDpt(x, y)); ++} + +- if(!isEmpty()) +- { +- const geos::geom::Envelope* envelope = m_privateData->m_geometry->getEnvelopeInternal(); ++void ossimPolyArea2d::getBoundingRect(ossimDrect &rect) const ++{ ++ m_privateData->getBoundingRect(rect); ++} + +- rect = ossimDrect(envelope->getMinX(), envelope->getMinY(), envelope->getMaxX(), envelope->getMaxY()); +- } ++bool ossimPolyArea2d::intersects(const ossimPolyArea2d &rhs) const ++{ ++ return (GEOSIntersects(m_privateData->m_geometry, ++ rhs.m_privateData->m_geometry) == 1); + } + +-std::string ossimPolyArea2d::toString()const ++void ossimPolyArea2d::makeValid() + { +- std::string result = ""; ++ ossimPolyArea2dPrivate::GEOSGeometryPtr geom = GEOSMakeValid(m_privateData->m_geometry); ++ if(geom) m_privateData->setGeometry(geom); ++} + +- if(m_privateData->m_geometry) +- { +- result = m_privateData->m_geometry->toString(); +- } + +- return result; ++void ossimPolyArea2d::add(const ossimPolyArea2d &rhs) ++{ ++ *this += rhs; + } + +-ossimPolyArea2d ossimPolyArea2d::getBufferedShape(double distance) const{ +- ossimPolyArea2d result; +- try{ +- geos::operation::buffer::BufferOp buffer_operation(m_privateData->m_geometry); +- result.m_privateData->setGeometry( buffer_operation.getResultGeometry(distance)); +- }catch( const std::exception& e ){ +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::getBufferedShape Caught exception: " << e.what() << std::endl; +- result.clearPolygons(); +- }catch( ... ){ +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::getBufferedShape Caught exception!" << std::endl; +- result.clearPolygons(); +- } +- return result; +-} +-ossimPolyArea2d& ossimPolyArea2d::setToBufferedShape(double distance) +-{ +- try{ +- geos::operation::buffer::BufferOp buffer_operation(m_privateData->m_geometry); +- m_privateData->setGeometry( buffer_operation.getResultGeometry(distance)); +- }catch( const std::exception& e ){ +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::getBufferedShape Caught exception: " << e.what() << std::endl; +- }catch( ... ){ +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::getBufferedShape Caught exception!" << std::endl; +- } +- return *this; ++bool ossimPolyArea2d::getVisiblePolygons(std::vector &polyList) const ++{ ++ m_privateData->getVisiblePolygons(polyList); ++ ++ return (polyList.size() > 0); + } + +-ossimPolyArea2d& ossimPolyArea2d::toMultiPolygon() ++bool ossimPolyArea2d::getPolygonHoles(std::vector &polyList) const + { ++ m_privateData->getPolygonHoles(polyList); + ++ return (polyList.size() > 0); ++} + +- try{ +- if(m_privateData->m_geometry) +- { +- switch(m_privateData->m_geometry->getGeometryTypeId()) +- { +- case geos::geom::GEOS_POLYGON: +- { +- std::vector values; +- values.push_back(m_privateData->m_geometry->clone()); +- +- m_privateData->setGeometry(m_privateData->m_geometry->getFactory()->createMultiPolygon(values)); +- break; +- } +- case geos::geom::GEOS_MULTIPOLYGON: +- { +- // intentionally left blank +- break; +- } +- default: +- { +- // might need an error at a later date +- ossimNotify(ossimNotifyLevel_WARN) +- << "ossimPolyArea2d::toMultiPolygon Geometry type can not be converted to a multi polygon: " <m_geometry->getGeometryType()<< std::endl; ++ossimPolyArea2d &ossimPolyArea2d::toMultiPolygon() ++{ ++ int geomType = GEOSGeomTypeId(m_privateData->m_geometry); + +- break; +- } +- } +- } +- } +- catch(const std::exception& e) +- { +- ossimNotify(ossimNotifyLevel_WARN) +- << "ossimPolyArea2d::toMultiPolygon Caught exception: " << e.what() << std::endl; +- } +- catch(...) ++ if (geomType != GEOS_MULTIPOLYGON) + { +- ossimNotify(ossimNotifyLevel_WARN) +- << "ossimPolyArea2d::toMultiPolygon Caught exception!" << std::endl; ++ std::vector geoms(1); ++ geoms[0] = GEOSGeom_clone(m_privateData->m_geometry); ++ GEOSGeometry *result = GEOSGeom_createCollection(GEOS_MULTIPOLYGON, ++ &geoms.front(), 1); ++ m_privateData->setGeometry(result); + } + + return *this; + } + +-bool ossimPolyArea2d::saveState(ossimKeywordlist& kwl, +- const char* prefix)const ++std::string ossimPolyArea2d::toString() const ++{ ++ return m_privateData->toString(); ++} ++ ++bool ossimPolyArea2d::setFromWkt(const std::string &s) ++{ ++ return m_privateData->setFromWkt(s); ++} ++ ++bool ossimPolyArea2d::saveState(ossimKeywordlist &kwl, ++ const char *prefix) const + { + kwl.add(prefix, + ossimKeywordNames::TYPE_KW, + "ossimPolyArea2d", + true); + +- if(!isEmpty()) ++ if (!isEmpty()) + { +- geos::io::WKTWriter writer; + + kwl.add(prefix, + "wkt", +- writer.write(m_privateData->m_geometry).c_str(), ++ toString().c_str(), + true); + } +- // else +- // { +- // +- // } +- + return true; + } + +-bool ossimPolyArea2d::loadState(const ossimKeywordlist& kwl, +- const char* prefix) ++bool ossimPolyArea2d::loadState(const ossimKeywordlist &kwl, ++ const char *prefix) + { +- if(m_privateData) ++ bool result = true; ++ ++ if (m_privateData) + { + ossimString wkt = kwl.find(prefix, "wkt"); + +- if(!wkt.empty()) ++ if (!wkt.empty()) + { +- geos::io::WKTReader reader(m_privateData->geomFactory()); +- try +- { +- m_privateData->setGeometry(reader.read(wkt.c_str())); +- } +- catch( const std::exception& e ) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::loadState Caught exception: " << e.what() << std::endl; +- this->clearPolygons(); +- } +- catch(...) +- { +- ossimNotify(ossimNotifyLevel_DEBUG) +- << "ossimPolyArea2d::loadState Caught exception!" << std::endl; +- this->clearPolygons(); +- } ++ result = setFromWkt(wkt.string()); + } + } +- return true; ++ ++ return result; ++} ++ ++std::ostream &operator<<(std::ostream &out, const ossimPolyArea2d &rhs) ++{ ++ if (!rhs.isEmpty()) ++ { ++ out << rhs.toString(); ++ } ++ ++ return out; + } +diff --git a/src/imaging/ossimImageGeometry.cpp b/src/imaging/ossimImageGeometry.cpp +index f7b054a8..148aeea4 100644 +--- a/src/imaging/ossimImageGeometry.cpp ++++ b/src/imaging/ossimImageGeometry.cpp +@@ -1240,7 +1240,7 @@ void ossimImageGeometry::calculatePolyBounds(ossimPolyArea2d& result, ossim_uint + } + result.add(ossimPolygon(gPoints)); + } +- if(!result.isValid()) result.setToBufferedShape(); ++ if(!result.isValid()) result.makeValid(); + } + + +diff --git a/src/init/ossimInit.cpp b/src/init/ossimInit.cpp +index 19b28113..9aeec9de 100644 +--- a/src/init/ossimInit.cpp ++++ b/src/init/ossimInit.cpp +@@ -65,12 +65,59 @@ + + #include + #include ++#include + + using namespace std; + + static ossimTrace traceExec = ossimTrace("ossimInit:exec"); + static ossimTrace traceDebug = ossimTrace("ossimInit:debug"); + ++extern "C" ++{ ++ void geosNoticeFunction(const char *fmt, ...); ++ void geosErrorFunction(const char *fmt, ...); ++} ++ ++ossimString geosErrorV(const char *fmt, va_list args) ++{ ++ char temp[2024]; ++ if (fmt) ++ { ++ vsprintf(temp, fmt, args); ++ } ++ else ++ { ++ sprintf(temp, "%s", ""); ++ } ++ ++ return temp; ++} ++ ++void geosNoticeFunction(const char *fmt, ...) ++{ ++ // NOTE: This code has an infinite loop in it!!! (drb) ++ //std::lock_guard lock(theMutex); ++ // theMutex.lock(); ++ va_list args; ++ ++ va_start(args, fmt); ++ ossimString result = geosErrorV(fmt, args); ++ va_end(args); ++ // theMutex.unlock(); ++ ossimNotify(ossimNotifyLevel_WARN) << result << "\n"; ++} ++ ++void geosErrorFunction(const char *fmt, ...) ++{ ++ va_list args; ++ ++ va_start(args, fmt); ++ ossimString result = geosErrorV(fmt, args); ++ va_end(args); ++ // theMutex.unlock(); ++ ossimNotify(ossimNotifyLevel_WARN) << result << "\n"; ++} ++ + ossimInit* ossimInit::theInstance = 0; + + ossimInit::~ossimInit() +@@ -122,6 +169,8 @@ void ossimInit::initialize(int& argc, char** argv) + { + static std::mutex m; + std::lock_guard lock(m); ++ initGEOS(geosNoticeFunction, geosErrorFunction); ++ + if( !theInitializedFlag ) + { + ossimArgumentParser argumentParser(&argc, argv); +@@ -262,7 +311,7 @@ void ossimInit::initialize() + + void ossimInit::finalize() + { +- ++ finishGEOS(); + } + /*!**************************************************************************** + * Prints to stdout the list of command line options that this object parses. diff --git a/gis/ossim/ossim.SlackBuild b/gis/ossim/ossim.SlackBuild index 034bb012b48d..61475da33a33 100644 --- a/gis/ossim/ossim.SlackBuild +++ b/gis/ossim/ossim.SlackBuild @@ -25,8 +25,8 @@ # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. PRGNAM=ossim -RELNAM=Miami -VERSION=${VERSION:-2.9.1} +RELNAM=Neptune +VERSION=${VERSION:-2.10.0} BUILD=${BUILD:-1} TAG=${TAG:-_SBo} @@ -73,6 +73,9 @@ find -L . \ -o -perm 440 -o -perm 400 \) -exec chmod 644 {} \; sed -i "s/lib\b/lib${LIBDIRSUFFIX}/" CMakeLists.txt +patch -p1 < $CWD/c45639.patch +patch -p1 < $CWD/c0d975.patch +patch -p1 < $CWD/0498f7.patch mkdir -p build cd build diff --git a/gis/ossim/ossim.info b/gis/ossim/ossim.info index dadbf7f7c09d..76489c657963 100644 --- a/gis/ossim/ossim.info +++ b/gis/ossim/ossim.info @@ -1,8 +1,8 @@ PRGNAM="ossim" -VERSION="2.9.1" +VERSION="2.10.0" HOMEPAGE="https://trac.osgeo.org/ossim/" -DOWNLOAD="https://github.com/ossimlabs/ossim/archive/Miami-2.9.1/ossim-Miami-2.9.1.tar.gz" -MD5SUM="9e1ed041b470198168100a57f66b7e75" +DOWNLOAD="https://github.com/ossimlabs/ossim/archive/Neptune-2.10.0/ossim-Neptune-2.10.0.tar.gz" +MD5SUM="a78f148936ae35a32da5fdb15c1362f5" DOWNLOAD_x86_64="" MD5SUM_x86_64="" REQUIRES="geos jsoncpp libgeotiff" -- cgit v1.2.3