From 0e55b3bf0f388ef3806c8dd489fdfa6ccf3a4e96 Mon Sep 17 00:00:00 2001 From: Marco Hugentobler Date: Fri, 29 May 2015 17:59:52 +0200 Subject: [PATCH] Fix loading of curved multitypes --- .../core/geometry/qgsabstractgeometryv2.sip | 4 ++ python/core/geometry/qgscircularstringv2.sip | 1 + python/core/geometry/qgscompoundcurvev2.sip | 2 + python/core/geometry/qgscurvepolygonv2.sip | 3 ++ python/core/geometry/qgscurvev2.sip | 3 ++ .../core/geometry/qgsgeometrycollectionv2.sip | 2 + python/core/geometry/qgsmulticurvev2.sip | 2 + python/core/geometry/qgsmultisurfacev2.sip | 3 ++ src/core/geometry/qgsabstractgeometryv2.h | 3 ++ src/core/geometry/qgscircularstringv2.h | 2 + src/core/geometry/qgscompoundcurvev2.cpp | 32 ++++++-------- src/core/geometry/qgscompoundcurvev2.h | 2 + src/core/geometry/qgscurvepolygonv2.cpp | 23 ++++++++++ src/core/geometry/qgscurvepolygonv2.h | 3 ++ src/core/geometry/qgscurvev2.cpp | 6 +++ src/core/geometry/qgscurvev2.h | 3 ++ src/core/geometry/qgsgeometry.cpp | 44 +++---------------- src/core/geometry/qgsgeometrycollectionv2.cpp | 13 ++++++ src/core/geometry/qgsgeometrycollectionv2.h | 2 + src/core/geometry/qgsmulticurvev2.cpp | 11 +++++ src/core/geometry/qgsmulticurvev2.h | 2 + src/core/geometry/qgsmultisurfacev2.cpp | 11 +++++ src/core/geometry/qgsmultisurfacev2.h | 3 ++ 23 files changed, 123 insertions(+), 57 deletions(-) diff --git a/python/core/geometry/qgsabstractgeometryv2.sip b/python/core/geometry/qgsabstractgeometryv2.sip index 8a7da284616..e716abc9319 100644 --- a/python/core/geometry/qgsabstractgeometryv2.sip +++ b/python/core/geometry/qgsabstractgeometryv2.sip @@ -112,4 +112,8 @@ class QgsAbstractGeometryV2 /**Length for linear geometries,perimeter for area geometries*/ virtual double length() const; virtual double area() const; + + virtual bool hasCurvedSegments() const; + /**Returns a geometry without curves. Caller takes ownership*/ + virtual QgsAbstractGeometryV2* segmentize() const /Factory/; }; diff --git a/python/core/geometry/qgscircularstringv2.sip b/python/core/geometry/qgscircularstringv2.sip index f8dbb3cb70d..6effe45b269 100644 --- a/python/core/geometry/qgscircularstringv2.sip +++ b/python/core/geometry/qgscircularstringv2.sip @@ -52,4 +52,5 @@ class QgsCircularStringV2: public QgsCurveV2 bool pointAt( int i, QgsPointV2& vertex, QgsVertexId::VertexType& type ) const; void sumUpArea( double& sum ) const; + bool hasCurvedSegments() const; }; diff --git a/python/core/geometry/qgscompoundcurvev2.sip b/python/core/geometry/qgscompoundcurvev2.sip index 4af3e7bb8c8..382ff107ec0 100644 --- a/python/core/geometry/qgscompoundcurvev2.sip +++ b/python/core/geometry/qgscompoundcurvev2.sip @@ -58,4 +58,6 @@ class QgsCompoundCurveV2: public QgsCurveV2 bool pointAt( int i, QgsPointV2& vertex, QgsVertexId::VertexType& type ) const; void sumUpArea( double& sum ) const; + + bool hasCurvedSegments() const; }; diff --git a/python/core/geometry/qgscurvepolygonv2.sip b/python/core/geometry/qgscurvepolygonv2.sip index edf140623a4..0c2001315fa 100644 --- a/python/core/geometry/qgscurvepolygonv2.sip +++ b/python/core/geometry/qgscurvepolygonv2.sip @@ -59,4 +59,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2 virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord /Out/ ) const; double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const; bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const; + + bool hasCurvedSegments() const; + QgsAbstractGeometryV2* segmentize() const /Factory/; }; diff --git a/python/core/geometry/qgscurvev2.sip b/python/core/geometry/qgscurvev2.sip index 86c69718ac2..91718d9db0b 100644 --- a/python/core/geometry/qgscurvev2.sip +++ b/python/core/geometry/qgscurvev2.sip @@ -23,4 +23,7 @@ class QgsCurveV2: public QgsAbstractGeometryV2 virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord /Out/ ) const; virtual bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const; virtual bool pointAt( int i, QgsPointV2& vertex, QgsVertexId::VertexType& type ) const = 0; + + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const /Factory/; }; diff --git a/python/core/geometry/qgsgeometrycollectionv2.sip b/python/core/geometry/qgsgeometrycollectionv2.sip index 55772a17562..2dcdaf63c9a 100644 --- a/python/core/geometry/qgsgeometrycollectionv2.sip +++ b/python/core/geometry/qgsgeometrycollectionv2.sip @@ -49,4 +49,6 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2 virtual double length() const; virtual double area() const; + + bool hasCurvedSegments() const; }; diff --git a/python/core/geometry/qgsmulticurvev2.sip b/python/core/geometry/qgsmulticurvev2.sip index 22fa3ec9ada..42c1fe4a94c 100644 --- a/python/core/geometry/qgsmulticurvev2.sip +++ b/python/core/geometry/qgsmulticurvev2.sip @@ -20,4 +20,6 @@ class QgsMultiCurveV2: public QgsGeometryCollectionV2 /**Adds a geometry and takes ownership. Returns true in case of success*/ virtual bool addGeometry( QgsAbstractGeometryV2* g ); + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const /Factory/; }; diff --git a/python/core/geometry/qgsmultisurfacev2.sip b/python/core/geometry/qgsmultisurfacev2.sip index e4e86de888b..96e5e5d3d83 100644 --- a/python/core/geometry/qgsmultisurfacev2.sip +++ b/python/core/geometry/qgsmultisurfacev2.sip @@ -19,4 +19,7 @@ class QgsMultiSurfaceV2: public QgsGeometryCollectionV2 /**Adds a geometry and takes ownership. Returns true in case of success*/ virtual bool addGeometry( QgsAbstractGeometryV2* g ); + + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const /Factory/; }; diff --git a/src/core/geometry/qgsabstractgeometryv2.h b/src/core/geometry/qgsabstractgeometryv2.h index 00d0e17f56d..7cfe85ecf12 100644 --- a/src/core/geometry/qgsabstractgeometryv2.h +++ b/src/core/geometry/qgsabstractgeometryv2.h @@ -131,6 +131,9 @@ class CORE_EXPORT QgsAbstractGeometryV2 bool isEmpty() const; + virtual bool hasCurvedSegments() const { return false; } + /**Returns a geometry without curves. Caller takes ownership*/ + virtual QgsAbstractGeometryV2* segmentize() const { return clone(); } protected: QgsWKBTypes::Type mWkbType; diff --git a/src/core/geometry/qgscircularstringv2.h b/src/core/geometry/qgscircularstringv2.h index 9703743c270..048b0c4c6ac 100644 --- a/src/core/geometry/qgscircularstringv2.h +++ b/src/core/geometry/qgscircularstringv2.h @@ -72,6 +72,8 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2 void sumUpArea( double& sum ) const override; + bool hasCurvedSegments() const override { return true; } + private: QVector mX; QVector mY; diff --git a/src/core/geometry/qgscompoundcurvev2.cpp b/src/core/geometry/qgscompoundcurvev2.cpp index 61f43d2cb09..e34ac10764c 100644 --- a/src/core/geometry/qgscompoundcurvev2.cpp +++ b/src/core/geometry/qgscompoundcurvev2.cpp @@ -333,24 +333,7 @@ QgsLineStringV2* QgsCompoundCurveV2::curveToLine() const line->append( currentLine ); delete currentLine; } -#if 0 - if ( curveIt == mCurves.constBegin() ) - { - line = ( *curveIt )->curveToLine(); - if ( !line ) - { - return 0; - } - } - else - { - currentLine = ( *curveIt )->curveToLine(); - line->append( currentLine ); - delete currentLine; - } -} -#endif //0 -return line; + return line; } const QgsCurveV2* QgsCompoundCurveV2::curveAt( int i ) const @@ -568,3 +551,16 @@ void QgsCompoundCurveV2::close() addVertex( startPoint() ); } +bool QgsCompoundCurveV2::hasCurvedSegments() const +{ + QList< QgsCurveV2* >::const_iterator curveIt = mCurves.constBegin(); + for ( ; curveIt != mCurves.constEnd(); ++curveIt ) + { + if (( *curveIt )->hasCurvedSegments() ) + { + return true; + } + } + return false; +} + diff --git a/src/core/geometry/qgscompoundcurvev2.h b/src/core/geometry/qgscompoundcurvev2.h index 2348bdc278b..2f9d02c49a1 100644 --- a/src/core/geometry/qgscompoundcurvev2.h +++ b/src/core/geometry/qgscompoundcurvev2.h @@ -78,6 +78,8 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2 /**Appends first point if not already closed*/ void close(); + bool hasCurvedSegments() const override; + private: QList< QgsCurveV2* > mCurves; /**Turns a vertex id for the compound curve into one or more ids for the subcurves diff --git a/src/core/geometry/qgscurvepolygonv2.cpp b/src/core/geometry/qgscurvepolygonv2.cpp index 2bf7712a67b..e36be38cf0e 100644 --- a/src/core/geometry/qgscurvepolygonv2.cpp +++ b/src/core/geometry/qgscurvepolygonv2.cpp @@ -636,3 +636,26 @@ bool QgsCurvePolygonV2::deleteVertex( const QgsVertexId& vId ) } return success; } + +bool QgsCurvePolygonV2::hasCurvedSegments() const +{ + if ( mExteriorRing && mExteriorRing->hasCurvedSegments() ) + { + return true; + } + + QList::const_iterator it = mInteriorRings.constBegin(); + for ( ; it != mInteriorRings.constEnd(); ++it ) + { + if (( *it )->hasCurvedSegments() ) + { + return true; + } + } + return false; +} + +QgsAbstractGeometryV2* QgsCurvePolygonV2::segmentize() const +{ + return toPolygon(); +} diff --git a/src/core/geometry/qgscurvepolygonv2.h b/src/core/geometry/qgscurvepolygonv2.h index e3eb82bc7c8..a6113ec1b3f 100644 --- a/src/core/geometry/qgscurvepolygonv2.h +++ b/src/core/geometry/qgscurvepolygonv2.h @@ -80,6 +80,9 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2 double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override; bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override; + bool hasCurvedSegments() const override; + QgsAbstractGeometryV2* segmentize() const override; + protected: QgsCurveV2* mExteriorRing; diff --git a/src/core/geometry/qgscurvev2.cpp b/src/core/geometry/qgscurvev2.cpp index f7401de2e98..cdabe4a3a96 100644 --- a/src/core/geometry/qgscurvev2.cpp +++ b/src/core/geometry/qgscurvev2.cpp @@ -16,6 +16,7 @@ ***************************************************************************/ #include "qgscurvev2.h" +#include "qgslinestringv2.h" QgsCurveV2::QgsCurveV2(): QgsAbstractGeometryV2() {} @@ -79,3 +80,8 @@ double QgsCurveV2::area() const sumUpArea( area ); return qAbs( area ); } + +QgsAbstractGeometryV2* QgsCurveV2::segmentize() const +{ + return curveToLine(); +} diff --git a/src/core/geometry/qgscurvev2.h b/src/core/geometry/qgscurvev2.h index 06d2f27e692..f9521bd3787 100644 --- a/src/core/geometry/qgscurvev2.h +++ b/src/core/geometry/qgscurvev2.h @@ -46,6 +46,9 @@ class CORE_EXPORT QgsCurveV2: public QgsAbstractGeometryV2 virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const override; virtual bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override; virtual bool pointAt( int i, QgsPointV2& vertex, QgsVertexId::VertexType& type ) const = 0; + + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const override; }; #endif // QGSCURVEV2_H diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 71c4a6173f4..729ae59da40 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -1485,42 +1485,10 @@ void QgsGeometry::convertToStraightSegment() } detach(); - QgsWKBTypes::Type flatGeomType = QgsWKBTypes::flatType( d->geometry->wkbType() ); - if ( flatGeomType == QgsWKBTypes::CompoundCurve || flatGeomType == QgsWKBTypes::CircularString ) - { - QgsCurveV2* curve = dynamic_cast( d->geometry ); - if ( !curve ) - { - return ; - } - d->geometry = curve->curveToLine(); - removeWkbGeos(); - delete curve; - } - else if ( flatGeomType == QgsWKBTypes::CurvePolygon ) - { - QgsCurvePolygonV2* curvePolygon = dynamic_cast( d->geometry ); - if ( !curvePolygon ) - { - return; - } - d->geometry = curvePolygon->toPolygon(); - removeWkbGeos(); - delete curvePolygon; - } - else //no segmentation needed - { - return; - } - - //compoundcurve / circularstring /multicurve ? - - //curve polygon / multisurface? - delete[] mWkb; - mWkb = 0; - mWkbSize = 0; - GEOSGeom_destroy( mGeos ); - mGeos = 0; + QgsAbstractGeometryV2* straightGeom = d->geometry->segmentize(); + delete d->geometry; + d->geometry = straightGeom; + removeWkbGeos(); } bool QgsGeometry::requiresConversionToStraightSegments() const @@ -1530,9 +1498,7 @@ bool QgsGeometry::requiresConversionToStraightSegments() const return false; } - QgsWKBTypes::Type flatGeomType = QgsWKBTypes::flatType( d->geometry->wkbType() ); - return ( flatGeomType == QgsWKBTypes::CompoundCurve || flatGeomType == QgsWKBTypes::CircularString - || flatGeomType == QgsWKBTypes::CurvePolygon ); + return d->geometry->hasCurvedSegments(); } int QgsGeometry::transform( const QgsCoordinateTransform& ct ) diff --git a/src/core/geometry/qgsgeometrycollectionv2.cpp b/src/core/geometry/qgsgeometrycollectionv2.cpp index 220a5e71db8..c8c77aa0f74 100644 --- a/src/core/geometry/qgsgeometrycollectionv2.cpp +++ b/src/core/geometry/qgsgeometrycollectionv2.cpp @@ -446,3 +446,16 @@ bool QgsGeometryCollectionV2::fromCollectionWkt( const QString &wkt, const QList qDeleteAll( subtypes ); return true; } + +bool QgsGeometryCollectionV2::hasCurvedSegments() const +{ + QVector< QgsAbstractGeometryV2* >::const_iterator it = mGeometries.constBegin(); + for ( ; it != mGeometries.constEnd(); ++it ) + { + if (( *it )->hasCurvedSegments() ) + { + return true; + } + } + return false; +} diff --git a/src/core/geometry/qgsgeometrycollectionv2.h b/src/core/geometry/qgsgeometrycollectionv2.h index d47c51a2471..334a06d09be 100644 --- a/src/core/geometry/qgsgeometrycollectionv2.h +++ b/src/core/geometry/qgsgeometrycollectionv2.h @@ -70,6 +70,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2 virtual double length() const override; virtual double area() const override; + bool hasCurvedSegments() const override; + protected: QVector< QgsAbstractGeometryV2* > mGeometries; void removeGeometries(); diff --git a/src/core/geometry/qgsmulticurvev2.cpp b/src/core/geometry/qgsmulticurvev2.cpp index 3a2133aca65..c3a3f9224e6 100644 --- a/src/core/geometry/qgsmulticurvev2.cpp +++ b/src/core/geometry/qgsmulticurvev2.cpp @@ -106,3 +106,14 @@ bool QgsMultiCurveV2::addGeometry( QgsAbstractGeometryV2* g ) setZMTypeFromSubGeometry( g, QgsWKBTypes::MultiCurve ); return QgsGeometryCollectionV2::addGeometry( g ); } + +QgsAbstractGeometryV2* QgsMultiCurveV2::segmentize() const +{ + QgsMultiCurveV2* c = new QgsMultiCurveV2(); + QVector< QgsAbstractGeometryV2* >::const_iterator geomIt = mGeometries.constBegin(); + for ( ; geomIt != mGeometries.constEnd(); ++geomIt ) + { + c->addGeometry(( *geomIt )->segmentize() ); + } + return c; +} diff --git a/src/core/geometry/qgsmulticurvev2.h b/src/core/geometry/qgsmulticurvev2.h index 282ca51a035..1cdcb27e81f 100644 --- a/src/core/geometry/qgsmulticurvev2.h +++ b/src/core/geometry/qgsmulticurvev2.h @@ -36,6 +36,8 @@ class CORE_EXPORT QgsMultiCurveV2: public QgsGeometryCollectionV2 /**Adds a geometry and takes ownership. Returns true in case of success*/ virtual bool addGeometry( QgsAbstractGeometryV2* g ) override; + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const override; }; #endif // QGSMULTICURVEV2_H diff --git a/src/core/geometry/qgsmultisurfacev2.cpp b/src/core/geometry/qgsmultisurfacev2.cpp index bbb7f1c8e8c..bd390294b0e 100644 --- a/src/core/geometry/qgsmultisurfacev2.cpp +++ b/src/core/geometry/qgsmultisurfacev2.cpp @@ -126,3 +126,14 @@ bool QgsMultiSurfaceV2::addGeometry( QgsAbstractGeometryV2* g ) setZMTypeFromSubGeometry( g, QgsWKBTypes::MultiSurface ); return QgsGeometryCollectionV2::addGeometry( g ); } + +QgsAbstractGeometryV2* QgsMultiSurfaceV2::segmentize() const +{ + QgsMultiSurfaceV2* c = new QgsMultiSurfaceV2(); + QVector< QgsAbstractGeometryV2* >::const_iterator geomIt = mGeometries.constBegin(); + for ( ; geomIt != mGeometries.constEnd(); ++geomIt ) + { + c->addGeometry(( *geomIt )->segmentize() ); + } + return c; +} diff --git a/src/core/geometry/qgsmultisurfacev2.h b/src/core/geometry/qgsmultisurfacev2.h index c4641b9a611..13b540dc07c 100644 --- a/src/core/geometry/qgsmultisurfacev2.h +++ b/src/core/geometry/qgsmultisurfacev2.h @@ -36,6 +36,9 @@ class CORE_EXPORT QgsMultiSurfaceV2: public QgsGeometryCollectionV2 /**Adds a geometry and takes ownership. Returns true in case of success*/ virtual bool addGeometry( QgsAbstractGeometryV2* g ) override; + + /**Returns a geometry without curves. Caller takes ownership*/ + QgsAbstractGeometryV2* segmentize() const override; }; #endif // QGSMULTISURFACEV2_H