Optimise calculation of QgsGeometry::vertexNrFromVertexId

By moving logic to abstract geometry subclasses so that they
can trivially retrieve the vertex number, instead of relying
on the inefficient coordinateSequence method.

Has flow on speed boosts to many geometry operations like
calculation of closest points in a geometry, which will
benefit snapping related operations.
This commit is contained in:
Nyall Dawson 2017-10-22 16:41:58 +10:00
parent 2e8e72d02d
commit 5d675720bb
21 changed files with 315 additions and 44 deletions

View File

@ -246,6 +246,19 @@ class QgsAbstractGeometry
\param p destination QPainter \param p destination QPainter
%End %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; virtual bool nextVertex( QgsVertexId &id, QgsPoint &vertex /Out/ ) const = 0;
%Docstring %Docstring
Returns next vertex id and coordinates Returns next vertex id and coordinates

View File

@ -104,6 +104,8 @@ class QgsCurve: QgsAbstractGeometry
virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex /Out/, QgsVertexId &nextVertex /Out/ ); 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; virtual bool pointAt( int node, QgsPoint &point /Out/, QgsVertexId::VertexType &type /Out/ ) const = 0;
%Docstring %Docstring

View File

@ -143,6 +143,8 @@ Adds an interior ring to the geometry (takes ownership)
virtual int nCoordinates() const; virtual int nCoordinates() const;
virtual int vertexNumberFromVertexId( QgsVertexId id ) const;
virtual bool isEmpty() 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; virtual double closestSegment( const QgsPoint &pt, QgsPoint &segmentPt /Out/, QgsVertexId &vertexAfter /Out/, bool *leftOf /Out/ = 0, double epsilon = 4 * DBL_EPSILON ) const;

View File

@ -1293,24 +1293,30 @@ Returns an extruded version of this geometry.
.. versionadded:: 2.10 .. versionadded:: 2.10
%End %End
bool vertexIdFromVertexNr( int nr, QgsVertexId &id /Out/ ) const; bool vertexIdFromVertexNr( int number, QgsVertexId &id /Out/ ) const;
%Docstring %Docstring
Calculates the vertex ID from a vertex number Calculates the vertex ID from a vertex ``number``.
\param nr vertex number
\param id reference to QgsVertexId for storing result If a matching vertex was found, it will be stored in ``id``.
:return: true if vertex was found
Returns true if vertex was found.
.. versionadded:: 2.10 .. versionadded:: 2.10
.. seealso:: vertexNrFromVertexId .. seealso:: vertexNrFromVertexId()
:rtype: bool :rtype: bool
%End %End
int vertexNrFromVertexId( QgsVertexId i ) const; int vertexNrFromVertexId( QgsVertexId id ) const;
%Docstring %Docstring
Returns the vertex number corresponding to a vertex idd Returns the vertex number corresponding to a vertex ``id``.
\param i vertex id
:return: vertex number 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 .. versionadded:: 2.10
.. seealso:: vertexIdFromVertexNr .. seealso:: vertexIdFromVertexNr()
:rtype: int :rtype: int
%End %End

View File

@ -55,6 +55,8 @@ class QgsGeometryCollection: QgsAbstractGeometry
virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex /Out/, QgsVertexId &nextVertex /Out/ ); virtual void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex /Out/, QgsVertexId &nextVertex /Out/ );
virtual int vertexNumberFromVertexId( QgsVertexId id ) const;
virtual bool addGeometry( QgsAbstractGeometry *g /Transfer/ ); virtual bool addGeometry( QgsAbstractGeometry *g /Transfer/ );
%Docstring %Docstring

View File

@ -45,6 +45,9 @@ class QgsMultiPointV2: QgsGeometryCollection
virtual QgsAbstractGeometry *boundary() const /Factory/; virtual QgsAbstractGeometry *boundary() const /Factory/;
virtual int vertexNumberFromVertexId( QgsVertexId id ) const;
protected: protected:

View File

@ -364,6 +364,8 @@ class QgsPoint: QgsAbstractGeometry
virtual int nCoordinates() const; virtual int nCoordinates() const;
virtual int vertexNumberFromVertexId( QgsVertexId id ) const;
virtual QgsAbstractGeometry *boundary() const /Factory/; virtual QgsAbstractGeometry *boundary() const /Factory/;

