Index: src/core/qgsgeometry.cpp =================================================================== --- src/core/qgsgeometry.cpp (Revision 9021) +++ src/core/qgsgeometry.cpp (Arbeitskopie) @@ -15,6 +15,8 @@ /* $Id$ */ #include +#include +#include #include "qgis.h" #include "qgsgeometry.h" @@ -23,79 +25,103 @@ #include "qgspoint.h" #include "qgsrect.h" -#if GEOS_VERSION_MAJOR < 3 -#include -#include -#include -#include -#define GEOS_IO geos -#define GEOS_LINEMERGE geos -#define GEOS_POLYGONIZE geos -#define GEOS_UTIL geos -#define GEOS_SIZE_T int -#define COORD_SEQ_FACTORY DefaultCoordinateSequenceFactory -#define GEOS_EXCEPTION GEOS_UTIL::GEOSException* +#include +#define DEFAULT_QUADRANT_SEGMENTS 8 + #define CATCH_GEOS(r) \ - catch (GEOS_EXCEPTION e) \ + catch (GEOSException &e) \ { \ - QString error = e->toString().c_str(); \ - delete e; \ - QgsDebugMsg("GEOS: " + error); \ + QgsDebugMsg("GEOS: " + QString( e.what() ) ); \ return r; \ } -#else -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define GEOS_IO geos::io -#define GEOS_LINEMERGE geos::operation::linemerge -#define GEOS_POLYGONIZE geos::operation::polygonize -#define GEOS_UTIL geos::util -#define GEOS_SIZE_T size_t -#define COORD_SEQ_FACTORY CoordinateArraySequenceFactory -#define GEOS_EXCEPTION GEOS_UTIL::GEOSException& -#define CATCH_GEOS(r) \ - catch (GEOS_EXCEPTION e) \ +#define RELAY_GEOS() \ + catch (GEOSException &e) \ { \ - QgsDebugMsg("GEOS: " + QString( e.what() ) ); \ - return r; \ + Q_UNUSED(e); \ + throw; \ } + +class GEOSException +{ +public: + GEOSException(const char *theMsg) + { + msg = theMsg; + } + + ~GEOSException() + { + delete [] msg; + } + + + const char *what() + { + return msg; + } + +private: + const char *msg; +}; + +extern "C" void throwGEOSException(const char *fmt, ...) +#ifdef _MSC_VER +throw() #endif +{ + va_list ap; + va_start(ap, fmt); + size_t buflen = vsnprintf(NULL, 0, fmt, ap); + char *msg=new char[buflen+1]; + vsnprintf(msg, buflen+1, fmt, ap); + va_end(ap); -// Set up static GEOS geometry factory -static GEOS_GEOM::GeometryFactory* geosGeometryFactory = new GEOS_GEOM::GeometryFactory(); + throw GEOSException(msg); +} +extern "C" void printGEOSNotice(const char *fmt, ...) +{ +#if defined(QGISDEBUG) + va_list ap; + va_start(ap, fmt); + size_t buflen = vsnprintf(NULL, 0, fmt, ap); + char *msg=new char[buflen+1]; + vsnprintf(msg, buflen+1, fmt, ap); + va_end(ap); + QgsDebugMsg( QString("GEOS notice: ").arg(msg) ); + delete [] msg; +#endif +} + +int QgsGeometry::refcount=0; + QgsGeometry::QgsGeometry() : mGeometry(0), - mGeometrySize(0), - mGeos(0), - - mDirtyWkb(FALSE), -mDirtyGeos(FALSE) + mGeometrySize(0), + mGeos(0), + mDirtyWkb(FALSE), + mDirtyGeos(FALSE) { + if(refcount++==0) { + initGEOS(printGEOSNotice, throwGEOSException); + } // NOOP } QgsGeometry::QgsGeometry( QgsGeometry const & rhs ) : mGeometry(0), - mGeometrySize( rhs.mGeometrySize ), - mDirtyWkb( rhs.mDirtyWkb ), - mDirtyGeos( rhs.mDirtyGeos ) + mGeometrySize( rhs.mGeometrySize ), + mDirtyWkb( rhs.mDirtyWkb ), + mDirtyGeos( rhs.mDirtyGeos ) { + if(refcount++==0) { + initGEOS(printGEOSNotice, throwGEOSException); + } + if ( mGeometrySize && rhs.mGeometry ) { mGeometry = new unsigned char[mGeometrySize]; @@ -105,36 +131,7 @@ // deep-copy the GEOS Geometry if appropriate if (rhs.mGeos) { - if(rhs.mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTIPOLYGON)//MH:problems with cloning for multipolygons in geos 2 - { - GEOS_GEOM::MultiPolygon* multiPoly = dynamic_cast(rhs.mGeos); - if(multiPoly) - { - std::vector polygonVector; - for(GEOS_SIZE_T i = 0; i < multiPoly->getNumGeometries(); ++i) - { - polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i))); - } - mGeos = geosGeometryFactory->createMultiPolygon(polygonVector); - } - } - else if(rhs.mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTILINESTRING) //MH: and also for cloning multilines - { - GEOS_GEOM::MultiLineString* multiLine = dynamic_cast(rhs.mGeos); - if(multiLine) - { - std::vector lineVector; - for(GEOS_SIZE_T i = 0; i < multiLine->getNumGeometries(); ++i) - { - lineVector.push_back((GEOS_GEOM::Geometry*)(multiLine->getGeometryN(i))); - } - mGeos = geosGeometryFactory->createMultiLineString(lineVector); - } - } - else - { - mGeos = rhs.mGeos->clone(); - } + mGeos = GEOSGeom_clone(rhs.mGeos); } else { @@ -142,228 +139,259 @@ } } -QgsGeometry* QgsGeometry::fromWkt(QString wkt) +//! Destructor +QgsGeometry::~QgsGeometry() { - GEOS_IO::WKTReader reader(geosGeometryFactory); - GEOS_GEOM::Geometry* geom = reader.read(wkt.toLocal8Bit().data()); - QgsGeometry* g = new QgsGeometry; - g->setGeos(geom); - return g; -} + if (mGeometry) + { + delete [] mGeometry; + } -QgsGeometry* QgsGeometry::fromPoint(const QgsPoint& point) -{ - GEOS_GEOM::Coordinate coord = GEOS_GEOM::Coordinate(point.x(), point.y()); - GEOS_GEOM::Geometry* geom = 0; - try + if (mGeos) { - geom = geosGeometryFactory->createPoint(coord); + GEOSGeom_destroy(mGeos); } - CATCH_GEOS(0) - QgsGeometry* g = new QgsGeometry; - g->setGeos(geom); - return g; + if(--refcount==0) + finishGEOS(); } -QgsGeometry* QgsGeometry::fromMultiPoint(const QgsMultiPoint& multipoint) +static unsigned int getNumGeosPoints(const GEOSGeometry *geom) { - std::vector* pointVector = new std::vector(multipoint.size()); - GEOS_GEOM::Coordinate currentCoord; - std::auto_ptr< std::vector > owner(pointVector); + unsigned int n; + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(geom); + GEOSCoordSeq_getSize(cs, &n); + return n; +} - for(int i = 0; i < multipoint.size(); ++i) - { - currentCoord.x = multipoint.at(i).x(); - currentCoord.y = multipoint.at(i).y(); - try - { - (*pointVector)[i] = geosGeometryFactory->createPoint(currentCoord); +static GEOSGeometry *createGeosPoint(const QgsPoint &point) +{ + GEOSCoordSequence *coord = GEOSCoordSeq_create(1, 2); + GEOSCoordSeq_setX(coord, 0, point.x()); + GEOSCoordSeq_setY(coord, 0, point.y()); + return GEOSGeom_createPoint(coord); +} + +static GEOSCoordSequence *createGeosCoordSequence(const QgsPolyline& points) +{ + GEOSCoordSequence *coord; + + try { + coord = GEOSCoordSeq_create(points.count(), 2); + int i; + for(i=0; icreateMultiPoint(pointVector); - owner.release(); - } - CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geom); - return g; } -QgsGeometry* QgsGeometry::fromPolyline(const QgsPolyline& polyline) +static GEOSGeometry *createGeosCollection(int typeId, QVector geoms) { - const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance(); - GEOS_GEOM::CoordinateSequence* seq = seqFactory->create(polyline.count(), 2); - std::auto_ptr< GEOS_GEOM::CoordinateSequence > owner(seq); + GEOSGeometry **geomarr = new GEOSGeometry*[ geoms.size() ]; + if(!geomarr) + return 0; - QgsPolyline::const_iterator it; - int i = 0; - for (it = polyline.begin(); it != polyline.end(); ++it) - { - seq->setAt(GEOS_GEOM::Coordinate(it->x(), it->y()), i++); + for(int i=0; icreateLineString(seq); - owner.release(); - } - CATCH_GEOS(0) + delete [] geomarr; - QgsGeometry* g = new QgsGeometry; - g->setGeos(geom); - return g; + return geom; } -QgsGeometry* QgsGeometry::fromMultiPolyline(const QgsMultiPolyline& multiline) +static GEOSGeometry *createGeosLineString(const QgsPolyline& polyline) { - const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance(); - std::vector* lineVector = new std::vector(multiline.count()); - GEOS_GEOM::LineString* currentLineString = 0; - std::auto_ptr< std::vector > owner(lineVector); + GEOSCoordSequence *coord = 0; - for(int i = 0; i < multiline.count(); ++i) + try { + coord = createGeosCoordSequence(polyline); + return GEOSGeom_createLineString(coord); + } + catch(GEOSException &e) { - QgsPolyline currentLine = multiline.at(i); - GEOS_GEOM::CoordinateSequence* seq = seqFactory->create(currentLine.count(), 2); - std::auto_ptr< GEOS_GEOM::CoordinateSequence > owner(seq); + Q_UNUSED(e); + if(coord) + GEOSCoordSeq_destroy(coord); + return 0; + } +} - for(int j = 0; j < currentLine.count(); ++j) - { - seq->setAt(GEOS_GEOM::Coordinate(currentLine.at(j).x(), currentLine.at(j).y()), j); +static GEOSGeometry *createGeosLinearRing(const QgsPolyline& polyline) +{ + GEOSCoordSequence *coord = 0; + + try { + if( polyline[0]!=polyline[polyline.size()-1] ) { + // Ring not closed + QgsPolyline closed(polyline); + closed << closed[0]; + coord = createGeosCoordSequence(closed); + } else { + coord = createGeosCoordSequence(polyline); } - try - { - currentLineString = geosGeometryFactory->createLineString(seq); - owner.release(); - } - CATCH_GEOS(0) - (*lineVector)[i] = currentLineString; + return GEOSGeom_createLinearRing(coord); } - - GEOS_GEOM::Geometry* geom = 0; - try + catch(GEOSException &e) { - geom = geosGeometryFactory->createMultiLineString(lineVector); - owner.release(); + Q_UNUSED(e); + if(coord) + GEOSCoordSeq_destroy(coord); + return 0; } - CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geom); - return g; } -static GEOS_GEOM::LinearRing* _createGeosLinearRing(const QgsPolyline& ring) +static GEOSGeometry *createGeosPolygon(const QVector &rings) { - // LinearRing in GEOS must have the first point the same as the last one - bool needRepeatLastPnt = (ring[0] != ring[ring.count()-1]); + GEOSGeometry *shell = rings[0]; + GEOSGeometry **holes = NULL; - const GEOS_GEOM::CoordinateSequenceFactory* seqFactory = GEOS_GEOM::COORD_SEQ_FACTORY::instance(); + if(rings.size()>1) { + holes = new GEOSGeometry*[ rings.size()-1 ]; + if(!holes) + return 0; - GEOS_GEOM::CoordinateSequence* seq = seqFactory->create(ring.count() + (needRepeatLastPnt ? 1 : 0), 2); - QgsPolyline::const_iterator it; - int i = 0; - for (it = ring.begin(); it != ring.end(); ++it) - { - seq->setAt(GEOS_GEOM::Coordinate(it->x(), it->y()), i++); + for(int i=0; isetAt(GEOS_GEOM::Coordinate(ring[0].x(), ring[0].y()), ring.count()); + GEOSGeometry *geom = GEOSGeom_createPolygon(shell, holes, rings.size()-1); - // ring takes ownership of the sequence - GEOS_GEOM::LinearRing* linRing = 0; - try - { - linRing = geosGeometryFactory->createLinearRing(seq); - } - CATCH_GEOS(0) + if(holes) + delete [] holes; + + return geom; +} - return linRing; +static GEOSGeometry *createGeosPolygon(GEOSGeometry *shell) +{ + return createGeosPolygon( QVector() << shell ); } -QgsGeometry* QgsGeometry::fromPolygon(const QgsPolygon& polygon) +static GEOSGeometry *createGeosPolygon(const QgsPolygon& polygon) { if (polygon.count() == 0) - return NULL; + return 0; - const QgsPolyline& ring0 = polygon[0]; + QVector geoms; - // outer ring - GEOS_GEOM::LinearRing* outerRing = _createGeosLinearRing(ring0); - - // holes - std::vector* holes = new std::vector (polygon.count()-1); - for (int i = 1; i < polygon.count(); i++) - { - (*holes)[i-1] = _createGeosLinearRing(polygon[i]); + try { + for(int i=0; icreatePolygon(outerRing, holes); - } - CATCH_GEOS(0) +static QgsGeometry *fromGeosGeom(GEOSGeometry *geom) +{ + if(!geom) + return 0; QgsGeometry* g = new QgsGeometry; g->setGeos(geom); return g; } -QgsGeometry* QgsGeometry::fromMultiPolygon(const QgsMultiPolygon& multipoly) +QgsGeometry* QgsGeometry::fromWkt(QString wkt) { - if(multipoly.count() == 0) - { - return 0; - } + GEOSWKTReader *reader = GEOSWKTReader_create();; + QgsGeometry *g = fromGeosGeom( GEOSWKTReader_read(reader, wkt.toLocal8Bit().data()) ); + GEOSWKTReader_destroy(reader); + return g; +} - std::vector* polygons = new std::vector(multipoly.count()); - std::auto_ptr< std::vector > owner(polygons); - GEOS_GEOM::Polygon* currentPolygon = 0; - GEOS_GEOM::LinearRing* currentOuterRing = 0; - std::vector* currentHoles = 0; +QgsGeometry* QgsGeometry::fromPoint(const QgsPoint& point) +{ + return fromGeosGeom( createGeosPoint(point) ); +} - for(int i = 0; i < multipoly.count(); ++i) - { - currentOuterRing = _createGeosLinearRing(multipoly[i].at(0)); - currentHoles = new std::vector(multipoly[i].count() - 1); - for(int j = 1; j < multipoly[i].count(); ++j) - { - (*currentHoles)[j-1] = _createGeosLinearRing(multipoly[i].at(j)); +QgsGeometry* QgsGeometry::fromPolyline(const QgsPolyline& polyline) +{ + return fromGeosGeom( createGeosLineString(polyline) ); +} + +QgsGeometry* QgsGeometry::fromPolygon(const QgsPolygon& polygon) +{ + return fromGeosGeom( createGeosPolygon( polygon ) ); +} + +QgsGeometry* QgsGeometry::fromMultiPoint(const QgsMultiPoint& multipoint) +{ + QVector geoms; + + try { + for(int i = 0; i < multipoint.size(); ++i) { + geoms << createGeosPoint( multipoint[i] ); } - try - { - currentPolygon = geosGeometryFactory->createPolygon(currentOuterRing, currentHoles); - } - CATCH_GEOS(0) + + return fromGeosGeom( createGeosCollection(GEOS_MULTIPOINT, geoms) ); + } catch(GEOSException &e) { + Q_UNUSED(e); + for(int i=0; i < geoms.size(); ++i) + GEOSGeom_destroy(geoms[i]); - (*polygons)[i] = currentPolygon; + return 0; } +} - GEOS_GEOM::Geometry* geom = 0; - try - { - geom = geosGeometryFactory->createMultiPolygon(polygons); - owner.release(); +QgsGeometry* QgsGeometry::fromMultiPolyline(const QgsMultiPolyline& multiline) +{ + QVector geoms; + + try { + for(int i=0; isetGeos(geom); - return g; +QgsGeometry* QgsGeometry::fromMultiPolygon(const QgsMultiPolygon& multipoly) +{ + if(multipoly.count() == 0) + return 0; + + QVector geoms; + + try { + for(int i=0; igetGeometryTypeId() == GEOS_GEOM::GEOS_MULTIPOLYGON)//MH:problems with cloning for multipolygons in geos 2 - { - GEOS_GEOM::MultiPolygon* multiPoly = dynamic_cast(rhs.mGeos); - if(multiPoly) - { - std::vector polygonVector; - for(GEOS_SIZE_T i = 0; i < multiPoly->getNumGeometries(); ++i) - { - polygonVector.push_back((GEOS_GEOM::Geometry*)(multiPoly->getGeometryN(i))); - } - mGeos = geosGeometryFactory->createMultiPolygon(polygonVector); - } - } - else if(rhs.mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTILINESTRING) //MH: and also for cloning multilines - { - GEOS_GEOM::MultiLineString* multiLine = dynamic_cast(rhs.mGeos); - if(multiLine) - { - std::vector lineVector; - for(GEOS_SIZE_T i = 0; i < multiLine->getNumGeometries(); ++i) - { - lineVector.push_back((GEOS_GEOM::Geometry*)(multiLine->getGeometryN(i))); - } - mGeos = geosGeometryFactory->createMultiLineString(lineVector); - } - } - else - { - mGeos = rhs.mGeos->clone(); - } - } - else - { - mGeos = 0; - } + mGeos = rhs.mGeos ? GEOSGeom_clone(rhs.mGeos) : 0; mDirtyGeos = rhs.mDirtyGeos; mDirtyWkb = rhs.mDirtyWkb; @@ -449,21 +441,6 @@ } // QgsGeometry::operator=( QgsGeometry const & rhs ) -//! Destructor -QgsGeometry::~QgsGeometry() -{ - if (mGeometry) - { - delete [] mGeometry; - } - - if (mGeos) - { - delete mGeos; - } -} - - void QgsGeometry::setWkbAndOwnership(unsigned char * wkb, size_t length) { // delete any existing WKB geometry before assigning new one @@ -474,7 +451,7 @@ } if (mGeos) { - delete mGeos; + GEOSGeom_destroy(mGeos); mGeos = 0; } @@ -566,13 +543,13 @@ } -void QgsGeometry::setGeos(GEOS_GEOM::Geometry* geos) +void QgsGeometry::setGeos(GEOSGeometry* geos) { // TODO - make this more heap-friendly if (mGeos) { - delete mGeos; + GEOSGeom_destroy(mGeos); mGeos = 0; } if (mGeometry) @@ -1093,8 +1070,8 @@ bool QgsGeometry::insertVertexBefore(double x, double y, int beforeVertex, - const GEOS_GEOM::CoordinateSequence* old_sequence, - GEOS_GEOM::CoordinateSequence** new_sequence) + const GEOSCoordSequence* old_sequence, + GEOSCoordSequence** new_sequence) { // Bounds checking @@ -1104,28 +1081,39 @@ return FALSE; } - int numPoints = old_sequence->getSize(); + unsigned int numPoints; + GEOSCoordSeq_getSize(old_sequence, &numPoints); - // Copy to the new sequence, including the new vertex - (*new_sequence) = new GEOS_GEOM::DefaultCoordinateSequence(); + *new_sequence = GEOSCoordSeq_create(numPoints+1, 2); + if(!*new_sequence) + return false; - bool inserted = FALSE; - for (int i = 0; i < numPoints; i++) + bool inserted = false; + for (unsigned int i=0, j=0; iadd( GEOS_GEOM::Coordinate(x, y) ); - inserted = TRUE; + GEOSCoordSeq_setX(*new_sequence, j, x); + GEOSCoordSeq_setY(*new_sequence, j, y); + j++; + inserted = true; } - (*new_sequence)->add( old_sequence->getAt(i) ); + + double aX, aY; + GEOSCoordSeq_getX(old_sequence, i, &aX); + GEOSCoordSeq_getY(old_sequence, i, &aY); + + GEOSCoordSeq_setX(*new_sequence, j, aX); + GEOSCoordSeq_setY(*new_sequence, j, aY); } if (!inserted) { // The beforeVertex is greater than the actual number of vertices // in the geometry - append it. - (*new_sequence)->add( GEOS_GEOM::Coordinate(x, y) ); + GEOSCoordSeq_setX(*new_sequence, numPoints, x); + GEOSCoordSeq_setY(*new_sequence, numPoints, y); } // TODO: Check that the sequence is still simple, e.g. with GEOS_GEOM::Geometry->isSimple() @@ -2018,14 +2006,14 @@ if (mGeos) //try to find the vertex from the Geos geometry (it present) { - GEOS_GEOM::CoordinateSequence* cs = mGeos->getCoordinates(); - if(cs) - { - const GEOS_GEOM::Coordinate& coord = cs->getAt(atVertex); - x = coord.x; - y = coord.y; - delete cs; + try { + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(mGeos); + GEOSCoordSeq_getX(cs, atVertex, &x); + GEOSCoordSeq_getY(cs, atVertex, &y); return QgsPoint(x,y); + } catch(GEOSException &e) { + Q_UNUSED(e); + return QgsPoint(0,0); } } else if(mGeometry) @@ -2244,33 +2232,39 @@ double QgsGeometry::closestVertexWithContext(const QgsPoint& point, int& atVertex) { - // Initialise some stuff double sqrDist = std::numeric_limits::max(); - int closestVertexIndex = 0; - // set up the GEOS geometry - exportWkbToGeos(); + try { + // Initialise some stuff + int closestVertexIndex = 0; - if (!mGeos) - { - QgsDebugMsg("GEOS geometry not available!"); - return -1; - } + // set up the GEOS geometry + exportWkbToGeos(); - GEOS_GEOM::CoordinateSequence* sequence = mGeos->getCoordinates(); - if(sequence) - { - for(GEOS_SIZE_T i = 0; i < sequence->getSize(); ++i) + const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq(mGeos); + + unsigned int n; + GEOSCoordSeq_getSize(sequence, &n); + + for(unsigned int i=0; igetAt(i).x, sequence->getAt(i).y); + double x, y; + GEOSCoordSeq_getX(sequence, i, &x); + GEOSCoordSeq_getY(sequence, i, &y); + + double testDist = point.sqrDist(x,y); if(testDist < sqrDist) { closestVertexIndex = i; sqrDist = testDist; } } + + atVertex = closestVertexIndex; + } catch(GEOSException &e) { + Q_UNUSED(e); + return -1; } - atVertex = closestVertexIndex; return sqrDist; } @@ -2505,199 +2499,156 @@ { //bail out if this geometry is not polygon/multipolygon if(vectorType() != QGis::Polygon) - { return 1; - } //test for invalid geometries if(ring.size() < 4) - { return 3; - } //ring must be closed if(ring.first() != ring.last()) - { return 2; - } //create geos geometry from wkb if not already there if(!mGeos || mDirtyGeos) - { exportWkbToGeos(); - } + int type = GEOSGeomTypeId(mGeos); + //Fill GEOS Polygons of the feature into list - std::list polygonList; //list of polygon pointers (only one for polygon geometries) - GEOS_GEOM::Polygon* thisPolygon = 0; - GEOS_GEOM::MultiPolygon* thisMultiPolygon = 0; + QVector polygonList; if(this->wkbType() == QGis::WKBPolygon) { - thisPolygon = dynamic_cast(mGeos); - if(!thisPolygon) - { + if(type!=GEOS_POLYGON) return 1; - } - polygonList.push_back(thisPolygon); + + polygonList << mGeos; } else if(this->wkbType() == QGis::WKBMultiPolygon) { - thisMultiPolygon = dynamic_cast(mGeos); - if(!thisMultiPolygon) - { + if(type!=GEOS_MULTIPOLYGON) return 1; - } - int numPolys = thisMultiPolygon->getNumGeometries(); - for(int i = 0; i < numPolys; ++i) - { - polygonList.push_back((GEOS_GEOM::Polygon*)(thisMultiPolygon->getGeometryN(i))); - } - } - //create new ring - GEOS_GEOM::DefaultCoordinateSequence* newSequence=new GEOS_GEOM::DefaultCoordinateSequence(); - std::auto_ptr< GEOS_GEOM::DefaultCoordinateSequence > owner(newSequence); - for(QList::const_iterator it = ring.begin(); it != ring.end(); ++it) - { - newSequence->add(GEOS_GEOM::Coordinate(it->x(),it->y())); + for(int i=0; i < GEOSGetNumGeometries(mGeos); ++i) + polygonList << GEOSGetGeometryN(mGeos, i); } //create new ring - GEOS_GEOM::LinearRing* newRing = 0; - try - { - newRing = geosGeometryFactory->createLinearRing(newSequence); - owner.release(); - } - CATCH_GEOS(3) + GEOSGeometry *newRing = 0; + GEOSGeometry *newRingPolygon = 0; - std::vector dummyVector; + try { + newRing = createGeosLinearRing(ring.toVector()); + if( !GEOSisValid(newRing) ) + throw GEOSException("ring is invalid"); - //create polygon from new ring because there is a problem with geos operations and linear rings - GEOS_GEOM::Polygon* newRingPolygon = geosGeometryFactory->createPolygon(*newRing, dummyVector); - if(!newRing || !newRingPolygon || !newRing->isValid() || !newRingPolygon->isValid()) - { - QgsDebugMsg("ring is not valid"); - delete newRing; - delete newRingPolygon; + newRingPolygon = createGeosPolygon( newRing ); + if( !GEOSisValid(newRingPolygon) ) + throw GEOSException("ring polygon is invalid"); + } catch(GEOSException &e) { + Q_UNUSED(e); + if(newRingPolygon) + GEOSGeom_destroy(newRingPolygon); + else if(newRing) + GEOSGeom_destroy(newRing); + return 3; } - GEOS_GEOM::LinearRing* outerRing = 0; //outer ring of already existing feature - std::vector* inner = 0; //vector of inner rings. The existing rings and the new one will be added - int numberOfPolyContainingRing = 0; //for multipolygons: store index of the polygon where the ring is - bool foundPoly = false; //set to true as soon we found a polygon containing the ring + QVector rings; - for(std::list::const_iterator it = polygonList.begin(); it != polygonList.end(); ++it) - { - /***********inner rings*****************************************/ - //consider already existing rings - inner=new std::vector(); - int numExistingRings = (*it)->getNumInteriorRing(); - inner->resize(numExistingRings + 1); - for(int i = 0; i < numExistingRings; ++i) - { - GEOS_GEOM::LinearRing* existingRing = geosGeometryFactory->createLinearRing((*it)->getInteriorRingN(i)->getCoordinates()); - //create polygon from new ring because there is a problem with geos operations and linear rings - GEOS_GEOM::Polygon* existingRingPolygon = geosGeometryFactory->createPolygon(*existingRing, dummyVector); + int i; + for(i=0; idisjoint(newRing)) - if(!existingRingPolygon->disjoint(newRingPolygon)) //does only work with polygons, not linear rings - { - QgsDebugMsg("new ring not disjoint with existing ring"); - //delete objects wich are no longer needed - delete existingRing; - delete existingRingPolygon; - for(std::vector::iterator it = inner->begin(); it != inner->end(); ++it) - { - delete *it; - } - delete inner; - delete newRing; - delete newRingPolygon; - return 4; //error: ring not disjoint with existing rings + GEOSGeometry *shellRing = 0; + GEOSGeometry *shell = 0; + try { + shellRing = GEOSGeom_clone( GEOSGetExteriorRing( polygonList[i] ) ); + shell = createGeosPolygon(shellRing); + + if( !GEOSWithin(newRingPolygon, shell) ) { + GEOSGeom_destroy(shell); + continue; } - (*inner)[i] = existingRing; - delete existingRingPolygon; //delete since this polygon has only be created for disjoint() test + } catch(GEOSException &e) { + Q_UNUSED(e); + if(shell) + GEOSGeom_destroy(shell); + else if(shellRing) + GEOSGeom_destroy(shellRing); + return 4; } - //also add new ring to the vector - if(newRing) - { - (*inner)[numExistingRings] = newRing; - } + // add outer ring + rings << GEOSGeom_clone(shellRing); - /*****************outer ring****************/ - outerRing = geosGeometryFactory->createLinearRing((*it)->getExteriorRing()->getCoordinates()); - //create polygon from new ring because there is a problem with geos operations and linear rings - GEOS_GEOM::Polygon* outerRingPolygon = geosGeometryFactory->createPolygon(*outerRing, dummyVector); + // check inner rings + int n = GEOSGetNumInteriorRings(polygonList[i]); + + int j; + for(j=0; jwithin(outerRing)) - if(newRingPolygon->within(outerRingPolygon)) //does only work for polygons, not linear rings - { - QgsDebugMsg("new ring within outer ring"); - foundPoly = true; - delete outerRingPolygon; - break; //ring is in geometry and does not intersect existing rings -> proceed with adding ring to feature - } - - //we need to search in other polygons... - for(std::vector::iterator it = inner->begin(); it != inner->end(); ++it) - { - if( (*it) != newRing) //we need newRing for later polygons - { - delete *it; + if( GEOSDisjoint(hole, newRingPolygon) ) + continue; + } catch(GEOSException &e) { + Q_UNUSED(e); + if(hole) + GEOSGeom_destroy(hole); + else if(holeRing) + GEOSGeom_destroy(holeRing); + throw; } + + rings << GEOSGeom_clone(holeRing); + + GEOSGeom_destroy(hole); } - delete inner; - delete outerRing; - delete outerRingPolygon; - ++numberOfPolyContainingRing; + if(j==n) + // this is it... + break; } - delete newRingPolygon; + if( i==polygonList.size() ) { + // clear rings + for(int j=0; jcreatePolygon(outerRing,inner); - if(this->wkbType() == QGis::WKBPolygon) - { - delete mGeos; - mGeos = newPolygon; - } - else if(this->wkbType() == QGis::WKBMultiPolygon) - { - //remember in which polygon the ring is and replace only this polygon - std::vector* polygons = new std::vector(); - int numPolys = thisMultiPolygon->getNumGeometries(); - for(int i = 0; i < numPolys; ++i) - { - if(i == numberOfPolyContainingRing) - { - polygons->push_back(newPolygon); - } - else - { - GEOS_GEOM::Polygon* p = (GEOS_GEOM::Polygon*)(thisMultiPolygon->getGeometryN(i)->clone()); - polygons->push_back(p); - } - } - delete mGeos; - mGeos = geosGeometryFactory->createMultiPolygon(polygons); - } - mDirtyWkb = true; - mDirtyGeos = false; - return 0; - } - else - { - delete newRing; + // no containing polygon found return 5; } + + rings << newRing; + + GEOSGeometry *newPolygon = createGeosPolygon(rings); + + if(this->wkbType() == QGis::WKBPolygon) { + GEOSGeom_destroy(mGeos); + mGeos = newPolygon; + } else if(this->wkbType() == QGis::WKBMultiPolygon) { + QVector newPolygons; + + for(int j=0; j& ring) @@ -2734,68 +2685,58 @@ exportWkbToGeos(); } - //this multipolygon - GEOS_GEOM::MultiPolygon* thisMultiPolygon = dynamic_cast(mGeos); - if(!thisMultiPolygon) - { + if( GEOSGeomTypeId(mGeos)!=GEOS_MULTIPOLYGON) return 1; - } //create new polygon from ring //coordinate sequence first - GEOS_GEOM::DefaultCoordinateSequence* newSequence=new GEOS_GEOM::DefaultCoordinateSequence(); - std::auto_ptr< GEOS_GEOM::DefaultCoordinateSequence > owner(newSequence); - for(QList::const_iterator it = ring.begin(); it != ring.end(); ++it) - { - newSequence->add(GEOS_GEOM::Coordinate(it->x(),it->y())); - } + GEOSGeometry *newRing = 0; + GEOSGeometry *newPolygon = 0; - //then linear ring - GEOS_GEOM::LinearRing* newRing = 0; - try - { - newRing = geosGeometryFactory->createLinearRing(newSequence); - owner.release(); - } - CATCH_GEOS(2) - - //finally the polygon - std::vector dummyVector; - GEOS_GEOM::Polygon* newPolygon = geosGeometryFactory->createPolygon(*newRing, dummyVector); - delete newRing; - - if(!newPolygon || !newPolygon->isValid()) - { - delete newPolygon; + try { + newRing = createGeosLinearRing(ring.toVector()); + if( !GEOSisValid(newRing) ) + throw GEOSException("ring invalid"); + newPolygon = createGeosPolygon(newRing); + if( !GEOSisValid(newPolygon) ) + throw GEOSException("polygon invalid"); + } catch(GEOSException &e) { + Q_UNUSED(e); + if(newPolygon) + GEOSGeom_destroy(newPolygon); + else if(newRing) + GEOSGeom_destroy(newRing); return 2; } + QVector polygons; + //create new multipolygon - std::vector* newMultiPolygonVector = new std::vector(); - for(GEOS_SIZE_T i = 0; i < thisMultiPolygon->getNumGeometries(); ++i) + int n = GEOSGetNumGeometries(mGeos); + int i; + for(i=0; igetGeometryN(i); + const GEOSGeometry *polygonN = GEOSGetGeometryN(mGeos, i); - //bail out if new polygon is not disjoint with existing ones - if(!polygonN->disjoint(newPolygon)) - { - delete newPolygon; - for(std::vector::iterator it =newMultiPolygonVector->begin(); it != newMultiPolygonVector->end(); ++it) - { - delete *it; - } - delete newMultiPolygonVector; - return 3; - } - newMultiPolygonVector->push_back(polygonN->clone()); + if( !GEOSDisjoint(polygonN, newPolygon) ) + //bail out if new polygon is not disjoint with existing ones + break; + + polygons << GEOSGeom_clone(polygonN); } - newMultiPolygonVector->push_back(newPolygon); - GEOS_GEOM::MultiPolygon* newMultiPolygon = geosGeometryFactory->createMultiPolygon(newMultiPolygonVector); - delete mGeos; - mGeos = newMultiPolygon; + if(i::const_iterator lineIt; - for(lineIt = splitLine.constBegin(); lineIt != splitLine.constEnd(); ++lineIt) + GEOSGeometry *splitLineGeos = createGeosLineString(splitLine.toVector()); + if(!GEOSisValid(splitLineGeos) || !GEOSisSimple(splitLineGeos)) { - splitLineCoords->add(GEOS_GEOM::Coordinate(lineIt->x(),lineIt->y())); - } - GEOS_GEOM::LineString* splitLineGeos = geosGeometryFactory->createLineString(splitLineCoords); - if(!splitLineGeos) - { - delete splitLineCoords; + GEOSGeom_destroy(splitLineGeos); return 1; } - if(!splitLineGeos->isValid() || !splitLineGeos->isSimple()) - { - delete splitLineGeos; - return 1; - } - //for line/multiline: call splitLinearGeometry if(vectorType() == QGis::Line) { returnCode = splitLinearGeometry(splitLineGeos, newGeometries); - delete splitLineGeos; + GEOSGeom_destroy(splitLineGeos); } else if(vectorType() == QGis::Polygon) { returnCode = splitPolygonGeometry(splitLineGeos, newGeometries); - delete splitLineGeos; + GEOSGeom_destroy(splitLineGeos); } else { @@ -3010,12 +2939,12 @@ return 1; } - if(!mGeos->isValid()) + if(!GEOSisValid(mGeos)) { return 2; } - if(!mGeos->isSimple()) + if(!GEOSisSimple(mGeos)) { return 3; } @@ -3034,12 +2963,12 @@ //make geometry::difference try { - if(mGeos->intersects(other->mGeos)) + if(GEOSIntersects(mGeos, other->mGeos)) { //check if multitype before and after bool multiType = isMultipart(); - mGeos = mGeos->difference(other->mGeos); + mGeos = GEOSDifference(mGeos, other->mGeos); mDirtyWkb = true; if(multiType && !isMultipart()) @@ -3365,7 +3294,7 @@ return false; } - return mGeos->intersects(geometry->mGeos); + return GEOSIntersects(mGeos, geometry->mGeos); } CATCH_GEOS(false) } @@ -3381,17 +3310,21 @@ return false; } - GEOS_GEOM::Point* geosPoint = geosGeometryFactory->createPoint(GEOS_GEOM::Coordinate(p->x(), p->y())); - std::auto_ptr< GEOS_GEOM::Point > owner(geosPoint); + GEOSGeometry *geosPoint = 0; - bool returnval; - try - { - returnval = mGeos->contains(geosPoint); - owner.release(); + bool returnval = false; + + try { + geosPoint = createGeosPoint( *p ); + returnval = GEOSContains(mGeos, geosPoint); + } catch(GEOSException &e) { + Q_UNUSED(e); + returnval = false; } - CATCH_GEOS(false) + if(geosPoint) + GEOSGeom_destroy(geosPoint); + return returnval; } @@ -3690,7 +3623,7 @@ if (mGeos) { - delete mGeos; + GEOSGeom_destroy(mGeos); mGeos = 0; } @@ -3727,7 +3660,7 @@ x = (double *) (mGeometry + 5); y = (double *) (mGeometry + 5 + sizeof(double)); - mGeos = geosGeometryFactory->createPoint(GEOS_GEOM::Coordinate(*x,*y)); + mGeos = createGeosPoint( QgsPoint(*x,*y) ); mDirtyGeos = FALSE; break; } @@ -3736,7 +3669,8 @@ hasZValue = true; case QGis::WKBMultiPoint: { - std::vector* points=new std::vector; + QVector points; + ptr = mGeometry + 5; nPoints = (int *) ptr; ptr = mGeometry + 1 + 2 * sizeof(int); @@ -3751,9 +3685,9 @@ { ptr += sizeof(double); } - points->push_back(geosGeometryFactory->createPoint(GEOS_GEOM::Coordinate(*x,*y))); + points << createGeosPoint( QgsPoint(*x,*y) ); } - mGeos = geosGeometryFactory->createMultiPoint(points); + mGeos = createGeosCollection(GEOS_MULTIPOINT, points); mDirtyGeos = FALSE; break; } @@ -3764,7 +3698,8 @@ { QgsDebugMsg("QgsGeometry::geosGeometry: Linestring found"); - GEOS_GEOM::DefaultCoordinateSequence* sequence=new GEOS_GEOM::DefaultCoordinateSequence(); + QgsPolyline sequence; + ptr = mGeometry + 5; nPoints = (int *) ptr; ptr = mGeometry + 1 + 2 * sizeof(int); @@ -3778,10 +3713,11 @@ { ptr += sizeof(double); } - sequence->add(GEOS_GEOM::Coordinate(*x,*y)); + + sequence << QgsPoint(*x,*y); } mDirtyGeos = FALSE; - mGeos = geosGeometryFactory->createLineString(sequence); + mGeos = createGeosLineString(sequence); break; } @@ -3789,12 +3725,13 @@ hasZValue = true; case QGis::WKBMultiLineString: { - std::vector* lines=new std::vector; + QVector lines; numLineStrings = (int) (mGeometry[5]); ptr = (mGeometry + 9); for (jdx = 0; jdx < numLineStrings; jdx++) { - GEOS_GEOM::DefaultCoordinateSequence* sequence=new GEOS_GEOM::DefaultCoordinateSequence(); + QgsPolyline sequence; + // each of these is a wbklinestring so must handle as such lsb = *ptr; ptr += 5; // skip type since we know its 2 @@ -3810,11 +3747,11 @@ { ptr += sizeof(double); } - sequence->add(GEOS_GEOM::Coordinate(*x,*y)); + sequence << QgsPoint(*x,*y); } - lines->push_back(geosGeometryFactory->createLineString(sequence)); + lines << createGeosLineString(sequence); } - mGeos = geosGeometryFactory->createMultiLineString(lines); + mGeos = createGeosCollection(GEOS_MULTILINESTRING, lines); mDirtyGeos = FALSE; break; } @@ -3829,15 +3766,14 @@ numRings = (int *) (mGeometry + 1 + sizeof(int)); ptr = mGeometry + 1 + 2 * sizeof(int); - GEOS_GEOM::LinearRing* outer=0; - std::vector* inner=new std::vector; + QVector rings; for (idx = 0; idx < *numRings; idx++) { - //QgsDebugMsg("Ring nr: "+QString::number(idx)); - GEOS_GEOM::DefaultCoordinateSequence* sequence=new GEOS_GEOM::DefaultCoordinateSequence(); + QgsPolyline sequence; + // get number of points in the ring nPoints = (int *) ptr; ptr += 4; @@ -3852,19 +3788,12 @@ { ptr += sizeof(double); } - sequence->add(GEOS_GEOM::Coordinate(*x,*y)); + sequence << QgsPoint(*x,*y); } - GEOS_GEOM::LinearRing* ring=geosGeometryFactory->createLinearRing(sequence); - if(idx==0) - { - outer=ring; - } - else - { - inner->push_back(ring); - } + + rings << createGeosLinearRing(sequence); } - mGeos = geosGeometryFactory->createPolygon(outer,inner); + mGeos = createGeosPolygon(rings); mDirtyGeos = FALSE; break; } @@ -3875,19 +3804,17 @@ { QgsDebugMsg("Multipolygon found"); - std::vector *polygons=new std::vector; + QVector polygons; + // get the number of polygons ptr = mGeometry + 5; numPolygons = (int *) ptr; ptr = mGeometry +9; for (kdx = 0; kdx < *numPolygons; kdx++) { - //QgsDebugMsg("Polygon nr: "+QString::number(kdx)); + QVector rings; - GEOS_GEOM::LinearRing* outer=0; - std::vector* inner=new std::vector; - //skip the endian and mGeometry type info and // get number of rings in the polygon ptr += 5; @@ -3897,7 +3824,8 @@ { //QgsDebugMsg("Ring nr: "+QString::number(idx)); - GEOS_GEOM::DefaultCoordinateSequence* sequence=new GEOS_GEOM::DefaultCoordinateSequence(); + QgsPolyline sequence; + // get number of points in the ring nPoints = (int *) ptr; ptr += 4; @@ -3912,22 +3840,15 @@ { ptr += sizeof(double); } - sequence->add(GEOS_GEOM::Coordinate(*x,*y)); + sequence << QgsPoint(*x,*y); } - GEOS_GEOM::LinearRing* ring=geosGeometryFactory->createLinearRing(sequence); - if(idx==0) - { - outer=ring; - } - else - { - inner->push_back(ring); - } + + rings << createGeosLinearRing(sequence); } - polygons->push_back(geosGeometryFactory->createPolygon(outer,inner)); + polygons << createGeosPolygon(rings); } - mGeos = geosGeometryFactory->createMultiPolygon(polygons); + mGeos = createGeosCollection(GEOS_MULTIPOLYGON, polygons); mDirtyGeos = FALSE; break; } @@ -3972,9 +3893,9 @@ // set up byteOrder char byteOrder = QgsApplication::endian(); - switch (mGeos->getGeometryTypeId()) + switch ( GEOSGeomTypeId(mGeos) ) { - case GEOS_GEOM::GEOS_POINT: // a point + case GEOS_POINT: // a point { mGeometrySize = 1 + // sizeof(byte) 4 + // sizeof(uint32) @@ -3988,22 +3909,25 @@ int wkbType = QGis::WKBPoint; memcpy(mGeometry+1, &wkbType, 4); - GEOS_GEOM::Point* pt = static_cast(mGeos); - double x = pt->getX(); - double y = pt->getY(); + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(mGeos); + double x, y; + GEOSCoordSeq_getX(cs, 0, &x); + GEOSCoordSeq_getY(cs, 0, &y); + memcpy(mGeometry+5, &x, sizeof(double)); memcpy(mGeometry+13, &y, sizeof(double)); break; } // case GEOS_GEOM::GEOS_POINT - case GEOS_GEOM::GEOS_LINESTRING: // a linestring + case GEOS_LINESTRING: // a linestring { //QgsDebugMsg("Got a geos::GEOS_LINESTRING."); - // TODO - int numPoints = mGeos->getNumPoints(); + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(mGeos); + unsigned int numPoints; + GEOSCoordSeq_getSize(cs, &numPoints); // allocate some space for the WKB mGeometrySize = 1 + // sizeof(byte) @@ -4029,11 +3953,10 @@ memcpy(ptr, &numPoints, 4); ptr += 4; - GEOS_GEOM::LineString* geosls = static_cast(mGeos); - const GEOS_GEOM::CoordinateSequence* sequence = geosls->getCoordinatesRO(); + const GEOSCoordSequence *sequence = GEOSGeom_getCoordSeq(mGeos); // assign points - for (int n = 0; n < numPoints; n++) + for (unsigned int n=0; ngetAt(n).y << "." << std::endl; #endif // assign x - memcpy(ptr, &(sequence->getAt(n).x), sizeof(double)); + GEOSCoordSeq_getX(sequence, n, (double *)ptr); ptr += sizeof(double); // assign y - memcpy(ptr, &(sequence->getAt(n).y), sizeof(double)); + GEOSCoordSeq_getY(sequence, n, (double *)ptr); ptr += sizeof(double); } @@ -4055,327 +3978,283 @@ // TODO: Deal with endian-ness } // case GEOS_GEOM::GEOS_LINESTRING - case GEOS_GEOM::GEOS_LINEARRING: // a linear ring (linestring with 1st point == last point) + case GEOS_LINEARRING: // a linear ring (linestring with 1st point == last point) { // TODO break; } // case GEOS_GEOM::GEOS_LINEARRING - case GEOS_GEOM::GEOS_POLYGON: // a polygon + case GEOS_POLYGON: // a polygon { int geometrySize; - double x, y; //point coordinates - GEOS_GEOM::Polygon* thePolygon = dynamic_cast(mGeos); - const GEOS_GEOM::LineString* theRing = 0; - int nPointsInRing = 0; + unsigned int nPointsInRing = 0; - if(thePolygon) + //first calculate the geometry size + geometrySize = 1 + 2*sizeof(int); //endian, type, number of rings + const GEOSGeometry *theRing = GEOSGetExteriorRing(mGeos); + if(theRing) { - //first calculate the geometry size - geometrySize = 1 + 2*sizeof(int); //endian, type, number of rings - theRing = thePolygon->getExteriorRing(); + geometrySize += sizeof(int); + geometrySize += getNumGeosPoints(theRing)*2*sizeof(double); + } + for(int i=0; i < GEOSGetNumInteriorRings(mGeos); ++i) + { + geometrySize += sizeof(int); //number of points in ring + theRing = GEOSGetInteriorRingN(mGeos, i); if(theRing) { - geometrySize += sizeof(int); - geometrySize += theRing->getNumPoints()*2*sizeof(double); + geometrySize += getNumGeosPoints(theRing)*2*sizeof(double); } - for(GEOS_SIZE_T i = 0; i < thePolygon->getNumInteriorRing(); ++i) - { - geometrySize += sizeof(int); //number of points in ring - theRing = thePolygon->getInteriorRingN(i); - if(theRing) - { - geometrySize += theRing->getNumPoints()*2*sizeof(double); - } - } + } - mGeometry = new unsigned char[geometrySize]; - mGeometrySize = geometrySize; + mGeometry = new unsigned char[geometrySize]; + mGeometrySize = geometrySize; - //then fill the geometry itself into the wkb - int position = 0; - // assign byteOrder - memcpy(mGeometry, &byteOrder, 1); - position += 1; - int wkbtype=QGis::WKBPolygon; - memcpy(&mGeometry[position],&wkbtype, sizeof(int)); + //then fill the geometry itself into the wkb + int position = 0; + // assign byteOrder + memcpy(mGeometry, &byteOrder, 1); + position += 1; + int wkbtype=QGis::WKBPolygon; + memcpy(&mGeometry[position],&wkbtype, sizeof(int)); + position += sizeof(int); + int nRings = GEOSGetNumInteriorRings(mGeos)+1; + memcpy(&mGeometry[position], &nRings, sizeof(int)); + position += sizeof(int); + + //exterior ring first + theRing = GEOSGetExteriorRing(mGeos); + if(theRing) + { + nPointsInRing = getNumGeosPoints(theRing); + memcpy(&mGeometry[position], &nPointsInRing, sizeof(int)); position += sizeof(int); - int nRings = thePolygon->getNumInteriorRing()+1; - memcpy(&mGeometry[position], &nRings, sizeof(int)); - position += sizeof(int); - //exterior ring first - theRing = thePolygon->getExteriorRing(); - if(theRing) + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(theRing); + unsigned int n; + GEOSCoordSeq_getSize(cs, &n); + + for(unsigned int j=0; jgetNumPoints(); - memcpy(&mGeometry[position], &nPointsInRing, sizeof(int)); - position += sizeof(int); - const GEOS_GEOM::CoordinateSequence* ringSequence = theRing->getCoordinatesRO(); - //for(int j = 0; j < nPointsInRing; ++j) - for(GEOS_SIZE_T j = 0; j < ringSequence->getSize(); ++j) - { - //x = theRing->getPointN(j)->getX(); - x = ringSequence->getAt(j).x; - memcpy(&mGeometry[position], &x, sizeof(double)); - position += sizeof(double); - //y = theRing->getPointN(j)->getY(); - y = ringSequence->getAt(j).y; - memcpy(&mGeometry[position], &y, sizeof(double)); - position += sizeof(double); - } + GEOSCoordSeq_getX(cs, j, (double *)&mGeometry[position]); + position += sizeof(double); + GEOSCoordSeq_getY(cs, j, (double *)&mGeometry[position]); + position += sizeof(double); } + } - //interior rings after - for(GEOS_SIZE_T i = 0; i < thePolygon->getNumInteriorRing(); ++i) + //interior rings after + for(int i=0; igetInteriorRingN(i); - if(theRing) - { - const GEOS_GEOM::CoordinateSequence* ringSequence = theRing->getCoordinatesRO(); - nPointsInRing = ringSequence->getSize(); - memcpy(&mGeometry[position], &nPointsInRing, sizeof(int)); - position += sizeof(int); - for(int j = 0; j < nPointsInRing; ++j) - { - x = ringSequence->getAt(j).x; - memcpy(&mGeometry[position], &x, sizeof(double)); - position += sizeof(double); - y = ringSequence->getAt(j).y; - memcpy(&mGeometry[position], &y, sizeof(double)); - position += sizeof(double); - } - } + GEOSCoordSeq_getX( cs, j, (double *)&mGeometry[position]); + position += sizeof(double); + GEOSCoordSeq_getY( cs, j, (double *)&mGeometry[position]); + position += sizeof(double); } - mDirtyWkb = FALSE; - return true; } - else - { - //error - } - break; + mDirtyWkb = FALSE; + return true; } // case GEOS_GEOM::GEOS_POLYGON + break; - case GEOS_GEOM::GEOS_MULTIPOINT: // a collection of points + case GEOS_MULTIPOINT: // a collection of points { - GEOS_GEOM::MultiPoint* theMultiPoint = dynamic_cast(mGeos); - if(!theMultiPoint) - { - return false; - } - - //find out size of geometry - int geometrySize = 1 + 2 * sizeof(int); - for(GEOS_SIZE_T i = 0; i < theMultiPoint->getNumGeometries(); ++i) - { - geometrySize += (1 + 2 * sizeof(int) + 2 * sizeof(double)); - } + // determine size of geometry + int geometrySize = 1 + 2 * sizeof(int); + for(int i=0; i < GEOSGetNumGeometries(mGeos); i++) + { + geometrySize += 1 + 2 * sizeof(int) + 2 * sizeof(double); + } - mGeometry = new unsigned char[geometrySize]; - mGeometrySize = geometrySize; - int wkbPosition = 0; //current position in the byte array - - memcpy(mGeometry, &byteOrder, 1); - wkbPosition += 1; - int wkbtype=QGis::WKBMultiPoint; - memcpy(&mGeometry[wkbPosition],&wkbtype, sizeof(int)); - wkbPosition += sizeof(int); - int numPoints = theMultiPoint->getNumGeometries(); - memcpy(&mGeometry[wkbPosition], &numPoints, sizeof(int)); - wkbPosition += sizeof(int); + mGeometry = new unsigned char[geometrySize]; + mGeometrySize = geometrySize; + int wkbPosition = 0; //current position in the byte array - int pointType = QGis::WKBPoint; - double x, y; - GEOS_GEOM::Point* currentPoint = 0; + memcpy(mGeometry, &byteOrder, 1); + wkbPosition += 1; + int wkbtype=QGis::WKBMultiPoint; + memcpy(&mGeometry[wkbPosition],&wkbtype, sizeof(int)); + wkbPosition += sizeof(int); + int numPoints = GEOSGetNumGeometries(mGeos); + memcpy(&mGeometry[wkbPosition], &numPoints, sizeof(int)); + wkbPosition += sizeof(int); - for(GEOS_SIZE_T i = 0; i < theMultiPoint->getNumGeometries(); ++i) - { - //copy endian and point type - memcpy(&mGeometry[wkbPosition], &byteOrder, 1); - wkbPosition += 1; - memcpy(&mGeometry[wkbPosition], &pointType, sizeof(int)); - wkbPosition += sizeof(int); + int pointType = QGis::WKBPoint; + const GEOSGeometry *currentPoint = 0; - currentPoint = (GEOS_GEOM::Point*)(theMultiPoint->getGeometryN(i)); - //x - x = currentPoint->getX(); - memcpy(&mGeometry[wkbPosition], &x, sizeof(double)); - wkbPosition += sizeof(double); - //y - y = currentPoint->getY(); - memcpy(&mGeometry[wkbPosition], &y, sizeof(double)); - wkbPosition += sizeof(double); - } - mDirtyWkb = FALSE; - return true; + for(int i=0; i(mGeos); - if(!theMultiLineString) - { - return false; - } - - //find out size of geometry - int geometrySize = 1 + 2 * sizeof(int); - for(GEOS_SIZE_T i = 0; i < theMultiLineString->getNumGeometries(); ++i) - { - geometrySize += (1 + 2 * sizeof(int)); - geometrySize += theMultiLineString->getGeometryN(i)->getNumPoints() * 2 * sizeof(double); - } + // determine size of geometry + int geometrySize = 1 + 2 * sizeof(int); + for(int i=0; i < GEOSGetNumGeometries(mGeos); i++) + { + geometrySize += 1 + 2 * sizeof(int); + geometrySize += getNumGeosPoints( GEOSGetGeometryN(mGeos,i) ) * 2 * sizeof(double); + } - mGeometry = new unsigned char[geometrySize]; - mGeometrySize = geometrySize; - int wkbPosition = 0; //current position in the byte array - - memcpy(mGeometry, &byteOrder, 1); - wkbPosition += 1; - int wkbtype=QGis::WKBMultiLineString; - memcpy(&mGeometry[wkbPosition],&wkbtype, sizeof(int)); - wkbPosition += sizeof(int); - int numLines = theMultiLineString->getNumGeometries(); - memcpy(&mGeometry[wkbPosition], &numLines, sizeof(int)); - wkbPosition += sizeof(int); + mGeometry = new unsigned char[geometrySize]; + mGeometrySize = geometrySize; + int wkbPosition = 0; //current position in the byte array - //loop over lines - int lineType = QGis::WKBLineString; - GEOS_GEOM::CoordinateSequence* lineCoordinates = 0; - GEOS_SIZE_T lineSize; - double x, y; + memcpy(mGeometry, &byteOrder, 1); + wkbPosition += 1; + int wkbtype=QGis::WKBMultiLineString; + memcpy(&mGeometry[wkbPosition],&wkbtype, sizeof(int)); + wkbPosition += sizeof(int); + int numLines = GEOSGetNumGeometries(mGeos); + memcpy(&mGeometry[wkbPosition], &numLines, sizeof(int)); + wkbPosition += sizeof(int); - for(GEOS_SIZE_T i = 0; i < theMultiLineString->getNumGeometries(); ++i) - { - //endian and type WKBLineString - memcpy(&mGeometry[wkbPosition], &byteOrder, 1); - wkbPosition += 1; - memcpy(&mGeometry[wkbPosition], &lineType, sizeof(int)); - wkbPosition += sizeof(int); - lineCoordinates = theMultiLineString->getGeometryN(i)->getCoordinates(); - - //line size - lineSize = lineCoordinates->getSize(); - memcpy(&mGeometry[wkbPosition], &lineSize, sizeof(int)); - wkbPosition += sizeof(int); - - //vertex coordinates - for(GEOS_SIZE_T j = 0; j < lineSize; ++j) - { - GEOS_GEOM::Coordinate c = lineCoordinates->getAt(j); - x = c.x; y = c.y; - memcpy(&mGeometry[wkbPosition], &x, sizeof(double)); - wkbPosition += sizeof(double); - memcpy(&mGeometry[wkbPosition], &y, sizeof(double)); - wkbPosition += sizeof(double); - } - delete lineCoordinates; - } - mDirtyWkb = FALSE; - return true; + //loop over lines + int lineType = QGis::WKBLineString; + const GEOSCoordSequence *cs = 0; + unsigned int lineSize; + + for(int i=0; i(mGeos); - if(!theMultiPolygon) - { - return false; - } - - //first determine size of geometry + //first determine size of geometry int geometrySize = 1 + (2 * sizeof(int)); //endian, type, number of polygons - for(GEOS_SIZE_T i = 0; i < theMultiPolygon->getNumGeometries(); ++i) - { - GEOS_GEOM::Polygon* thePoly = (GEOS_GEOM::Polygon*)(theMultiPolygon->getGeometryN(i)); - geometrySize += (1 + (2 * sizeof(int))); //endian, type, number of rings - //exterior ring - geometrySize += sizeof(int); //number of points in exterior ring - const GEOS_GEOM::LineString* exRing = thePoly->getExteriorRing(); - geometrySize += (2*sizeof(double)*exRing->getNumPoints()); + for(int i=0; igetNumInteriorRing(); ++j) - { - geometrySize += sizeof(int); //number of points in ring - intRing = thePoly->getInteriorRingN(j); - geometrySize += 2*sizeof(double)*intRing->getNumPoints(); - } - } + const GEOSGeometry *intRing = 0; + for(int j=0; jgetNumGeometries(); - memcpy(&mGeometry[wkbPosition], &numPolygons, sizeof(int)); - wkbPosition += sizeof(int); + mGeometry = new unsigned char[geometrySize]; + mGeometrySize = geometrySize; + int wkbPosition = 0; //current position in the byte array - //loop over polygons - for(GEOS_SIZE_T i = 0; i < theMultiPolygon->getNumGeometries(); ++i) - { - GEOS_GEOM::Polygon* thePoly = (GEOS_GEOM::Polygon*)(theMultiPolygon->getGeometryN(i)); - memcpy(&mGeometry[wkbPosition], &byteOrder, 1); - wkbPosition += 1; - int polygonType = QGis::WKBPolygon; - memcpy(&mGeometry[wkbPosition], &polygonType, sizeof(int)); - wkbPosition += sizeof(int); - int numRings = thePoly->getNumInteriorRing() + 1; - memcpy(&mGeometry[wkbPosition], &numRings, sizeof(int)); - wkbPosition += sizeof(int); + memcpy(mGeometry, &byteOrder, 1); + wkbPosition += 1; + int wkbtype=QGis::WKBMultiPolygon; + memcpy(&mGeometry[wkbPosition], &wkbtype, sizeof(int)); + wkbPosition += sizeof(int); + int numPolygons = GEOSGetNumGeometries(mGeos); + memcpy(&mGeometry[wkbPosition], &numPolygons, sizeof(int)); + wkbPosition += sizeof(int); - //exterior ring - const GEOS_GEOM::LineString* theRing = thePoly->getExteriorRing(); - int nPointsInRing = theRing->getNumPoints(); - memcpy(&mGeometry[wkbPosition], &nPointsInRing, sizeof(int)); - wkbPosition += sizeof(int); - const GEOS_GEOM::CoordinateSequence* ringCoordinates = theRing->getCoordinatesRO(); - - double x, y; - GEOS_GEOM::Coordinate coord; - for(int k = 0; k < nPointsInRing; ++k) - { - coord = ringCoordinates->getAt(k); - x = coord.x; - y = coord.y; - memcpy(&mGeometry[wkbPosition], &x, sizeof(double)); - wkbPosition += sizeof(double); - memcpy(&mGeometry[wkbPosition], &y, sizeof(double)); - wkbPosition += sizeof(double); - } - - //interior rings - for(GEOS_SIZE_T j = 0; j < thePoly->getNumInteriorRing(); ++j) - { - theRing = thePoly->getInteriorRingN(j); - nPointsInRing = theRing->getNumPoints(); - memcpy(&mGeometry[wkbPosition], &nPointsInRing, sizeof(int)); - wkbPosition += sizeof(int); - ringCoordinates = theRing->getCoordinatesRO(); + //loop over polygons + for(int i=0; igetAt(k); - x = coord.x; - y = coord.y; - memcpy(&mGeometry[wkbPosition], &x, sizeof(double)); - wkbPosition += sizeof(double); - memcpy(&mGeometry[wkbPosition], &y, sizeof(double)); - wkbPosition += sizeof(double); - } - } - } - mDirtyWkb = FALSE; - return true; + //exterior ring + const GEOSGeometry *theRing = GEOSGetExteriorRing(thePoly); + int nPointsInRing = getNumGeosPoints(theRing); + memcpy(&mGeometry[wkbPosition], &nPointsInRing, sizeof(int)); + wkbPosition += sizeof(int); + const GEOSCoordSequence *cs = GEOSGeom_getCoordSeq(theRing); + + for(int k = 0; k < nPointsInRing; ++k) + { + GEOSCoordSeq_getX(cs, k, (double *)&mGeometry[wkbPosition]); + wkbPosition += sizeof(double); + GEOSCoordSeq_getY(cs, k, (double *)&mGeometry[wkbPosition]); + wkbPosition += sizeof(double); + } + + //interior rings + for(int j=0; j& newGeometries) +int QgsGeometry::splitLinearGeometry(GEOSGeometry *splitLine, QList& newGeometries) { if(!splitLine) - { - return 2; - } + { + return 2; + } if(!mGeos || mDirtyGeos) - { - exportWkbToGeos(); - } + { + exportWkbToGeos(); + } - //first test if linestring intersects geometry. If not, return straight away - if(!splitLine->intersects(mGeos)) - { - return 1; - } + //first test if linestring intersects geometry. If not, return straight away + if(!GEOSIntersects(splitLine, mGeos)) + { + return 1; + } - //todo: use the geos polygonizer - GEOS_LINEMERGE::LineMerger lineMerger; - //first union all the polygon rings together (to get them noded, see JTS developer guide) - GEOS_GEOM::Geometry* nodedGeometry = nodeGeometries(splitLine, mGeos); + GEOSGeometry* nodedGeometry = nodeGeometries(splitLine, mGeos); if(!nodedGeometry) - { - return 3; //an error occured during noding - } + { + return 3; //an error occured during noding + } - lineMerger.add(nodedGeometry); + GEOSGeometry *mergedLines = GEOSLineMerge(nodedGeometry); + if(!mergedLines) + { + GEOSGeom_destroy(nodedGeometry); + return 4; + } - std::vector* mergedLineStrings = lineMerger.getMergedLineStrings(); - if(!mergedLineStrings) - { - delete nodedGeometry; - return 4; - } + QVector testedGeometries; + GEOSGeometry* intersectGeom = 0; - QList testedGeometries; - GEOS_GEOM::Geometry* intersectGeom = 0; - //hardcoded thresholds double bufferDistance = 0.000000001; double intersectThreshold = 0.0000001; - for(unsigned int i = 0; i < mergedLineStrings->size(); ++i) - { - intersectGeom = mGeos->intersection((*mergedLineStrings)[i]->buffer(bufferDistance)); - if(intersectGeom->getLength() > intersectThreshold) - { - testedGeometries.push_back((*mergedLineStrings)[i]); - } - else - { - delete (*mergedLineStrings)[i]; - } - delete intersectGeom; - } + for(int i=0; i intersectThreshold) + testedGeometries << GEOSGeom_clone(testing); + GEOSGeom_destroy(intersectGeom); + } mergeGeometriesMultiTypeSplit(testedGeometries); if(testedGeometries.size() > 0) - { - delete mGeos; - mGeos = testedGeometries.at(0); - mDirtyWkb = true; - } + { + GEOSGeom_destroy(mGeos); + mGeos = testedGeometries[0]; + mDirtyWkb = true; + } - for(int i = 1; i < testedGeometries.size(); ++i) - { - QgsGeometry* newQgisGeometry = new QgsGeometry(); - newQgisGeometry->setGeos(testedGeometries[i]); - newGeometries.push_back(newQgisGeometry); - } + for(int i=1; i& newGeometries) +int QgsGeometry::splitPolygonGeometry(GEOSGeometry* splitLine, QList& newGeometries) { if(!splitLine) - { - return 2; - } + { + return 2; + } if(!mGeos || mDirtyGeos) - { - exportWkbToGeos(); - } + { + exportWkbToGeos(); + } //first test if linestring intersects geometry. If not, return straight away - if(!splitLine->intersects(mGeos)) - { - return 1; - } + if(!GEOSIntersects(splitLine, mGeos)) + { + return 1; + } - //todo: use the geos polygonizer - GEOS_POLYGONIZE::Polygonizer polygonizer; - //first union all the polygon rings together (to get them noded, see JTS developer guide) - GEOS_GEOM::Geometry* nodedGeometry = nodeGeometries(splitLine, mGeos); + GEOSGeometry *nodedGeometry = nodeGeometries(splitLine, mGeos); if(!nodedGeometry) - { - return 2; //an error occured during noding + { + return 2; //an error occured during noding + } + +#if GEOS_VERSION_MAJOR>3 || (GEOS_VERSION_MAJOR==3 && GEOS_VERSION_MINOR>=1) + GEOSGeometry *cutEdges = GEOSPolygonizer_getCutEdges( &nodedGeometry, 1 ); + if( cutEdges ) { + if( GEOSGetNumGeometries(cutEdges)>0 ) { + GEOSGeom_destroy(cutEdges); + GEOSGeom_destroy(nodedGeometry); + return 3; } - //add to polygonizer - polygonizer.add(nodedGeometry); + GEOSGeom_destroy(cutEdges); + } +#endif + + GEOSGeometry *polygons = GEOSPolygonize( &nodedGeometry, 1 ); + if( !polygons || GEOSGetNumGeometries(polygons)==0 ) + { + if(polygons) + GEOSGeom_destroy(polygons); - //test for cut edge and abort split if they are present - std::vector* cutEdges = polygonizer.getCutEdges(); - if(cutEdges && cutEdges->size() > 0) - { - return 3; - } + GEOSGeom_destroy(nodedGeometry); - std::vector* polygons = polygonizer.getPolygons(); - if(!polygons) - { - delete nodedGeometry; - return 4; - } + return 4; + } + GEOSGeom_destroy(nodedGeometry); + //test every polygon if contained in original geometry //include in result if yes - QList testedGeometries; - GEOS_GEOM::Geometry* intersectGeometry = 0; + QVector testedGeometries; + GEOSGeometry *intersectGeometry = 0; //ratio intersect geometry / geometry. This should be close to 1 //if the polygon belongs to the input geometry double areaRatio = 0.0; - for(unsigned int i = 0; i < polygons->size(); ++i) - { - intersectGeometry = mGeos->intersection((*polygons)[i]); - areaRatio = intersectGeometry->getArea() / (*polygons)[i]->getArea(); - if(areaRatio > 0.99 && areaRatio < 1.01) - { - testedGeometries.push_back((*polygons)[i]); - } - else - { - delete (*polygons)[i]; - } - delete intersectGeometry; - } + for(int i=0; i 0.99 && areaRatio < 1.01) + testedGeometries << GEOSGeom_clone(polygon); + + GEOSGeom_destroy( intersectGeometry ); + } + mergeGeometriesMultiTypeSplit(testedGeometries); if(testedGeometries.size() > 0) - { - delete mGeos; - mGeos = testedGeometries.at(0); - mDirtyWkb = true; - } + { + GEOSGeom_destroy( mGeos ); + mGeos = testedGeometries[0]; + mDirtyWkb = true; + } for(int i = 1; i < testedGeometries.size(); ++i) - { - QgsGeometry* newQgisGeometry = new QgsGeometry(); - newQgisGeometry->setGeos(testedGeometries[i]); - newGeometries.push_back(newQgisGeometry); - } + { + newGeometries << fromGeosGeom( testedGeometries[i] ); + } - delete nodedGeometry; - delete polygons; + GEOSGeom_destroy( polygons ); return 0; } -GEOS_GEOM::Geometry* QgsGeometry::nodeGeometries(const GEOS_GEOM::LineString* splitLine, const GEOS_GEOM::Geometry* geom) const +GEOSGeometry *QgsGeometry::nodeGeometries(const GEOSGeometry *splitLine, GEOSGeometry *geom) const { if(!splitLine || !geom) - { - return 0; - } + { + return 0; + } - const GEOS_GEOM::Geometry* geometryBoundary = 0; + GEOSGeometry *geometryBoundary = 0; bool deleteBoundary = false; - if(geom->getGeometryTypeId() == GEOS_GEOM::GEOS_POLYGON || geom->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTIPOLYGON) - { - geometryBoundary = geom->getBoundary(); - deleteBoundary = true; - } + if( GEOSGeomTypeId(geom) == GEOS_POLYGON || GEOSGeomTypeId(geom) == GEOS_MULTIPOLYGON) + { + geometryBoundary = GEOSBoundary(geom); + deleteBoundary = true; + } else - { - geometryBoundary = geom; - } + { + geometryBoundary = geom; + } - GEOS_GEOM::Geometry* splitLineClone = splitLine->clone(); - GEOS_GEOM::Geometry* unionGeometry = splitLineClone->Union(geometryBoundary); - - delete splitLineClone; + GEOSGeometry *splitLineClone = GEOSGeom_clone(splitLine); + GEOSGeometry *unionGeometry = GEOSUnion(splitLineClone, geometryBoundary); + GEOSGeom_destroy(splitLineClone); + if(deleteBoundary) - { - delete geometryBoundary; - } + GEOSGeom_destroy(geometryBoundary); return unionGeometry; } -int QgsGeometry::mergeGeometriesMultiTypeSplit(QList& splitResult) +int QgsGeometry::mergeGeometriesMultiTypeSplit(QVector& splitResult) { if(!mGeos || mDirtyGeos) - { - exportWkbToGeos(); - } + { + exportWkbToGeos(); + } //convert mGeos to geometry collection - GEOS_GEOM::GeometryCollection* collection = dynamic_cast(mGeos); - if(!collection) - { - return 0; - } + int type = GEOSGeomTypeId(mGeos); + if( type!=GEOS_GEOMETRYCOLLECTION && + type!=GEOS_MULTILINESTRING && + type!=GEOS_MULTIPOLYGON && + type!=GEOS_MULTIPOINT ) { + return 0; + } - QList copyList = splitResult; + QVector copyList = splitResult; splitResult.clear(); //collect all the geometries that belong to the initial multifeature - std::vector* unionGeom = new std::vector(); + QVector unionGeom; for(int i = 0; i < copyList.size(); ++i) + { + //is this geometry a part of the original multitype? + bool isPart = false; + for(int j=0; jgetNumGeometries(); ++j) - { - if(copyList.at(i)->equals(collection->getGeometryN(j))) - { - isPart = true; - break; - } - } + if( GEOSEquals(copyList[i], GEOSGetGeometryN(mGeos, j)) ) + { + isPart = true; + break; + } + } - if(isPart) - { - unionGeom->push_back(copyList.at(i)); - } + if(isPart) + { + unionGeom << copyList[i]; + } + else + { + QVector geomVector; + geomVector << copyList[i]; + + if( type == GEOS_MULTILINESTRING) + { + splitResult << createGeosCollection(GEOS_MULTILINESTRING, geomVector); + } + else if(type == GEOS_MULTIPOLYGON) + { + splitResult << createGeosCollection(GEOS_MULTIPOLYGON, geomVector); + } else - { - std::vector* geomVector = new std::vector(); - geomVector->push_back(copyList.at(i)); - if(mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTILINESTRING) - { - splitResult.push_back(geosGeometryFactory->createMultiLineString(geomVector)); - } - else if(mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTIPOLYGON) - { - splitResult.push_back(geosGeometryFactory->createMultiPolygon(geomVector)); - } - else - { - delete copyList.at(i); - delete geomVector; - } - } + { + GEOSGeom_destroy( copyList[i] ); + } } + } //make multifeature out of unionGeom - if(unionGeom->size() > 0) + if( unionGeom.size() > 0 ) + { + if( type == GEOS_MULTILINESTRING) { - if(mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTILINESTRING) - { - splitResult.push_front(geosGeometryFactory->createMultiLineString(unionGeom)); - } - else if(mGeos->getGeometryTypeId() == GEOS_GEOM::GEOS_MULTIPOLYGON) - { - splitResult.push_front(geosGeometryFactory->createMultiPolygon(unionGeom)); - } + splitResult << createGeosCollection(GEOS_MULTILINESTRING, unionGeom); } - else + else if(type == GEOS_MULTIPOLYGON) { - delete unionGeom; + splitResult << createGeosCollection(GEOS_MULTIPOLYGON, unionGeom); } + } + else + { + unionGeom.clear(); + } return 0; } @@ -5048,7 +4921,9 @@ try { - return mGeos->distance(geom.mGeos); + double dist; + GEOSDistance(mGeos, geom.mGeos, &dist); + return dist; } CATCH_GEOS(-1.0) } @@ -5064,16 +4939,12 @@ { return 0; } - GEOS_GEOM::Geometry* geos; + try { - geos = mGeos->buffer(distance, segments); + return fromGeosGeom( GEOSBuffer(mGeos, distance, segments) ); } CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } QgsGeometry* QgsGeometry::convexHull() @@ -5087,16 +4958,11 @@ return 0; } - GEOS_GEOM::Geometry* geos; try { - geos = mGeos->convexHull(); + return fromGeosGeom( GEOSConvexHull(mGeos) ); } CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } QgsGeometry* QgsGeometry::intersection(QgsGeometry* geometry) @@ -5118,16 +4984,11 @@ return 0; } - GEOS_GEOM::Geometry* geos; try { - geos = mGeos->intersection(geometry->mGeos); + return fromGeosGeom( GEOSIntersection(mGeos, geometry->mGeos) ); } CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } QgsGeometry* QgsGeometry::Union(QgsGeometry* geometry) @@ -5148,16 +5009,12 @@ { return 0; } - GEOS_GEOM::Geometry* geos = 0; + try { - geos = mGeos->Union(geometry->mGeos); + return fromGeosGeom( GEOSUnion( mGeos, geometry->mGeos) ); } CATCH_GEOS( new QgsGeometry(*this) ) //return this geometry if union not possible - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } QgsGeometry* QgsGeometry::difference(QgsGeometry* geometry) @@ -5178,16 +5035,12 @@ { return 0; } - GEOS_GEOM::Geometry* geos; + try { - geos = mGeos->difference(geometry->mGeos); + return fromGeosGeom( GEOSDifference(mGeos, geometry->mGeos) ); } CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } QgsGeometry* QgsGeometry::symDifference(QgsGeometry* geometry) @@ -5209,14 +5062,9 @@ return 0; } - GEOS_GEOM::Geometry* geos; try { - geos = mGeos->symDifference(geometry->mGeos); + return fromGeosGeom( GEOSSymDifference( mGeos, geometry->mGeos) ); } CATCH_GEOS(0) - - QgsGeometry* g = new QgsGeometry; - g->setGeos(geos); - return g; } Index: src/core/spatialindex/qgsspatialindex.cpp =================================================================== --- src/core/spatialindex/qgsspatialindex.cpp (Revision 9021) +++ src/core/spatialindex/qgsspatialindex.cpp (Arbeitskopie) @@ -19,6 +19,7 @@ #include "qgsgeometry.h" #include "qgsfeature.h" #include "qgsrect.h" +#include "qgslogger.h" #include "SpatialIndex.h" @@ -105,8 +106,16 @@ if (!featureInfo(f, r, id)) return false; - // TODO: handle possible exceptions - mRTree->insertData(0,0, r, id); + // TODO: handle possible exceptions correctly + try { + mRTree->insertData(0,0, r, id); + } catch(Tools::Exception &e) { + QgsDebugMsg( QString("Tools::Exception caught: ").arg(e.what().c_str()) ); + } catch(const std::exception &e) { + QgsDebugMsg( QString("std::exception caught: ").arg(e.what()) ); + } catch(...) { + QgsDebugMsg( "unknown spatial index exception caught" ); + } return true; } Index: src/core/qgsgeometry.h =================================================================== --- src/core/qgsgeometry.h (Revision 9021) +++ src/core/qgsgeometry.h (Arbeitskopie) @@ -22,15 +22,10 @@ #include "qgis.h" -#include -#if GEOS_VERSION_MAJOR < 3 -#include -#define GEOS_GEOM geos -#else -#include -#include -#include -#define GEOS_GEOM geos::geom +#include + +#if GEOS_VERSION_MAJOR<3 +#define GEOSGeometry GEOSGeom #endif #include "qgspoint.h" @@ -67,7 +62,6 @@ */ class CORE_EXPORT QgsGeometry { - public: @@ -125,7 +119,7 @@ Set the geometry, feeding in a geometry in GEOS format. This class will take ownership of the buffer. */ - void setGeos(GEOS_GEOM::Geometry* geos); + void setGeos(GEOSGeometry* geos); /** Set the geometry, feeding in the buffer containing OGC Well-Known Binary and the buffer's length. @@ -230,8 +224,8 @@ int addRing(const QList& ring); /**Adds a new island polygon to a multipolygon feature - @return 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring \ -not disjoint with existing polygons of the feature*/ + @return 0 in case of success, 1 if not a multipolygon, 2 if ring is not a valid geometry, 3 if new polygon ring + not disjoint with existing polygons of the feature*/ int addIsland(const QList& ring); /**Translate this geometry by dx, dy @@ -312,9 +306,7 @@ if wkbType is WKBPolygon, otherwise an empty list */ QgsMultiPolygon asMultiPolygon(); - private: - - +private: // Private variables // All of these are mutable since there may be on-the-fly @@ -331,7 +323,7 @@ size_t mGeometrySize; /** cached GEOS version of this geometry */ - GEOS_GEOM::Geometry* mGeos; + GEOSGeometry* mGeos; /** If the geometry has been set since the last conversion to WKB **/ bool mDirtyWkb; @@ -374,8 +366,8 @@ */ bool insertVertexBefore(double x, double y, int beforeVertex, - const GEOS_GEOM::CoordinateSequence* old_sequence, - GEOS_GEOM::CoordinateSequence** new_sequence); + const GEOSCoordSequence* old_sequence, + GEOSCoordSequence** new_sequence); /**Converts single type geometry into multitype geometry e.g. a polygon into a multipolygon geometry with one polygon @@ -396,18 +388,18 @@ @splitLine the line that splits the feature @newGeometry new geometry if splitting was successful @return 0 in case of success, 1 if geometry has not been split, error else*/ - int splitLinearGeometry(GEOS_GEOM::LineString* splitLine, QList& newGeometries); + int splitLinearGeometry(GEOSGeometry *splitLine, QList& newGeometries); /**Splits polygon/multipolygon geometries @return 0 in case of success, 1 if geometry has not been split, error else*/ - int splitPolygonGeometry(GEOS_GEOM::LineString* splitLine, QList& newGeometries); + int splitPolygonGeometry(GEOSGeometry *splitLine, QList& newGeometries); /**Finds the vertices next to point where the line is split. If it is split at a vertex, beforeVertex and afterVertex are the same*/ /**Nodes together a split line and a (multi-) polygon geometry in a multilinestring @return the noded multiline geometry or 0 in case of error. The calling function takes ownership of the node geometry*/ - GEOS_GEOM::Geometry* nodeGeometries(const GEOS_GEOM::LineString* splitLine, const GEOS_GEOM::Geometry* poly) const; + GEOSGeometry* nodeGeometries(const GEOSGeometry *splitLine, GEOSGeometry *poly) const; - int mergeGeometriesMultiTypeSplit(QList& splitResult); + int mergeGeometriesMultiTypeSplit(QVector& splitResult); /** return point from wkb */ QgsPoint asPoint(unsigned char*& ptr, bool hasZValue); @@ -418,6 +410,7 @@ /** return polygon from wkb */ QgsPolygon asPolygon(unsigned char*& ptr, bool hasZValue); + static int refcount; }; // class QgsGeometry #endif Index: src/providers/wfs/qgswfsdata.cpp =================================================================== --- src/providers/wfs/qgswfsdata.cpp (Revision 9021) +++ src/providers/wfs/qgswfsdata.cpp (Arbeitskopie) @@ -17,6 +17,8 @@ #include "qgsspatialrefsys.h" #include #include +#include +#include //just for a test //#include @@ -24,7 +26,23 @@ const char NS_SEPARATOR = '?'; const QString GML_NAMESPACE = "http://www.opengis.net/gml"; -QgsWFSData::QgsWFSData(const QString& uri, QgsRect* extent, QgsSpatialRefSys* srs, std::list* features, const QString& geometryAttribute, const std::set& thematicAttributes, QGis::WKBTYPE* wkbType): QObject(), mUri(uri), mExtent(extent), mSrs(srs), mFeatures(features), mGeometryAttribute(geometryAttribute), mThematicAttributes(thematicAttributes), mWkbType(wkbType), mFinished(false), mFeatureCount(0) +QgsWFSData::QgsWFSData( + const QString& uri, QgsRect* extent, + QgsSpatialRefSys* srs, + QList &features, + const QString& geometryAttribute, + const QSet& thematicAttributes, + QGis::WKBTYPE* wkbType) +: QObject(), + mUri(uri), + mExtent(extent), + mSrs(srs), + mFeatures(features), + mGeometryAttribute(geometryAttribute), + mThematicAttributes(thematicAttributes), + mWkbType(wkbType), + mFinished(false), + mFeatureCount(0) { //qWarning("Name of the geometry attribute is:"); //qWarning(mGeometryAttribute.toLocal8Bit().data()); @@ -51,11 +69,6 @@ } -QgsWFSData::QgsWFSData() -{ - -} - int QgsWFSData::getWFSData() { XML_Parser p = XML_ParserCreateNS(NULL, NS_SEPARATOR); @@ -237,7 +250,7 @@ else if(elementName == GML_NAMESPACE + NS_SEPARATOR + "featureMember") { mCurrentFeature->setGeometryAndOwnership(mCurrentWKB, mCurrentWKBSize); - mFeatures->push_back(mCurrentFeature); + mFeatures << mCurrentFeature; ++mFeatureCount; //qWarning("Removing featureMember from stack"); mParseModeStack.pop(); Index: src/providers/wfs/qgswfsprovider.cpp =================================================================== --- src/providers/wfs/qgswfsprovider.cpp (Revision 9021) +++ src/providers/wfs/qgswfsprovider.cpp (Arbeitskopie) @@ -23,6 +23,7 @@ #include "qgsspatialrefsys.h" #include "qgswfsdata.h" #include "qgswfsprovider.h" +#include "qgsspatialindex.h" #include "qgslogger.h" #include #include @@ -37,8 +38,9 @@ static const QString GML_NAMESPACE = "http://www.opengis.net/gml"; QgsWFSProvider::QgsWFSProvider(const QString& uri) - : QgsVectorDataProvider(uri), mUseIntersect(false), mSelectedFeatures(0), mSourceSRS(0), mFeatureCount(0), mValid(true) + : QgsVectorDataProvider(uri), mUseIntersect(false), mSourceSRS(0), mFeatureCount(0), mValid(true) { + mSpatialIndex = new QgsSpatialIndex; if(getFeature(uri) == 0) { mValid = true; @@ -54,58 +56,56 @@ QgsWFSProvider::~QgsWFSProvider() { - delete mSelectedFeatures; - for(std::list >::iterator it = mEnvelopesAndFeatures.begin();\ - it != mEnvelopesAndFeatures.end(); ++it) - { - delete it->first; - delete it->second; - } + mSelectedFeatures.clear(); + for(int i=0; iend()) - { - return 0; - } + return 0; + } - feature.setFeatureId(((QgsFeature*)(*mFeatureIterator))->featureId()); - if(mFetchGeom) - { - QgsGeometry* geometry = ((QgsFeature*)(*mFeatureIterator))->geometry(); - unsigned char* geom = geometry->wkbBuffer(); - int geomSize = geometry->wkbSize(); - - unsigned char* copiedGeom = new unsigned char[geomSize]; - memcpy(copiedGeom, geom, geomSize); - feature.setGeometryAndOwnership(copiedGeom, geomSize); - } - - const QgsAttributeMap& attributes = ((QgsFeature*)(*mFeatureIterator))->attributeMap(); - for(QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it) - { - feature.addAttribute(*it, attributes[*it]); - } - ++mFeatureIterator; - if(mUseIntersect) - { - if(feature.geometry()->intersects(mSpatialFilter)) - { - return true; - } - else - { - continue; //go for the next feature - } - } + feature.setFeatureId( mFeatures[*mFeatureIterator]->featureId() ); + if(mFetchGeom) + { + QgsGeometry* geometry = mFeatures[*mFeatureIterator]->geometry(); + unsigned char* geom = geometry->wkbBuffer(); + int geomSize = geometry->wkbSize(); + + unsigned char* copiedGeom = new unsigned char[geomSize]; + memcpy(copiedGeom, geom, geomSize); + feature.setGeometryAndOwnership(copiedGeom, geomSize); + } + + const QgsAttributeMap& attributes = mFeatures[*mFeatureIterator]->attributeMap(); + for(QgsAttributeList::const_iterator it = mAttributesToFetch.begin(); it != mAttributesToFetch.end(); ++it) + { + feature.addAttribute(*it, attributes[*it]); + } + ++mFeatureIterator; + if(mUseIntersect) + { + if(feature.geometry()->intersects(mSpatialFilter)) + { + return true; + } else - { - return true; - } + { + continue; //go for the next feature + } } + else + { + return true; + } + } } @@ -132,10 +132,7 @@ void QgsWFSProvider::reset() { - if(mSelectedFeatures) - { - mFeatureIterator = mSelectedFeatures->begin(); - } + mFeatureIterator = mSelectedFeatures.begin(); } QgsSpatialRefSys QgsWFSProvider::getSRS() @@ -162,24 +159,17 @@ mAttributesToFetch = fetchAttributes; mFetchGeom = fetchGeometry; - delete mSelectedFeatures; if(rect.isEmpty()) - { - mSpatialFilter = mExtent; - } + { + mSpatialFilter = mExtent; + } else - { - mSpatialFilter = rect; - } + { + mSpatialFilter = rect; + } - GEOS_GEOM::Envelope filter(mSpatialFilter.xMin(), mSpatialFilter.xMax(), mSpatialFilter.yMin(), mSpatialFilter.yMax()); -#if GEOS_VERSION_MAJOR < 3 - mSelectedFeatures = mSpatialIndex.query(&filter); -#else - mSelectedFeatures = new std::vector; - mSpatialIndex.query(&filter, *mSelectedFeatures); -#endif - mFeatureIterator = mSelectedFeatures->begin(); + mSelectedFeatures = mSpatialIndex->intersects(mSpatialFilter); + mFeatureIterator = mSelectedFeatures.begin(); } int QgsWFSProvider::getFeature(const QString& uri) @@ -249,20 +239,20 @@ QByteArray result; QgsHttpTransaction http(request); http.getSynchronously(result); - + QDomDocument getFeatureDocument; if(!getFeatureDocument.setContent(result, true)) - { - return 1; //error - } + { + return 1; //error + } QDomElement featureCollectionElement = getFeatureDocument.documentElement(); - + //get and set Extent if(getExtentFromGML2(&mExtent, featureCollectionElement) != 0) - { - return 3; - } + { + return 3; + } setSRSFromGML2(featureCollectionElement); @@ -275,58 +265,52 @@ #endif //the new and faster method with the expat parser - std::list dataFeatures; - std::set thematicAttributes; + QSet thematicAttributes; for(QgsFieldMap::const_iterator it = mFields.begin(); it != mFields.end(); ++it) - { - thematicAttributes.insert(it->name()); - } - - QgsWFSData dataReader(uri, &mExtent, &mSourceSRS, &dataFeatures, geometryAttribute, thematicAttributes, &mWKBType); + { + thematicAttributes << it->name(); + } + + QgsWFSData dataReader(uri, &mExtent, &mSourceSRS, mFeatures, geometryAttribute, thematicAttributes, &mWKBType); QObject::connect(dataReader.http(), SIGNAL(dataReadProgress(int, int)), this, SLOT(handleWFSProgressMessage(int, int))); //also connect to setStatus signal of qgisapp (if it exists) QWidget* mainWindow = 0; - + QWidgetList topLevelWidgets = qApp->topLevelWidgets(); QWidgetList::iterator it = topLevelWidgets.begin(); for(; it != topLevelWidgets.end(); ++it) + { + if((*it)->objectName() == "QgisApp") { - if((*it)->objectName() == "QgisApp") - { - mainWindow = *it; - break; - } + mainWindow = *it; + break; } - + } + if(mainWindow) - { - QObject::connect(this, SIGNAL(dataReadProgressMessage(QString)), mainWindow, SLOT(showStatusMessage(QString))); - } + { + QObject::connect(this, SIGNAL(dataReadProgressMessage(QString)), mainWindow, SLOT(showStatusMessage(QString))); + } if(dataReader.getWFSData() != 0) - { - qWarning("getWFSData returned with error"); - return 1; - } + { + qWarning("getWFSData returned with error"); + return 1; + } qWarning("feature count after request is:"); - qWarning(QString::number(dataFeatures.size()).toLocal8Bit().data()); + qWarning(QString::number(mFeatures.size()).toLocal8Bit().data()); qWarning("mExtent after request is:"); qWarning(mExtent.stringRep().toLocal8Bit().data()); - mFeatureCount = 0; + for(QList::iterator it = mFeatures.begin(); it != mFeatures.end(); ++it) { + QgsDebugMsg("feature " + QString::number((*it)->featureId())); + mSpatialIndex->insertFeature(**it); + } - QgsRect featureBBox; - GEOS_GEOM::Envelope* geosBBox; - for(std::list::const_iterator it = dataFeatures.begin(); it != dataFeatures.end(); ++it) - { - featureBBox = (*it)->geometry()->boundingBox(); - geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax()); - mSpatialIndex.insert(geosBBox, (void*)(*it)); - mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, (*it))); - ++mFeatureCount; - } + mFeatureCount = mFeatures.size(); + return 0; } @@ -755,8 +739,6 @@ unsigned char* wkb = 0; int wkbSize = 0; QGis::WKBTYPE currentType; - QgsRect featureBBox; - GEOS_GEOM::Envelope* geosBBox; mFeatureCount = 0; for(int i = 0; i < featureTypeNodeList.size(); ++i) @@ -800,10 +782,8 @@ if(wkb && wkbSize > 0) { //insert bbox and pointer to feature into search tree - featureBBox = f->geometry()->boundingBox(); - geosBBox = new GEOS_GEOM::Envelope(featureBBox.xMin(), featureBBox.xMax(), featureBBox.yMin(), featureBBox.yMax()); - mSpatialIndex.insert(geosBBox, (void*)f); - mEnvelopesAndFeatures.push_back(std::make_pair(geosBBox, f)); + mSpatialIndex->insertFeature(*f); + mFeatures << f; ++mFeatureCount; } ++counter; Index: src/providers/wfs/qgswfsdata.h =================================================================== --- src/providers/wfs/qgswfsdata.h (Revision 9021) +++ src/providers/wfs/qgswfsdata.h (Arbeitskopie) @@ -34,7 +34,14 @@ { Q_OBJECT public: - QgsWFSData(const QString& uri, QgsRect* extent, QgsSpatialRefSys* srs, std::list* features, const QString& geometryAttribute, const std::set& thematicAttributes, QGis::WKBTYPE* wkbType); + QgsWFSData( + const QString& uri, + QgsRect* extent, + QgsSpatialRefSys* srs, + QList &features, + const QString& geometryAttribute, + const QSet& thematicAttributes, + QGis::WKBTYPE* wkbType); ~QgsWFSData(); /**Does the Http GET request to the wfs server @@ -74,17 +81,17 @@ void endElement(const XML_Char* el); void characters(const XML_Char* chars, int len); static void start(void* data, const XML_Char* el, const XML_Char** attr) - { - static_cast(data)->startElement(el, attr); - } + { + static_cast(data)->startElement(el, attr); + } static void end(void* data, const XML_Char* el) - { - static_cast(data)->endElement(el); - } + { + static_cast(data)->endElement(el); + } static void chars(void* data, const XML_Char* chars, int len) - { - static_cast(data)->characters(chars, len); - } + { + static_cast(data)->characters(chars, len); + } //helper routines /**Reads attribute srsName="EPSG:..." @@ -126,10 +133,10 @@ /**Source srs of the layer*/ QgsSpatialRefSys* mSrs; /**The features of the layer*/ - std::list* mFeatures; + QList &mFeatures; /**Name of geometry attribute*/ QString mGeometryAttribute; - std::set mThematicAttributes; + const QSet &mThematicAttributes; QGis::WKBTYPE* mWkbType; /**True if the request is finished*/ bool mFinished; Index: src/providers/wfs/qgswfsprovider.h =================================================================== --- src/providers/wfs/qgswfsprovider.h (Revision 9021) +++ src/providers/wfs/qgswfsprovider.h (Arbeitskopie) @@ -23,20 +23,9 @@ #include "qgsrect.h" #include "qgsspatialrefsys.h" #include "qgsvectordataprovider.h" -#include -#if GEOS_VERSION_MAJOR < 3 -#include -#include -#define GEOS_GEOM geos -#define GEOS_INDEX_STRTREE geos -#else -#include -#include -#define GEOS_GEOM geos::geom -#define GEOS_INDEX_STRTREE geos::index::strtree -#endif class QgsRect; +class QgsSpatialIndex; /**A provider reading features from a WFS server*/ class QgsWFSProvider: public QgsVectorDataProvider @@ -122,13 +111,13 @@ /**Flag if precise intersection test is needed. Otherwise, every feature is returned (even if a filter is set)*/ bool mUseIntersect; /**A spatial index for fast access to a feature subset*/ - GEOS_INDEX_STRTREE::STRtree mSpatialIndex; - /**Stores all the inserted rectangles and features. This is used to clean up the memory in the destructor*/ - std::list< std::pair > mEnvelopesAndFeatures; - /**Vector where the QgsFeature* of a query are inserted*/ - std::vector* mSelectedFeatures; + QgsSpatialIndex *mSpatialIndex; + /**Vector where the ids of the selected features are inserted*/ + QList mSelectedFeatures; /**Iterator on the feature vector for use in reset(), getNextFeature(), etc...*/ - std::vector::iterator mFeatureIterator; + QList::iterator mFeatureIterator; + /**Vector where the features are inserted*/ + QList mFeatures; /**Geometry type of the features in this layer*/ mutable QGis::WKBTYPE mWKBType; /**Source SRS*/ Index: src/providers/wfs/CMakeLists.txt =================================================================== --- src/providers/wfs/CMakeLists.txt (Revision 9021) +++ src/providers/wfs/CMakeLists.txt (Arbeitskopie) @@ -22,6 +22,7 @@ INCLUDE_DIRECTORIES ( ../../core + ../../core/spatialindex ${GEOS_INCLUDE_DIR} ${GEOS_INCLUDE_DIR}/geos ${EXPAT_INCLUDE_DIR} Index: src/providers/ogr/qgsogrprovider.h =================================================================== --- src/providers/ogr/qgsogrprovider.h (Revision 9021) +++ src/providers/ogr/qgsogrprovider.h (Arbeitskopie) @@ -19,23 +19,10 @@ #include "qgsrect.h" #include "qgsvectordataprovider.h" -#include -#if GEOS_VERSION_MAJOR < 3 -#include -#define GEOS_GEOM geos -#else -#include -#define GEOS_GEOM geos::geom -#endif - class QgsFeature; class QgsField; -typedef void *OGRDataSourceH; -typedef void *OGRSFDriverH; -typedef void *OGRLayerH; -typedef void *OGRFeatureH; -typedef void *OGRGeometryH; +#include /** \class QgsOgrProvider @@ -264,6 +251,4 @@ bool addFeature(QgsFeature& f); /**Deletes one feature*/ bool deleteFeature(int id); - //! The geometry factory - GEOS_GEOM::GeometryFactory *geometryFactory; }; Index: src/providers/ogr/qgsogrprovider.cpp =================================================================== --- src/providers/ogr/qgsogrprovider.cpp (Revision 9021) +++ src/providers/ogr/qgsogrprovider.cpp (Arbeitskopie) @@ -36,16 +36,6 @@ #include #include -//TODO Following ifndef can be removed once WIN32 GEOS support -// is fixed -#ifndef NOWIN32GEOSXXX -//XXX GEOS support on windows is broken until we can get VC++ to -// tolerate geos.h without throwing a bunch of type errors. It -// appears that the windows version of GEOS may be compiled with -// MINGW rather than VC++. -#endif - - #include "qgsapplication.h" #include "qgsdataprovider.h" #include "qgsfeature.h" @@ -134,10 +124,6 @@ valid = false; } - // create the geos objects - geometryFactory = new GEOS_GEOM::GeometryFactory(); - assert(geometryFactory!=0); - mSupportedNativeTypes.insert("Integer"); mSupportedNativeTypes.insert("Real"); mSupportedNativeTypes.insert("String"); @@ -149,7 +135,6 @@ ogrDataSource = 0; free(extent_); extent_ = 0; - delete geometryFactory; if( mSelectionRectangle ) { OGR_G_DestroyGeometry( mSelectionRectangle );