diff --git a/python/core/geometry/qgsabstractgeometry.sip b/python/core/geometry/qgsabstractgeometry.sip index e121e39ee72..0fa299815ff 100644 --- a/python/core/geometry/qgsabstractgeometry.sip +++ b/python/core/geometry/qgsabstractgeometry.sip @@ -246,6 +246,19 @@ class QgsAbstractGeometry \param p destination QPainter %End + virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0; +%Docstring + Returns the vertex number corresponding to a vertex ``id``. + + The vertex numbers start at 0, so a return value of 0 corresponds + to the first vertex. + + Returns -1 if a corresponding vertex could not be found. + +.. versionadded:: 3.0 + :rtype: int +%End + virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex /Out/ ) const = 0; %Docstring Returns next vertex id and coordinates diff --git a/python/core/geometry/qgscurve.sip b/python/core/geometry/qgscurve.sip index 1cbde3f5e31..647823ce7a8 100644 --- a/python/core/geometry/qgscurve.sip +++ b/python/core/geometry/qgscurve.sip @@ -104,6 +104,8 @@ class QgsCurve: QgsAbstractGeometry virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex /Out/, QgsVertexId &nextVertex /Out/ ); + virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + virtual bool pointAt( int node, QgsPoint &point /Out/, QgsVertexId::VertexType &type /Out/ ) const = 0; %Docstring diff --git a/python/core/geometry/qgscurvepolygon.sip b/python/core/geometry/qgscurvepolygon.sip index 35f47345677..3f1fabcc915 100644 --- a/python/core/geometry/qgscurvepolygon.sip +++ b/python/core/geometry/qgscurvepolygon.sip @@ -143,6 +143,8 @@ Adds an interior ring to the geometry (takes ownership) virtual int nCoordinates() const; + virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + virtual bool isEmpty() const; virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt /Out/, QgsVertexId &vertexAfter /Out/, bool *leftOf /Out/ = 0, double epsilon = 4 * DBL_EPSILON ) const; diff --git a/python/core/geometry/qgsgeometry.sip b/python/core/geometry/qgsgeometry.sip index d2b46d6ddc2..63402702997 100644 --- a/python/core/geometry/qgsgeometry.sip +++ b/python/core/geometry/qgsgeometry.sip @@ -1293,24 +1293,30 @@ Returns an extruded version of this geometry. .. versionadded:: 2.10 %End - bool vertexIdFromVertexNr( int nr, QgsVertexId &id /Out/ ) const; + bool vertexIdFromVertexNr( int number, QgsVertexId &id /Out/ ) const; %Docstring - Calculates the vertex ID from a vertex number - \param nr vertex number - \param id reference to QgsVertexId for storing result - :return: true if vertex was found + Calculates the vertex ID from a vertex ``number``. + + If a matching vertex was found, it will be stored in ``id``. + + Returns true if vertex was found. + .. versionadded:: 2.10 -.. seealso:: vertexNrFromVertexId +.. seealso:: vertexNrFromVertexId() :rtype: bool %End - int vertexNrFromVertexId( QgsVertexId i ) const; + int vertexNrFromVertexId( QgsVertexId id ) const; %Docstring - Returns the vertex number corresponding to a vertex idd - \param i vertex id - :return: vertex number + Returns the vertex number corresponding to a vertex ``id``. + + The vertex numbers start at 0, so a return value of 0 corresponds + to the first vertex. + + Returns -1 if a corresponding vertex could not be found. + .. versionadded:: 2.10 -.. seealso:: vertexIdFromVertexNr +.. seealso:: vertexIdFromVertexNr() :rtype: int %End diff --git a/python/core/geometry/qgsgeometrycollection.sip b/python/core/geometry/qgsgeometrycollection.sip index 7f8069cfcd7..b90f2100078 100644 --- a/python/core/geometry/qgsgeometrycollection.sip +++ b/python/core/geometry/qgsgeometrycollection.sip @@ -55,6 +55,8 @@ class QgsGeometryCollection: QgsAbstractGeometry virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex /Out/, QgsVertexId &nextVertex /Out/ ); + virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + virtual bool addGeometry( QgsAbstractGeometry *g /Transfer/ ); %Docstring diff --git a/python/core/geometry/qgsmultipoint.sip b/python/core/geometry/qgsmultipoint.sip index f9281c18541..9f5cab623c9 100644 --- a/python/core/geometry/qgsmultipoint.sip +++ b/python/core/geometry/qgsmultipoint.sip @@ -45,6 +45,9 @@ class QgsMultiPointV2: QgsGeometryCollection virtual QgsAbstractGeometry *boundary() const /Factory/; + virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + + protected: diff --git a/python/core/geometry/qgspoint.sip b/python/core/geometry/qgspoint.sip index 9bffbd36204..70fda7507f8 100644 --- a/python/core/geometry/qgspoint.sip +++ b/python/core/geometry/qgspoint.sip @@ -364,6 +364,8 @@ class QgsPoint: QgsAbstractGeometry virtual int nCoordinates() const; + virtual int vertexNumberFromVertexId( QgsVertexId id ) const; + virtual QgsAbstractGeometry *boundary() const /Factory/; diff --git a/src/core/geometry/qgsabstractgeometry.h b/src/core/geometry/qgsabstractgeometry.h index 4a5418f2a6e..bb3c937c736 100644 --- a/src/core/geometry/qgsabstractgeometry.h +++ b/src/core/geometry/qgsabstractgeometry.h @@ -273,6 +273,18 @@ class CORE_EXPORT QgsAbstractGeometry */ virtual void draw( QPainter &p ) const = 0; + /** + * Returns the vertex number corresponding to a vertex \a id. + * + * The vertex numbers start at 0, so a return value of 0 corresponds + * to the first vertex. + * + * Returns -1 if a corresponding vertex could not be found. + * + * \since QGIS 3.0 + */ + virtual int vertexNumberFromVertexId( QgsVertexId id ) const = 0; + /** * Returns next vertex id and coordinates * \param id initial value should be the starting vertex id. The next vertex id will be stored diff --git a/src/core/geometry/qgscurve.cpp b/src/core/geometry/qgscurve.cpp index c500f01401f..fae2d4a45ec 100644 --- a/src/core/geometry/qgscurve.cpp +++ b/src/core/geometry/qgscurve.cpp @@ -106,6 +106,15 @@ void QgsCurve::adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex } } +int QgsCurve::vertexNumberFromVertexId( QgsVertexId id ) const +{ + if ( id.part != 0 || id.ring != 0 ) + return -1; + if ( id.vertex < 0 || id.vertex >= numPoints() ) + return -1; + return id.vertex; +} + QgsAbstractGeometry *QgsCurve::boundary() const { if ( isEmpty() ) diff --git a/src/core/geometry/qgscurve.h b/src/core/geometry/qgscurve.h index 65c22dc9682..556fc7cb8fe 100644 --- a/src/core/geometry/qgscurve.h +++ b/src/core/geometry/qgscurve.h @@ -104,6 +104,7 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry QgsCoordinateSequence coordinateSequence() const override; bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) const override; void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) override; + int vertexNumberFromVertexId( QgsVertexId id ) const override; /** * Returns the point and vertex id of a point within the curve. diff --git a/src/core/geometry/qgscurvepolygon.cpp b/src/core/geometry/qgscurvepolygon.cpp index 5af6bd4c1d1..245c46c101f 100644 --- a/src/core/geometry/qgscurvepolygon.cpp +++ b/src/core/geometry/qgscurvepolygon.cpp @@ -717,6 +717,41 @@ int QgsCurvePolygon::nCoordinates() const return count; } +int QgsCurvePolygon::vertexNumberFromVertexId( QgsVertexId id ) const +{ + if ( id.part != 0 ) + return -1; + + if ( id.ring < 0 || id.ring >= ringCount() ) + return -1; + + int number = 0; + if ( id.ring == 0 && mExteriorRing ) + { + return mExteriorRing->vertexNumberFromVertexId( QgsVertexId( 0, 0, id.vertex ) ); + } + else + { + number += mExteriorRing->numPoints(); + } + + for ( int i = 0; i < mInteriorRings.count(); ++i ) + { + if ( id.ring == i + 1 ) + { + int partNumber = mInteriorRings.at( i )->vertexNumberFromVertexId( QgsVertexId( 0, 0, id.vertex ) ); + if ( partNumber == -1 ) + return -1; + return number + partNumber; + } + else + { + number += mInteriorRings.at( i )->numPoints(); + } + } + return -1; // should not happen +} + bool QgsCurvePolygon::isEmpty() const { if ( !mExteriorRing ) diff --git a/src/core/geometry/qgscurvepolygon.h b/src/core/geometry/qgscurvepolygon.h index ab37c5b9a9a..6465dc53412 100644 --- a/src/core/geometry/qgscurvepolygon.h +++ b/src/core/geometry/qgscurvepolygon.h @@ -118,6 +118,7 @@ class CORE_EXPORT QgsCurvePolygon: public QgsSurface QgsCoordinateSequence coordinateSequence() const override; int nCoordinates() const override; + int vertexNumberFromVertexId( QgsVertexId id ) const override; bool isEmpty() const override; double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt SIP_OUT, QgsVertexId &vertexAfter SIP_OUT, bool *leftOf SIP_OUT = nullptr, double epsilon = 4 * DBL_EPSILON ) const override; diff --git a/src/core/geometry/qgsgeometry.cpp b/src/core/geometry/qgsgeometry.cpp index 3f86fb13b38..5912116ae6e 100644 --- a/src/core/geometry/qgsgeometry.cpp +++ b/src/core/geometry/qgsgeometry.cpp @@ -334,8 +334,12 @@ QgsPointXY QgsGeometry::closestVertex( const QgsPointXY &point, int &atVertex, i } sqrDist = QgsGeometryUtils::sqrDistance2D( pt, vp ); + QgsVertexId prevVertex; + QgsVertexId nextVertex; + d->geometry->adjacentVertices( id, prevVertex, nextVertex ); atVertex = vertexNrFromVertexId( id ); - adjacentVertices( atVertex, beforeVertex, afterVertex ); + beforeVertex = vertexNrFromVertexId( prevVertex ); + afterVertex = vertexNrFromVertexId( nextVertex ); return QgsPointXY( vp.x(), vp.y() ); } @@ -2451,27 +2455,7 @@ int QgsGeometry::vertexNrFromVertexId( QgsVertexId id ) const { return -1; } - - QgsCoordinateSequence coords = d->geometry->coordinateSequence(); - - int vertexCount = 0; - for ( int part = 0; part < coords.size(); ++part ) - { - const QgsRingSequence &featureCoords = coords.at( part ); - for ( int ring = 0; ring < featureCoords.size(); ++ring ) - { - const QgsPointSequence &ringCoords = featureCoords.at( ring ); - for ( int vertex = 0; vertex < ringCoords.size(); ++vertex ) - { - if ( vertex == id.vertex && ring == id.ring && part == id.part ) - { - return vertexCount; - } - ++vertexCount; - } - } - } - return -1; + return d->geometry->vertexNumberFromVertexId( id ); } QString QgsGeometry::lastError() const diff --git a/src/core/geometry/qgsgeometry.h b/src/core/geometry/qgsgeometry.h index bfc94dfa00d..f921d38ffe1 100644 --- a/src/core/geometry/qgsgeometry.h +++ b/src/core/geometry/qgsgeometry.h @@ -1277,23 +1277,29 @@ class CORE_EXPORT QgsGeometry void draw( QPainter &p ) const; /** - * Calculates the vertex ID from a vertex number - * \param nr vertex number - * \param id reference to QgsVertexId for storing result - * \returns true if vertex was found + * Calculates the vertex ID from a vertex \a number. + * + * If a matching vertex was found, it will be stored in \a id. + * + * Returns true if vertex was found. + * * \since QGIS 2.10 - * \see vertexNrFromVertexId + * \see vertexNrFromVertexId() */ - bool vertexIdFromVertexNr( int nr, QgsVertexId &id SIP_OUT ) const; + bool vertexIdFromVertexNr( int number, QgsVertexId &id SIP_OUT ) const; /** - * Returns the vertex number corresponding to a vertex idd - * \param i vertex id - * \returns vertex number + * Returns the vertex number corresponding to a vertex \a id. + * + * The vertex numbers start at 0, so a return value of 0 corresponds + * to the first vertex. + * + * Returns -1 if a corresponding vertex could not be found. + * * \since QGIS 2.10 - * \see vertexIdFromVertexNr + * \see vertexIdFromVertexNr() */ - int vertexNrFromVertexId( QgsVertexId i ) const; + int vertexNrFromVertexId( QgsVertexId id ) const; /** * Returns an error string referring to the last error encountered diff --git a/src/core/geometry/qgsgeometrycollection.cpp b/src/core/geometry/qgsgeometrycollection.cpp index 3461cd11e3c..02f27b8680a 100644 --- a/src/core/geometry/qgsgeometrycollection.cpp +++ b/src/core/geometry/qgsgeometrycollection.cpp @@ -92,6 +92,32 @@ void QgsGeometryCollection::adjacentVertices( QgsVertexId vertex, QgsVertexId &p mGeometries.at( vertex.part )->adjacentVertices( vertex, previousVertex, nextVertex ); } +int QgsGeometryCollection::vertexNumberFromVertexId( QgsVertexId id ) const +{ + if ( id.part < 0 || id.part >= mGeometries.count() ) + return -1; + + int number = 0; + int part = 0; + for ( QgsAbstractGeometry *geometry : mGeometries ) + { + if ( part == id.part ) + { + int partNumber = geometry->vertexNumberFromVertexId( QgsVertexId( 0, id.ring, id.vertex ) ); + if ( partNumber == -1 ) + return -1; + return number + partNumber; + } + else + { + number += geometry->nCoordinates(); + } + + part++; + } + return -1; // should not happen +} + int QgsGeometryCollection::numGeometries() const { return mGeometries.size(); diff --git a/src/core/geometry/qgsgeometrycollection.h b/src/core/geometry/qgsgeometrycollection.h index b7845e2dc2d..753b8bc6db7 100644 --- a/src/core/geometry/qgsgeometrycollection.h +++ b/src/core/geometry/qgsgeometrycollection.h @@ -66,6 +66,7 @@ class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry void clear() override; QgsAbstractGeometry *boundary() const override SIP_FACTORY; void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) override; + int vertexNumberFromVertexId( QgsVertexId id ) const override; //! Adds a geometry and takes ownership. Returns true in case of success. virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ); diff --git a/src/core/geometry/qgsmultipoint.cpp b/src/core/geometry/qgsmultipoint.cpp index 97b6e3733e3..c3e62fa5775 100644 --- a/src/core/geometry/qgsmultipoint.cpp +++ b/src/core/geometry/qgsmultipoint.cpp @@ -154,6 +154,14 @@ QgsAbstractGeometry *QgsMultiPointV2::boundary() const return nullptr; } +int QgsMultiPointV2::vertexNumberFromVertexId( QgsVertexId id ) const +{ + if ( id.part < 0 || id.part >= mGeometries.count() || id.vertex != 0 || id.ring != 0 ) + return -1; + + return id.part; // can shortcut the calculation, since each part will have 1 vertex +} + bool QgsMultiPointV2::wktOmitChildType() const { return true; diff --git a/src/core/geometry/qgsmultipoint.h b/src/core/geometry/qgsmultipoint.h index d83e16bd86d..04084dc1aa9 100644 --- a/src/core/geometry/qgsmultipoint.h +++ b/src/core/geometry/qgsmultipoint.h @@ -43,6 +43,8 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollection bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override; bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override; QgsAbstractGeometry *boundary() const override SIP_FACTORY; + int vertexNumberFromVertexId( QgsVertexId id ) const override; + #ifndef SIP_RUN diff --git a/src/core/geometry/qgspoint.cpp b/src/core/geometry/qgspoint.cpp index 6e5c0fefc69..bfefc74ea4f 100644 --- a/src/core/geometry/qgspoint.cpp +++ b/src/core/geometry/qgspoint.cpp @@ -320,6 +320,14 @@ int QgsPoint::nCoordinates() const return 1; } +int QgsPoint::vertexNumberFromVertexId( QgsVertexId id ) const +{ + if ( id.vertex != 0 ) + return -1; + else + return 0; +} + QgsAbstractGeometry *QgsPoint::boundary() const { return nullptr; diff --git a/src/core/geometry/qgspoint.h b/src/core/geometry/qgspoint.h index e1ee6e61779..16d8f1581f2 100644 --- a/src/core/geometry/qgspoint.h +++ b/src/core/geometry/qgspoint.h @@ -405,6 +405,7 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry void transform( const QTransform &t ) override; QgsCoordinateSequence coordinateSequence() const override; int nCoordinates() const override; + int vertexNumberFromVertexId( QgsVertexId id ) const override; QgsAbstractGeometry *boundary() const override SIP_FACTORY; //low-level editing diff --git a/tests/src/core/testqgsgeometry.cpp b/tests/src/core/testqgsgeometry.cpp index 45a5d1fd4c2..aae762b54c0 100644 --- a/tests/src/core/testqgsgeometry.cpp +++ b/tests/src/core/testqgsgeometry.cpp @@ -1028,6 +1028,10 @@ void TestQgsGeometry::point() QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 45 ) ), 45.0 ); QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 135 ) ), 135.0 ); + // vertex number + QCOMPARE( QgsPoint( 1, 2 ).vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( QgsPoint( 1, 2 ).vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), -1 ); + QCOMPARE( QgsPoint( 1, 2 ).vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); } void TestQgsGeometry::circularString() @@ -4006,6 +4010,22 @@ void TestQgsGeometry::lineString() vertexLine1.adjacentVertices( QgsVertexId( 0, 0, 3 ), prev, next ); QCOMPARE( prev, QgsVertexId( 0, 0, 2 ) ); QCOMPARE( next, QgsVertexId() ); + + // vertex number + QgsLineString vertexLine2; + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + vertexLine2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 111, 112 ) ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, -1, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), -1 ); } void TestQgsGeometry::polygon() @@ -5630,6 +5650,46 @@ void TestQgsGeometry::polygon() p28.adjacentVertices( QgsVertexId( 0, 2, 0 ), previous, next ); QCOMPARE( previous, QgsVertexId( ) ); QCOMPARE( next, QgsVertexId( ) ); + + // vertex number + QgsLineString vertexLine2; + QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + + QgsLineString *closedRing2 = new QgsLineString(); + closedRing2->setPoints( QList() << QgsPoint( 1, 1 ) << QgsPoint( 1, 2 ) << QgsPoint( 2, 2 ) << QgsPoint( 2, 1 ) << QgsPoint( 1, 1 ) ); + QgsPolygonV2 p29; + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, -1, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), -1 ); + p29.setExteriorRing( closedRing2 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, -1, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), 3 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 4 ) ), 4 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 5 ) ), -1 ); + p29.addInteriorRing( closedRing2->clone() ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), 3 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 4 ) ), 4 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 0, 5 ) ), -1 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), 5 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 1 ) ), 6 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 2 ) ), 7 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 3 ) ), 8 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 4 ) ), 9 ); + QCOMPARE( p29.vertexNumberFromVertexId( QgsVertexId( 0, 1, 5 ) ), -1 ); } void TestQgsGeometry::triangle() @@ -10535,6 +10595,21 @@ void TestQgsGeometry::multiPoint() QCOMPARE( prev, QgsVertexId() ); QCOMPARE( next, QgsVertexId() ); + // vertex number + QgsMultiPointV2 c22; + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + c22.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 10, 0, 4, 8 ) ); + c22.addGeometry( new QgsPoint( QgsWkbTypes::PointZM, 9, 1, 4, 4 ) ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 2, 0, 0 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), 1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( 1, 0, 1 ) ), -1 ); + QCOMPARE( c22.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); } void TestQgsGeometry::multiLineString() @@ -14253,6 +14328,78 @@ void TestQgsGeometry::geometryCollection() c31.adjacentVertices( QgsVertexId( 1, 0, 1 ), prev, next ); QCOMPARE( prev, QgsVertexId( 1, 0, 0 ) ); QCOMPARE( next, QgsVertexId( 1, 0, 2 ) ); + + + // vertex number + QgsGeometryCollection c32; + QgsLineString vertexLine2; + vertexLine2.setPoints( QgsPointSequence() << QgsPoint( 1, 2 ) << QgsPoint( 11, 12 ) << QgsPoint( 111, 112 ) ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, -1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), -1 ); + c32.addGeometry( vertexLine2.clone() ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, -1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, -1 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), -1 ); + c32.addGeometry( vertexLine2.clone() ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), 3 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 1 ) ), 4 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 2 ) ), 5 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 3 ) ), -1 ); + QgsPolygonV2 polyPart; + vertexLine2.close(); + polyPart.setExteriorRing( vertexLine2.clone() ); + c32.addGeometry( polyPart.clone() ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 0 ) ), 0 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 1 ) ), 1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 2 ) ), 2 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 0, 0, 3 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 0 ) ), 3 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 1 ) ), 4 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 2 ) ), 5 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 1, 0, 3 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, -1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, -1 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 0 ) ), 6 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 1 ) ), 7 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 2 ) ), 8 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 3 ) ), 9 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 4 ) ), -1 ); + polyPart.addInteriorRing( vertexLine2.clone() ); + c32.addGeometry( polyPart.clone() ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 0 ) ), 6 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 1 ) ), 7 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 2 ) ), 8 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 3 ) ), 9 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 2, 0, 4 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, -1, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 2, 0 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 0, 0 ) ), 10 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 0, 1 ) ), 11 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 0, 2 ) ), 12 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 0, 3 ) ), 13 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 0, 4 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 1, 0 ) ), 14 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 1, 1 ) ), 15 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 1, 2 ) ), 16 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 1, 3 ) ), 17 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 1, 4 ) ), -1 ); + QCOMPARE( c32.vertexNumberFromVertexId( QgsVertexId( 3, 2, 0 ) ), -1 ); } void TestQgsGeometry::triangle2()