View File

@ -273,6 +273,18 @@ class CORE_EXPORT QgsAbstractGeometry
*/ */
virtual void draw( QPainter &p ) const = 0; 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 * Returns next vertex id and coordinates
* \param id initial value should be the starting vertex id. The next vertex id will be stored * \param id initial value should be the starting vertex id. The next vertex id will be stored

View File

@ -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 QgsAbstractGeometry *QgsCurve::boundary() const
{ {
if ( isEmpty() ) if ( isEmpty() )

View File

@ -104,6 +104,7 @@ class CORE_EXPORT QgsCurve: public QgsAbstractGeometry
QgsCoordinateSequence coordinateSequence() const override; QgsCoordinateSequence coordinateSequence() const override;
bool nextVertex( QgsVertexId &id, QgsPoint &vertex SIP_OUT ) 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; 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. * Returns the point and vertex id of a point within the curve.

View File

@ -717,6 +717,41 @@ int QgsCurvePolygon::nCoordinates() const
return count; 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 bool QgsCurvePolygon::isEmpty() const
{ {
if ( !mExteriorRing ) if ( !mExteriorRing )

View File

@ -118,6 +118,7 @@ class CORE_EXPORT QgsCurvePolygon: public QgsSurface
QgsCoordinateSequence coordinateSequence() const override; QgsCoordinateSequence coordinateSequence() const override;
int nCoordinates() const override; int nCoordinates() const override;
int vertexNumberFromVertexId( QgsVertexId id ) const override;
bool isEmpty() 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; 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;

View File

@ -334,8 +334,12 @@ QgsPointXY QgsGeometry::closestVertex( const QgsPointXY &point, int &atVertex, i
} }
sqrDist = QgsGeometryUtils::sqrDistance2D( pt, vp ); sqrDist = QgsGeometryUtils::sqrDistance2D( pt, vp );
QgsVertexId prevVertex;
QgsVertexId nextVertex;
d->geometry->adjacentVertices( id, prevVertex, nextVertex );
atVertex = vertexNrFromVertexId( id ); atVertex = vertexNrFromVertexId( id );
adjacentVertices( atVertex, beforeVertex, afterVertex ); beforeVertex = vertexNrFromVertexId( prevVertex );
afterVertex = vertexNrFromVertexId( nextVertex );
return QgsPointXY( vp.x(), vp.y() ); return QgsPointXY( vp.x(), vp.y() );
} }
@ -2451,27 +2455,7 @@ int QgsGeometry::vertexNrFromVertexId( QgsVertexId id ) const
{ {
return -1; return -1;
} }
return d->geometry->vertexNumberFromVertexId( id );
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;
} }
QString QgsGeometry::lastError() const QString QgsGeometry::lastError() const

View File

