Skip to content
Permalink
Browse files

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

(cherry-picked from 49432a8)
  • Loading branch information
nyalldawson committed Oct 27, 2016
1 parent 65a379b commit 0af733144444245bcef2b4fc8db735f87440d836
@@ -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
*/
@@ -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;

@@ -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;

@@ -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;
@@ -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 );
@@ -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
@@ -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
*/
@@ -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 )
@@ -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;

@@ -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 );
@@ -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;

@@ -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;
@@ -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;
@@ -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

0 comments on commit 0af7331

Please sign in to comment.
You can’t perform that action at this time.