Skip to content

Commit 49432a8

Browse files
committed
Optimise QgsAbstractGeometry
Make nCoordinates virtual, and provide shortcuts for some geometry types. The base method which calls coordinateSequence() is quite slow in certain circumstances. Speeds up rendering point layers by ~25%, also likely to speed up lots of geometry heavy operations throughout QGIS Refs #15752
1 parent 5798a82 commit 49432a8

14 files changed

+50
-2
lines changed

python/core/geometry/qgsabstractgeometry.sip

+1-1
Original file line numberDiff line numberDiff line change
@@ -248,7 +248,7 @@ class QgsAbstractGeometry
248248

249249
/** Returns the number of nodes contained in the geometry
250250
*/
251-
int nCoordinates() const;
251+
virtual int nCoordinates() const;
252252

253253
/** Returns the point corresponding to a specified vertex id
254254
*/

python/core/geometry/qgscurvepolygon.sip

+1
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ class QgsCurvePolygon: public QgsSurface
6868
virtual bool deleteVertex( QgsVertexId position );
6969

7070
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
71+
virtual int nCoordinates() const;
7172
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
7273
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const;
7374

python/core/geometry/qgsgeometrycollection.sip

+1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ class QgsGeometryCollection: public QgsAbstractGeometry
6767
virtual QgsRectangle boundingBox() const;
6868

6969
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
70+
virtual int nCoordinates() const;
7071
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
7172
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const;
7273

python/core/geometry/qgslinestring.sip

+1
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,7 @@ class QgsLineString: public QgsCurve
120120
virtual QgsLineString* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;
121121

122122
int numPoints() const;
123+
virtual int nCoordinates() const;
123124
void points( QList<QgsPointV2>& pt ) const;
124125

125126
void draw( QPainter& p ) const;

python/core/geometry/qgsmultipoint.sip

+1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class QgsMultiPointV2: public QgsGeometryCollection
1616
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
1717
QString asJSON( int precision = 17 ) const;
1818

19+
virtual int nCoordinates() const;
1920

2021
/** Adds a geometry and takes ownership. Returns true in case of success*/
2122
virtual bool addGeometry( QgsAbstractGeometry* g /Transfer/ );

python/core/geometry/qgspointv2.sip

+1
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class QgsPointV2: public QgsAbstractGeometry
157157
bool transformZ = false );
158158
void transform( const QTransform& t );
159159
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
160+
virtual int nCoordinates() const;
160161
virtual QgsAbstractGeometry* boundary() const /Factory/;
161162

162163
//low-level editing

src/core/geometry/qgsabstractgeometry.h

+1-1
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ class CORE_EXPORT QgsAbstractGeometry
233233

234234
/** Returns the number of nodes contained in the geometry
235235
*/
236-
int nCoordinates() const;
236+
virtual int nCoordinates() const;
237237

238238
/** Returns the point corresponding to a specified vertex id
239239
*/

src/core/geometry/qgscurvepolygon.cpp

+21
Original file line numberDiff line numberDiff line change
@@ -632,6 +632,27 @@ QgsCoordinateSequence QgsCurvePolygon::coordinateSequence() const
632632
return mCoordinateSequence;
633633
}
634634

635+
int QgsCurvePolygon::nCoordinates() const
636+
{
637+
if ( !mCoordinateSequence.isEmpty() )
638+
return QgsAbstractGeometry::nCoordinates();
639+
640+
int count = 0;
641+
642+
if ( mExteriorRing )
643+
{
644+
count += mExteriorRing->nCoordinates();
645+
}
646+
647+
QList<QgsCurve*>::const_iterator it = mInteriorRings.constBegin();
648+
for ( ; it != mInteriorRings.constEnd(); ++it )
649+
{
650+
count += ( *it )->nCoordinates();
651+
}
652+
653+
return count;
654+
}
655+
635656
double QgsCurvePolygon::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
636657
{
637658
if ( !mExteriorRing )

src/core/geometry/qgscurvepolygon.h

+1
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ class CORE_EXPORT QgsCurvePolygon: public QgsSurface
9393
virtual bool deleteVertex( QgsVertexId position ) override;
9494

9595
virtual QgsCoordinateSequence coordinateSequence() const override;
96+
virtual int nCoordinates() const override;
9697
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
9798
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;
9899

src/core/geometry/qgsgeometrycollection.cpp

+16
Original file line numberDiff line numberDiff line change
@@ -369,6 +369,22 @@ QgsCoordinateSequence QgsGeometryCollection::coordinateSequence() const
369369
return mCoordinateSequence;
370370
}
371371

372+
int QgsGeometryCollection::nCoordinates() const
373+
{
374+
if ( !mCoordinateSequence.isEmpty() )
375+
return QgsAbstractGeometry::nCoordinates();
376+
377+
int count = 0;
378+
379+
QVector< QgsAbstractGeometry* >::const_iterator geomIt = mGeometries.constBegin();
380+
for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
381+
{
382+
count += ( *geomIt )->nCoordinates();
383+
}
384+
385+
return count;
386+
}
387+
372388
double QgsGeometryCollection::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
373389
{
374390
return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::PART, pt, segmentPt, vertexAfter, leftOf, epsilon );

src/core/geometry/qgsgeometrycollection.h

+2
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,8 @@ class CORE_EXPORT QgsGeometryCollection: public QgsAbstractGeometry
9191
virtual QgsRectangle boundingBox() const override;
9292

9393
virtual QgsCoordinateSequence coordinateSequence() const override;
94+
virtual int nCoordinates() const override;
95+
9496
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
9597
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;
9698

src/core/geometry/qgslinestring.h

+1
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ class CORE_EXPORT QgsLineString: public QgsCurve
148148
virtual QgsLineString* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override;
149149

150150
int numPoints() const override;
151+
virtual int nCoordinates() const override { return mX.size(); }
151152
void points( QgsPointSequence &pt ) const override;
152153

153154
void draw( QPainter& p ) const override;

src/core/geometry/qgsmultipoint.h

+1
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollection
4040
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
4141
QString asJSON( int precision = 17 ) const override;
4242

43+
virtual int nCoordinates() const override { return mGeometries.size(); }
4344

4445
//! Adds a geometry and takes ownership. Returns true in case of success
4546
virtual bool addGeometry( QgsAbstractGeometry* g ) override;

src/core/geometry/qgspointv2.h

+1
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometry
170170
bool transformZ = false ) override;
171171
void transform( const QTransform& t ) override;
172172
virtual QgsCoordinateSequence coordinateSequence() const override;
173+
virtual int nCoordinates() const override { return 1; }
173174
virtual QgsAbstractGeometry* boundary() const override;
174175

175176
//low-level editing

0 commit comments

Comments
 (0)