@ -1277,23 +1277,29 @@ class CORE_EXPORT QgsGeometry
void draw( QPainter &p ) const; void draw( QPainter &p ) const;
/** /**
* Calculates the vertex ID from a vertex number * Calculates the vertex ID from a vertex \a number.
* \param nr vertex number *
* \param id reference to QgsVertexId for storing result * If a matching vertex was found, it will be stored in \a id.
* \returns true if vertex was found *
* Returns true if vertex was found.
*
* \since QGIS 2.10 * \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 * Returns the vertex number corresponding to a vertex \a id.
* \param i vertex id *
* \returns vertex number * 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 * \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 * Returns an error string referring to the last error encountered

View File

@ -92,6 +92,32 @@ void QgsGeometryCollection::adjacentVertices( QgsVertexId vertex, QgsVertexId &p
mGeometries.at( vertex.part )->adjacentVertices( vertex, previousVertex, nextVertex ); 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 int QgsGeometryCollection::numGeometries() const
{ {
return mGeometries.size(); return mGeometries.size();

View File

@ -66,6 +66,7 @@ class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry
void clear() override; void clear() override;
QgsAbstractGeometry *boundary() const override SIP_FACTORY; QgsAbstractGeometry *boundary() const override SIP_FACTORY;
void adjacentVertices( QgsVertexId vertex, QgsVertexId &previousVertex SIP_OUT, QgsVertexId &nextVertex SIP_OUT ) override; 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. //! Adds a geometry and takes ownership. Returns true in case of success.
virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ); virtual bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER );

View File

@ -154,6 +154,14 @@ QgsAbstractGeometry *QgsMultiPointV2::boundary() const
return nullptr; 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 bool QgsMultiPointV2::wktOmitChildType() const
{ {
return true; return true;

View File

@ -43,6 +43,8 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollection
bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override; bool addGeometry( QgsAbstractGeometry *g SIP_TRANSFER ) override;
bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override; bool insertGeometry( QgsAbstractGeometry *g SIP_TRANSFER, int index ) override;
QgsAbstractGeometry *boundary() const override SIP_FACTORY; QgsAbstractGeometry *boundary() const override SIP_FACTORY;
int vertexNumberFromVertexId( QgsVertexId id ) const override;
#ifndef SIP_RUN #ifndef SIP_RUN

View File

@ -320,6 +320,14 @@ int QgsPoint::nCoordinates() const
return 1; return 1;
} }
int QgsPoint::vertexNumberFromVertexId( QgsVertexId id ) const
{
if ( id.vertex != 0 )
return -1;
else
return 0;
}
QgsAbstractGeometry *QgsPoint::boundary() const QgsAbstractGeometry *QgsPoint::boundary() const
{ {
return nullptr; return nullptr;

View File

@ -405,6 +405,7 @@ class CORE_EXPORT QgsPoint: public QgsAbstractGeometry
void transform( const QTransform &t ) override; void transform( const QTransform &t ) override;
QgsCoordinateSequence coordinateSequence() const override; QgsCoordinateSequence coordinateSequence() const override;
int nCoordinates() const override; int nCoordinates() const override;
int vertexNumberFromVertexId( QgsVertexId id ) const override;
QgsAbstractGeometry *boundary() const override SIP_FACTORY; QgsAbstractGeometry *boundary() const override SIP_FACTORY;
//low-level editing //low-level editing

View File

@ -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, 45 ) ), 45.0 );
QCOMPARE( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).inclination( QgsPoint( QgsWkbTypes::PointZ, 1, 2, 2 ).project( 5, 90, 135 ) ), 135.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() void TestQgsGeometry::circularString()
@ -4006,6 +4010,22 @@ void TestQgsGeometry::lineString()
vertexLine1.adjacentVertices( QgsVertexId( 0, 0, 3 ), prev, next ); vertexLine1.adjacentVertices( QgsVertexId( 0, 0, 3 ), prev, next );
QCOMPARE( prev, QgsVertexId( 0, 0, 2 ) ); QCOMPARE( prev, QgsVertexId( 0, 0, 2 ) );
QCOMPARE( next, QgsVertexId() ); 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() void TestQgsGeometry::polygon()
@ -5630,6 +5650,46 @@ void TestQgsGeometry::polygon()
p28.adjacentVertices( QgsVertexId( 0, 2, 0 ), previous, next ); p28.adjacentVertices( QgsVertexId( 0, 2, 0 ), previous, next );
QCOMPARE( previous, QgsVertexId( ) ); QCOMPARE( previous, QgsVertexId( ) );
QCOMPARE( next, QgsVertexId( ) ); QCOMPARE( next, QgsVertexId( ) );
// vertex number
QgsLineString vertexLine2;
QCOMPARE( vertexLine2.vertexNumberFromVertexId( QgsVertexId( -1, 0, 0 ) ), -1 );
QgsLineString *closedRing2 = new QgsLineString();
closedRing2->setPoints( QList<QgsPoint>() << 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() void TestQgsGeometry::triangle()
@ -10535,6 +10595,21 @@ void TestQgsGeometry::multiPoint()
QCOMPARE( prev, QgsVertexId() ); QCOMPARE( prev, QgsVertexId() );
QCOMPARE( next, 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() void TestQgsGeometry::multiLineString()
@ -14253,6 +14328,78 @@ void TestQgsGeometry::geometryCollection()
c31.adjacentVertices( QgsVertexId( 1, 0, 1 ), prev, next ); c31.adjacentVertices( QgsVertexId( 1, 0, 1 ), prev, next );
QCOMPARE( prev, QgsVertexId( 1, 0, 0 ) ); QCOMPARE( prev, QgsVertexId( 1, 0, 0 ) );
QCOMPARE( next, QgsVertexId( 1, 0, 2 ) ); 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() void TestQgsGeometry::triangle2()