mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-14 00:07:35 -04:00
Optimise storage/calculation of geometry bounding boxes
- removes storage of bounding box from QgsPointV2 (gives significant decrease in size of object) - more efficient calculation of bounding box for linestrings Additionally, this commit moves the bounding box invalidation to a virtual QgsAbstractGeometryV2::clearCache() method, so that other non-bounding box caches can also be cleared when the geometry is modified.
This commit is contained in:
parent
fef9c93e48
commit
50f01a2ac8
@ -85,12 +85,7 @@ class QgsAbstractGeometryV2
|
||||
|
||||
/** Returns the minimal bounding box for the geometry
|
||||
*/
|
||||
QgsRectangle boundingBox() const;
|
||||
|
||||
/** Calculates the minimal bounding box for the geometry. Derived classes should override this method
|
||||
* to return the correct bounding box.
|
||||
*/
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual QgsRectangle boundingBox() const = 0;
|
||||
|
||||
//mm-sql interface
|
||||
/** Returns the inherent dimension of the geometry. For example, this is 0 for a point geometry,
|
||||
@ -373,4 +368,13 @@ class QgsAbstractGeometryV2
|
||||
/** Updates the geometry type based on whether sub geometries contain z or m values.
|
||||
*/
|
||||
void setZMTypeFromSubGeometry( const QgsAbstractGeometryV2* subggeom, QgsWKBTypes::Type baseGeomType );
|
||||
|
||||
/** Default calculator for the minimal bounding box for the geometry. Derived classes should override this method
|
||||
* if a more efficient bounding box calculation is available.
|
||||
*/
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
/** Clears any cached parameters associated with the geometry, eg bounding boxes
|
||||
*/
|
||||
virtual void clearCache() const;
|
||||
};
|
||||
|
@ -16,8 +16,6 @@ class QgsCircularStringV2: public QgsCurveV2
|
||||
virtual QgsCircularStringV2* clone() const;
|
||||
virtual void clear();
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
@ -109,6 +107,10 @@ class QgsCircularStringV2: public QgsCurveV2
|
||||
virtual bool dropZValue();
|
||||
virtual bool dropMValue();
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
private:
|
||||
//helper methods for curveToLine
|
||||
void segmentize( const QgsPointV2& p1, const QgsPointV2& p2, const QgsPointV2& p3, QList<QgsPointV2>& points ) const;
|
||||
|
@ -18,8 +18,6 @@ class QgsCompoundCurveV2: public QgsCurveV2
|
||||
virtual QgsCompoundCurveV2* clone() const;
|
||||
virtual void clear();
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
@ -96,4 +94,8 @@ class QgsCompoundCurveV2: public QgsCurveV2
|
||||
virtual bool dropZValue();
|
||||
virtual bool dropMValue();
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
};
|
||||
|
@ -15,8 +15,6 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
virtual QgsCurvePolygonV2* clone() const;
|
||||
void clear();
|
||||
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb );
|
||||
virtual bool fromWkt( const QString& wkt );
|
||||
|
||||
@ -88,4 +86,8 @@ class QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
virtual bool addMValue( double mValue = 0 );
|
||||
virtual bool dropZValue();
|
||||
virtual bool dropMValue();
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
};
|
||||
|
@ -81,6 +81,8 @@ class QgsCurveV2: public QgsAbstractGeometryV2
|
||||
virtual int partCount() const;
|
||||
virtual QgsPointV2 vertexAt( QgsVertexId id ) const;
|
||||
|
||||
virtual QgsRectangle boundingBox() const;
|
||||
|
||||
/** Drops any Z dimensions which exist in the geometry.
|
||||
* @returns true if Z values were present and have been removed
|
||||
* @see dropMValue()
|
||||
@ -94,4 +96,9 @@ class QgsCurveV2: public QgsAbstractGeometryV2
|
||||
* @note added in QGIS 2.14
|
||||
*/
|
||||
virtual bool dropMValue() = 0;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void clearCache() const;
|
||||
|
||||
};
|
||||
|
@ -66,7 +66,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
|
||||
QString asJSON( int precision = 17 ) const;
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual QgsRectangle boundingBox() const;
|
||||
|
||||
virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord /Out/ ) const;
|
||||
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const;
|
||||
@ -113,4 +113,7 @@ class QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
*/
|
||||
bool fromCollectionWkt( const QString &wkt, const QList<QgsAbstractGeometryV2*>& subtypes, const QString& defaultChildWkbType = QString() );
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual void clearCache() const;
|
||||
|
||||
};
|
||||
|
@ -162,4 +162,8 @@ class QgsLineStringV2: public QgsCurveV2
|
||||
|
||||
virtual bool convertTo( QgsWKBTypes::Type type );
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
};
|
||||
|
@ -139,6 +139,7 @@ class QgsPointV2: public QgsAbstractGeometryV2
|
||||
QPointF toQPointF() const;
|
||||
|
||||
//implementation of inherited methods
|
||||
virtual QgsRectangle boundingBox() const;
|
||||
virtual QString geometryType() const;
|
||||
virtual int dimension() const;
|
||||
virtual QgsPointV2* clone() const /Factory/;
|
||||
@ -151,7 +152,6 @@ class QgsPointV2: public QgsAbstractGeometryV2
|
||||
QDomElement asGML2( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
|
||||
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const;
|
||||
QString asJSON( int precision = 17 ) const;
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
void draw( QPainter& p ) const;
|
||||
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform );
|
||||
void transform( const QTransform& t );
|
||||
|
@ -7,4 +7,11 @@ class QgsSurfaceV2: public QgsAbstractGeometryV2
|
||||
public:
|
||||
|
||||
virtual QgsPolygonV2* surfaceToPolygon() const = 0;
|
||||
|
||||
virtual QgsRectangle boundingBox() const;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void clearCache() const;
|
||||
|
||||
};
|
||||
|
@ -45,15 +45,6 @@ QgsAbstractGeometryV2& QgsAbstractGeometryV2::operator=( const QgsAbstractGeomet
|
||||
return *this;
|
||||
}
|
||||
|
||||
QgsRectangle QgsAbstractGeometryV2::boundingBox() const
|
||||
{
|
||||
if ( mBoundingBox.isNull() )
|
||||
{
|
||||
mBoundingBox = calculateBoundingBox();
|
||||
}
|
||||
return mBoundingBox;
|
||||
}
|
||||
|
||||
bool QgsAbstractGeometryV2::is3D() const
|
||||
{
|
||||
return QgsWKBTypes::hasZ( mWkbType );
|
||||
|
@ -56,12 +56,7 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
||||
|
||||
/** Returns the minimal bounding box for the geometry
|
||||
*/
|
||||
QgsRectangle boundingBox() const;
|
||||
|
||||
/** Calculates the minimal bounding box for the geometry. Derived classes should override this method
|
||||
* to return the correct bounding box.
|
||||
*/
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
virtual QgsRectangle boundingBox() const = 0;
|
||||
|
||||
//mm-sql interface
|
||||
/** Returns the inherent dimension of the geometry. For example, this is 0 for a point geometry,
|
||||
@ -353,11 +348,20 @@ class CORE_EXPORT QgsAbstractGeometryV2
|
||||
|
||||
protected:
|
||||
QgsWKBTypes::Type mWkbType;
|
||||
mutable QgsRectangle mBoundingBox;
|
||||
|
||||
/** Updates the geometry type based on whether sub geometries contain z or m values.
|
||||
*/
|
||||
void setZMTypeFromSubGeometry( const QgsAbstractGeometryV2* subggeom, QgsWKBTypes::Type baseGeomType );
|
||||
|
||||
/** Default calculator for the minimal bounding box for the geometry. Derived classes should override this method
|
||||
* if a more efficient bounding box calculation is available.
|
||||
*/
|
||||
virtual QgsRectangle calculateBoundingBox() const;
|
||||
|
||||
/** Clears any cached parameters associated with the geometry, eg bounding boxes
|
||||
*/
|
||||
virtual void clearCache() const {}
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
@ -723,7 +723,7 @@ bool QgsCircularStringV2::insertVertex( QgsVertexId position, const QgsPointV2&
|
||||
{
|
||||
insertVertexBetween( position.vertex, position.vertex + 1, position.vertex - 1 );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -744,7 +744,7 @@ bool QgsCircularStringV2::moveVertex( QgsVertexId position, const QgsPointV2& ne
|
||||
{
|
||||
mM[position.vertex] = newPos.m();
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -772,7 +772,7 @@ bool QgsCircularStringV2::deleteVertex( QgsVertexId position )
|
||||
deleteVertex( position.vertex - 1 );
|
||||
}
|
||||
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -41,8 +41,6 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
||||
virtual QgsCircularStringV2* clone() const override;
|
||||
virtual void clear() override;
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
@ -134,6 +132,10 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
||||
virtual bool dropZValue() override;
|
||||
virtual bool dropMValue() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
private:
|
||||
QVector<double> mX;
|
||||
QVector<double> mY;
|
||||
@ -152,6 +154,7 @@ class CORE_EXPORT QgsCircularStringV2: public QgsCurveV2
|
||||
const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon );
|
||||
void insertVertexBetween( int after, int before, int pointOnCircle );
|
||||
void deleteVertex( int i );
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCIRCULARSTRING_H
|
||||
|
@ -89,10 +89,10 @@ QgsRectangle QgsCompoundCurveV2::calculateBoundingBox() const
|
||||
return QgsRectangle();
|
||||
}
|
||||
|
||||
QgsRectangle bbox = mCurves.at( 0 )->calculateBoundingBox();
|
||||
QgsRectangle bbox = mCurves.at( 0 )->boundingBox();
|
||||
for ( int i = 1; i < mCurves.size(); ++i )
|
||||
{
|
||||
QgsRectangle curveBox = mCurves.at( i )->calculateBoundingBox();
|
||||
QgsRectangle curveBox = mCurves.at( i )->boundingBox();
|
||||
bbox.combineExtentWith( &curveBox );
|
||||
}
|
||||
return bbox;
|
||||
@ -497,7 +497,7 @@ bool QgsCompoundCurveV2::insertVertex( QgsVertexId position, const QgsPointV2& v
|
||||
bool success = mCurves.at( curveId )->insertVertex( curveIds.at( 0 ).second, vertex );
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //bbox changed
|
||||
clearCache(); //bbox changed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -514,7 +514,7 @@ bool QgsCompoundCurveV2::moveVertex( QgsVertexId position, const QgsPointV2& new
|
||||
bool success = !curveIds.isEmpty();
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //bbox changed
|
||||
clearCache(); //bbox changed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -531,7 +531,7 @@ bool QgsCompoundCurveV2::deleteVertex( QgsVertexId position )
|
||||
bool success = !curveIds.isEmpty();
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //bbox changed
|
||||
clearCache(); //bbox changed
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -42,8 +42,6 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
|
||||
virtual QgsCompoundCurveV2* clone() const override;
|
||||
virtual void clear() override;
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
@ -120,11 +118,16 @@ class CORE_EXPORT QgsCompoundCurveV2: public QgsCurveV2
|
||||
virtual bool dropZValue() override;
|
||||
virtual bool dropMValue() override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
private:
|
||||
QList< QgsCurveV2* > mCurves;
|
||||
/** Turns a vertex id for the compound curve into one or more ids for the subcurves
|
||||
@return the index of the subcurve or -1 in case of error*/
|
||||
QList< QPair<int, QgsVertexId> > curveVertexId( QgsVertexId id ) const;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSCOMPOUNDCURVEV2_H
|
||||
|
@ -209,7 +209,7 @@ QgsRectangle QgsCurvePolygonV2::calculateBoundingBox() const
|
||||
{
|
||||
if ( mExteriorRing )
|
||||
{
|
||||
return mExteriorRing->calculateBoundingBox();
|
||||
return mExteriorRing->boundingBox();
|
||||
}
|
||||
return QgsRectangle();
|
||||
}
|
||||
@ -666,7 +666,7 @@ bool QgsCurvePolygonV2::insertVertex( QgsVertexId vId, const QgsPointV2& vertex
|
||||
else if ( vId.vertex == n )
|
||||
ring->moveVertex( QgsVertexId( 0, 0, 0 ), vertex );
|
||||
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -687,7 +687,7 @@ bool QgsCurvePolygonV2::moveVertex( QgsVertexId vId, const QgsPointV2& newPos )
|
||||
ring->moveVertex( QgsVertexId( vId.part, vId.ring, n - 1 ), newPos );
|
||||
else if ( vId.vertex == n - 1 )
|
||||
ring->moveVertex( QgsVertexId( vId.part, vId.ring, 0 ), newPos );
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -717,7 +717,7 @@ bool QgsCurvePolygonV2::deleteVertex( QgsVertexId vId )
|
||||
{
|
||||
removeInteriorRing( vId.ring - 1 );
|
||||
}
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -729,7 +729,7 @@ bool QgsCurvePolygonV2::deleteVertex( QgsVertexId vId )
|
||||
ring->moveVertex( QgsVertexId( 0, 0, n - 2 ), ring->vertexAt( QgsVertexId( 0, 0, 0 ) ) );
|
||||
else if ( vId.vertex == n - 1 )
|
||||
ring->moveVertex( QgsVertexId( 0, 0, 0 ), ring->vertexAt( QgsVertexId( 0, 0, n - 2 ) ) );
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -41,8 +41,6 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
virtual QgsCurvePolygonV2* clone() const override;
|
||||
void clear() override;
|
||||
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
virtual bool fromWkb( QgsConstWkbPtr wkb ) override;
|
||||
virtual bool fromWkt( const QString& wkt ) override;
|
||||
|
||||
@ -120,6 +118,7 @@ class CORE_EXPORT QgsCurvePolygonV2: public QgsSurfaceV2
|
||||
QgsCurveV2* mExteriorRing;
|
||||
QList<QgsCurveV2*> mInteriorRings;
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
};
|
||||
|
||||
#endif // QGSCURVEPOLYGONV2_H
|
||||
|
@ -89,3 +89,13 @@ QgsPointV2 QgsCurveV2::vertexAt( QgsVertexId id ) const
|
||||
pointAt( id.vertex, v, type );
|
||||
return v;
|
||||
}
|
||||
|
||||
QgsRectangle QgsCurveV2::boundingBox() const
|
||||
{
|
||||
if ( mBoundingBox.isNull() )
|
||||
{
|
||||
mBoundingBox = calculateBoundingBox();
|
||||
}
|
||||
return mBoundingBox;
|
||||
}
|
||||
|
||||
|
@ -109,6 +109,15 @@ class CORE_EXPORT QgsCurveV2: public QgsAbstractGeometryV2
|
||||
virtual int partCount() const override { return numPoints() > 0 ? 1 : 0; }
|
||||
virtual QgsPointV2 vertexAt( QgsVertexId id ) const override;
|
||||
|
||||
virtual QgsRectangle boundingBox() const override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual void clearCache() const override { mBoundingBox = QgsRectangle(); }
|
||||
|
||||
private:
|
||||
|
||||
mutable QgsRectangle mBoundingBox;
|
||||
};
|
||||
|
||||
#endif // QGSCURVEV2_H
|
||||
|
@ -72,7 +72,7 @@ void QgsGeometryCollectionV2::clear()
|
||||
qDeleteAll( mGeometries );
|
||||
mGeometries.clear();
|
||||
mWkbType = QgsWKBTypes::Unknown;
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
int QgsGeometryCollectionV2::numGeometries() const
|
||||
@ -98,7 +98,7 @@ bool QgsGeometryCollectionV2::addGeometry( QgsAbstractGeometryV2* g )
|
||||
}
|
||||
|
||||
mGeometries.append( g );
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -110,7 +110,7 @@ bool QgsGeometryCollectionV2::insertGeometry( QgsAbstractGeometryV2 *g, int inde
|
||||
}
|
||||
|
||||
mGeometries.insert( index, g );
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -122,7 +122,7 @@ bool QgsGeometryCollectionV2::removeGeometry( int nr )
|
||||
}
|
||||
delete mGeometries.at( nr );
|
||||
mGeometries.remove( nr );
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -147,7 +147,7 @@ void QgsGeometryCollectionV2::transform( const QgsCoordinateTransform& ct, QgsCo
|
||||
{
|
||||
g->transform( ct, d );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
void QgsGeometryCollectionV2::transform( const QTransform& t )
|
||||
@ -156,7 +156,7 @@ void QgsGeometryCollectionV2::transform( const QTransform& t )
|
||||
{
|
||||
g->transform( t );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
#if 0
|
||||
@ -207,7 +207,7 @@ bool QgsGeometryCollectionV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
{
|
||||
mGeometries[i] = geometryList.at( i );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -314,6 +314,15 @@ QString QgsGeometryCollectionV2::asJSON( int precision ) const
|
||||
return json;
|
||||
}
|
||||
|
||||
QgsRectangle QgsGeometryCollectionV2::boundingBox() const
|
||||
{
|
||||
if ( mBoundingBox.isNull() )
|
||||
{
|
||||
mBoundingBox = calculateBoundingBox();
|
||||
}
|
||||
return mBoundingBox;
|
||||
}
|
||||
|
||||
QgsRectangle QgsGeometryCollectionV2::calculateBoundingBox() const
|
||||
{
|
||||
if ( mGeometries.size() < 1 )
|
||||
@ -321,10 +330,10 @@ QgsRectangle QgsGeometryCollectionV2::calculateBoundingBox() const
|
||||
return QgsRectangle();
|
||||
}
|
||||
|
||||
QgsRectangle bbox = mGeometries.at( 0 )->calculateBoundingBox();
|
||||
QgsRectangle bbox = mGeometries.at( 0 )->boundingBox();
|
||||
for ( int i = 1; i < mGeometries.size(); ++i )
|
||||
{
|
||||
QgsRectangle geomBox = mGeometries.at( i )->calculateBoundingBox();
|
||||
QgsRectangle geomBox = mGeometries.at( i )->boundingBox();
|
||||
bbox.combineExtentWith( &geomBox );
|
||||
}
|
||||
return bbox;
|
||||
@ -385,7 +394,7 @@ bool QgsGeometryCollectionV2::insertVertex( QgsVertexId position, const QgsPoint
|
||||
bool success = mGeometries.at( position.part )->insertVertex( position, vertex );
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -400,7 +409,7 @@ bool QgsGeometryCollectionV2::moveVertex( QgsVertexId position, const QgsPointV2
|
||||
bool success = mGeometries.at( position.part )->moveVertex( position, newPos );
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
return success;
|
||||
}
|
||||
@ -428,7 +437,7 @@ bool QgsGeometryCollectionV2::deleteVertex( QgsVertexId position )
|
||||
|
||||
if ( success )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
|
||||
QString asJSON( int precision = 17 ) const override;
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
virtual QgsRectangle boundingBox() const override;
|
||||
|
||||
virtual void coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coord ) const override;
|
||||
virtual double closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const override;
|
||||
@ -138,6 +138,12 @@ class CORE_EXPORT QgsGeometryCollectionV2: public QgsAbstractGeometryV2
|
||||
*/
|
||||
bool fromCollectionWkt( const QString &wkt, const QList<QgsAbstractGeometryV2*>& subtypes, const QString& defaultChildWkbType = QString() );
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
virtual void clearCache() const override { mBoundingBox = QgsRectangle(); }
|
||||
|
||||
private:
|
||||
|
||||
mutable QgsRectangle mBoundingBox;
|
||||
};
|
||||
|
||||
#endif // QGSGEOMETRYCOLLECTIONV2_H
|
||||
|
@ -87,7 +87,7 @@ void QgsLineStringV2::clear()
|
||||
mZ.clear();
|
||||
mM.clear();
|
||||
mWkbType = QgsWKBTypes::Unknown;
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
bool QgsLineStringV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
@ -113,6 +113,30 @@ void QgsLineStringV2::fromWkbPoints( QgsWKBTypes::Type type, const QgsConstWkbPt
|
||||
importVerticesFromWkb( wkb );
|
||||
}
|
||||
|
||||
QgsRectangle QgsLineStringV2::calculateBoundingBox() const
|
||||
{
|
||||
double xmin = std::numeric_limits<double>::max();
|
||||
double ymin = std::numeric_limits<double>::max();
|
||||
double xmax = -std::numeric_limits<double>::max();
|
||||
double ymax = -std::numeric_limits<double>::max();
|
||||
|
||||
Q_FOREACH ( double x, mX )
|
||||
{
|
||||
if ( x < xmin )
|
||||
xmin = x;
|
||||
if ( x > xmax )
|
||||
xmax = x;
|
||||
}
|
||||
Q_FOREACH ( double y, mY )
|
||||
{
|
||||
if ( y < ymin )
|
||||
ymin = y;
|
||||
if ( y > ymax )
|
||||
ymax = y;
|
||||
}
|
||||
return QgsRectangle( xmin, ymin, xmax, ymax );
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
* This class is considered CRITICAL and any change MUST be accompanied with
|
||||
* full unit tests.
|
||||
@ -341,14 +365,14 @@ void QgsLineStringV2::setXAt( int index, double x )
|
||||
{
|
||||
if ( index >= 0 && index < mX.size() )
|
||||
mX[ index ] = x;
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void QgsLineStringV2::setYAt( int index, double y )
|
||||
{
|
||||
if ( index >= 0 && index < mY.size() )
|
||||
mY[ index ] = y;
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void QgsLineStringV2::setZAt( int index, double z )
|
||||
@ -381,7 +405,7 @@ void QgsLineStringV2::points( QList<QgsPointV2>& pts ) const
|
||||
|
||||
void QgsLineStringV2::setPoints( const QList<QgsPointV2>& points )
|
||||
{
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
|
||||
if ( points.isEmpty() )
|
||||
{
|
||||
@ -495,7 +519,7 @@ void QgsLineStringV2::append( const QgsLineStringV2* line )
|
||||
}
|
||||
}
|
||||
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
QgsLineStringV2* QgsLineStringV2::reversed() const
|
||||
@ -584,7 +608,7 @@ void QgsLineStringV2::transform( const QgsCoordinateTransform& ct, QgsCoordinate
|
||||
{
|
||||
delete[] zArray;
|
||||
}
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void QgsLineStringV2::transform( const QTransform& t )
|
||||
@ -597,7 +621,7 @@ void QgsLineStringV2::transform( const QTransform& t )
|
||||
mX[i] = x;
|
||||
mY[i] = y;
|
||||
}
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
@ -628,7 +652,7 @@ bool QgsLineStringV2::insertVertex( QgsVertexId position, const QgsPointV2& vert
|
||||
{
|
||||
mM.insert( position.vertex, vertex.m() );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -648,7 +672,7 @@ bool QgsLineStringV2::moveVertex( QgsVertexId position, const QgsPointV2& newPos
|
||||
{
|
||||
mM[position.vertex] = newPos.m();
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -675,7 +699,7 @@ bool QgsLineStringV2::deleteVertex( QgsVertexId position )
|
||||
clear();
|
||||
}
|
||||
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -702,7 +726,7 @@ void QgsLineStringV2::addVertex( const QgsPointV2& pt )
|
||||
{
|
||||
mM.append( pt.m() );
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
double QgsLineStringV2::closestSegment( const QgsPointV2& pt, QgsPointV2& segmentPt, QgsVertexId& vertexAfter, bool* leftOf, double epsilon ) const
|
||||
@ -843,7 +867,7 @@ void QgsLineStringV2::importVerticesFromWkb( const QgsConstWkbPtr& wkb )
|
||||
wkb >> mM[i];
|
||||
}
|
||||
}
|
||||
mBoundingBox = QgsRectangle(); //set bounding box invalid
|
||||
clearCache(); //set bounding box invalid
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -188,6 +188,10 @@ class CORE_EXPORT QgsLineStringV2: public QgsCurveV2
|
||||
|
||||
bool convertTo( QgsWKBTypes::Type type ) override;
|
||||
|
||||
protected:
|
||||
|
||||
virtual QgsRectangle calculateBoundingBox() const override;
|
||||
|
||||
private:
|
||||
QVector<double> mX;
|
||||
QVector<double> mY;
|
||||
|
@ -113,7 +113,7 @@ bool QgsPointV2::fromWkb( QgsConstWkbPtr wkbPtr )
|
||||
if ( isMeasure() )
|
||||
wkbPtr >> mM;
|
||||
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -255,12 +255,12 @@ void QgsPointV2::clear()
|
||||
{
|
||||
mWkbType = QgsWKBTypes::Unknown;
|
||||
mX = mY = mZ = mM = 0.;
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
}
|
||||
|
||||
void QgsPointV2::transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d )
|
||||
{
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
ct.transformInPlace( mX, mY, mZ, d );
|
||||
}
|
||||
|
||||
@ -281,7 +281,7 @@ void QgsPointV2::coordinateSequence( QList< QList< QList< QgsPointV2 > > >& coor
|
||||
bool QgsPointV2::moveVertex( QgsVertexId position, const QgsPointV2& newPos )
|
||||
{
|
||||
Q_UNUSED( position );
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
mX = newPos.mX;
|
||||
mY = newPos.mY;
|
||||
if ( is3D() && newPos.is3D() )
|
||||
@ -354,7 +354,7 @@ bool QgsPointV2::addMValue( double mValue )
|
||||
|
||||
void QgsPointV2::transform( const QTransform& t )
|
||||
{
|
||||
mBoundingBox = QgsRectangle();
|
||||
clearCache();
|
||||
qreal x, y;
|
||||
t.map( mX, mY, &x, &y );
|
||||
mX = x;
|
||||
|
@ -91,7 +91,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
* @see setX()
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
double &rx() { mBoundingBox = QgsRectangle(); return mX; }
|
||||
double &rx() { clearCache(); return mX; }
|
||||
|
||||
/** Returns a reference to the y-coordinate of this point.
|
||||
* Using a reference makes it possible to directly manipulate y in place.
|
||||
@ -99,7 +99,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
* @see setY()
|
||||
* @note not available in Python bindings
|
||||
*/
|
||||
double &ry() { mBoundingBox = QgsRectangle(); return mY; }
|
||||
double &ry() { clearCache(); return mY; }
|
||||
|
||||
/** Returns a reference to the z-coordinate of this point.
|
||||
* Using a reference makes it possible to directly manipulate z in place.
|
||||
@ -121,13 +121,13 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
* @see x()
|
||||
* @see rx()
|
||||
*/
|
||||
void setX( double x ) { mX = x; mBoundingBox = QgsRectangle(); }
|
||||
void setX( double x ) { clearCache(); mX = x; }
|
||||
|
||||
/** Sets the point's y-coordinate.
|
||||
* @see y()
|
||||
* @see ry()
|
||||
*/
|
||||
void setY( double y ) { mY = y; mBoundingBox = QgsRectangle(); }
|
||||
void setY( double y ) { clearCache(); mY = y; }
|
||||
|
||||
/** Sets the point's z-coordinate.
|
||||
* @note calling this will have no effect if the point does not contain a z-dimension. Use addZValue() to
|
||||
@ -151,6 +151,7 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
QPointF toQPointF() const;
|
||||
|
||||
//implementation of inherited methods
|
||||
virtual QgsRectangle boundingBox() const override { return QgsRectangle( mX, mY, mX, mY ); }
|
||||
virtual QString geometryType() const override { return "Point"; }
|
||||
virtual int dimension() const override { return 0; }
|
||||
virtual QgsPointV2* clone() const override;
|
||||
@ -163,7 +164,6 @@ class CORE_EXPORT QgsPointV2: public QgsAbstractGeometryV2
|
||||
QDomElement asGML2( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
|
||||
QDomElement asGML3( QDomDocument& doc, int precision = 17, const QString& ns = "gml" ) const override;
|
||||
QString asJSON( int precision = 17 ) const override;
|
||||
virtual QgsRectangle calculateBoundingBox() const override { return QgsRectangle( mX, mY, mX, mY );}
|
||||
void draw( QPainter& p ) const override;
|
||||
void transform( const QgsCoordinateTransform& ct, QgsCoordinateTransform::TransformDirection d = QgsCoordinateTransform::ForwardTransform ) override;
|
||||
void transform( const QTransform& t ) override;
|
||||
|
@ -28,6 +28,25 @@ class CORE_EXPORT QgsSurfaceV2: public QgsAbstractGeometryV2
|
||||
public:
|
||||
|
||||
virtual QgsPolygonV2* surfaceToPolygon() const = 0;
|
||||
|
||||
/** Returns the minimal bounding box for the geometry
|
||||
*/
|
||||
virtual QgsRectangle boundingBox() const override
|
||||
{
|
||||
if ( mBoundingBox.isNull() )
|
||||
{
|
||||
mBoundingBox = calculateBoundingBox();
|
||||
}
|
||||
return mBoundingBox;
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void clearCache() const override { mBoundingBox = QgsRectangle(); }
|
||||
|
||||
private:
|
||||
|
||||
mutable QgsRectangle mBoundingBox;
|
||||
};
|
||||
|
||||
#endif // QGSSURFACEV2_H
|
||||
|
Loading…
x
Reference in New Issue
Block a user