Skip to content

Commit

Permalink
Optimise QgsAbstractGeometry
Browse files Browse the repository at this point in the history
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

(cherry-picked from 49432a8)
  • Loading branch information
nyalldawson committed Oct 27, 2016
1 parent 65a379b commit 0af7331
Show file tree
Hide file tree
Showing 14 changed files with 50 additions and 2 deletions.
2 changes: 1 addition & 1 deletion python/core/geometry/qgsabstractgeometryv2.sip
Expand Up @@ -248,7 +248,7 @@ class QgsAbstractGeometryV2

/** Returns the number of nodes contained in the geometry
*/
int nCoordinates() const;
virtual int nCoordinates() const;

/** Returns the point corresponding to a specified vertex id
*/
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgscurvepolygonv2.sip
Expand Up @@ -68,6 +68,7 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
virtual bool deleteVertex( QgsVertexId position );

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

Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgsgeometrycollectionv2.sip
Expand Up @@ -67,6 +67,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual QgsRectangle boundingBox() const;

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

Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgslinestringv2.sip
Expand Up @@ -138,6 +138,7 @@ class QgsLineStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const /Factory/;

int numPoints() const;
virtual int nCoordinates() const;
void points( QList<QgsPointV2>& pt ) const;

void draw( QPainter& p ) const;
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgsmultipointv2.sip
Expand Up @@ -16,6 +16,7 @@ class QgsMultiPointV2: public QgsGeometryCollectionV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
QString asJSON( int precision = 17 ) const;

virtual int nCoordinates() const;

/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g );
Expand Down
1 change: 1 addition & 0 deletions python/core/geometry/qgspointv2.sip
Expand Up @@ -157,6 +157,7 @@ class QgsPointV2: public QgsAbstractGeometryV2
bool transformZ = false );
void transform( const QTransform& t );
virtual QList< QList< QList< QgsPointV2 > > > coordinateSequence() const;
virtual int nCoordinates() const;
virtual QgsAbstractGeometryV2* boundary() const /Factory/;

//low-level editing
Expand Down
2 changes: 1 addition & 1 deletion src/core/geometry/qgsabstractgeometryv2.h
Expand Up @@ -232,7 +232,7 @@ class CORE_EXPORT QgsAbstractGeometryV2

/** Returns the number of nodes contained in the geometry
*/
int nCoordinates() const;
virtual int nCoordinates() const;

/** Returns the point corresponding to a specified vertex id
*/
Expand Down
21 changes: 21 additions & 0 deletions src/core/geometry/qgscurvepolygonv2.cpp
Expand Up @@ -632,6 +632,27 @@ QgsCoordinateSequenceV2 QgsCurvePolygonV2::coordinateSequence() const
return mCoordinateSequence;
}

int QgsCurvePolygonV2::nCoordinates() const
{
if ( !mCoordinateSequence.isEmpty() )
return QgsAbstractGeometryV2::nCoordinates();

int count = 0;

if ( mExteriorRing )
{
count += mExteriorRing->nCoordinates();
}

QList<QgsCurveV2*>::const_iterator it = mInteriorRings.constBegin();
for ( ; it != mInteriorRings.constEnd(); ++it )
{
count += ( *it )->nCoordinates();
}

return count;
}

double QgsCurvePolygonV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
if ( !mExteriorRing )
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgscurvepolygonv2.h
Expand Up @@ -93,6 +93,7 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
virtual bool deleteVertex( QgsVertexId position ) override;

virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
virtual int nCoordinates() const override;
double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;

Expand Down
16 changes: 16 additions & 0 deletions src/core/geometry/qgsgeometrycollectionv2.cpp
Expand Up @@ -369,6 +369,22 @@ QgsCoordinateSequenceV2 QgsGeometryCollectionV2::coordinateSequence() const
return mCoordinateSequence;
}

int QgsGeometryCollectionV2::nCoordinates() const
{
if ( !mCoordinateSequence.isEmpty() )
return QgsAbstractGeometryV2::nCoordinates();

int count = 0;

QVector< QgsAbstractGeometryV2* >::const_iterator geomIt = mGeometries.constBegin();
for ( ; geomIt != mGeometries.constEnd(); ++geomIt )
{
count += ( *geomIt )->nCoordinates();
}

return count;
}

double QgsGeometryCollectionV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
{
return QgsGeometryUtils::closestSegmentFromComponents( mGeometries, QgsGeometryUtils::PART, pt, segmentPt, vertexAfter, leftOf, epsilon );
Expand Down
2 changes: 2 additions & 0 deletions src/core/geometry/qgsgeometrycollectionv2.h
Expand Up @@ -91,6 +91,8 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
virtual QgsRectangle boundingBox() const override;

virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
virtual int nCoordinates() const override;

virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
bool nextVertex( QgsVertexId& id, QgsPointV2& vertex ) const override;

Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgslinestringv2.h
Expand Up @@ -164,6 +164,7 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
virtual QgsLineStringV2* curveToLine( double tolerance = M_PI_2 / 90, SegmentationToleranceType toleranceType = MaximumAngle ) const override;

int numPoints() const override;
virtual int nCoordinates() const override { return mX.size(); }
void points( QgsPointSequenceV2 &pt ) const override;

void draw( QPainter& p ) const override;
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgsmultipointv2.h
Expand Up @@ -40,6 +40,7 @@ class CORE_EXPORT QgsMultiPointV2: public QgsGeometryCollectionV2
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
QString asJSON( int precision = 17 ) const override;

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

/** Adds a geometry and takes ownership. Returns true in case of success*/
virtual bool addGeometry( QgsAbstractGeometryV2* g ) override;
Expand Down
1 change: 1 addition & 0 deletions src/core/geometry/qgspointv2.h
Expand Up @@ -169,6 +169,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
bool transformZ = false ) override;
void transform( const QTransform& t ) override;
virtual QgsCoordinateSequenceV2 coordinateSequence() const override;
virtual int nCoordinates() const override { return 1; }
virtual QgsAbstractGeometryV2* boundary() const override;

//low-level editing
Expand Down

0 comments on commit 0af7331

Please sign in to comment.