Skip to content

Commit

Permalink
Add QgsRectangle::setNull(), deprecating setMinimal()
Browse files Browse the repository at this point in the history
  • Loading branch information
strk authored and nyalldawson committed Oct 19, 2023
1 parent d927a59 commit 0ec5f0d
Show file tree
Hide file tree
Showing 24 changed files with 102 additions and 53 deletions.
32 changes: 28 additions & 4 deletions python/core/auto_generated/geometry/qgsrectangle.sip.in
Expand Up @@ -111,10 +111,26 @@ Set the minimum y value.
Set the maximum y value.
%End

void setMinimal() /HoldGIL/;
void setNull() /HoldGIL/;
%Docstring
Mark a rectangle as being null (holding no spatial information).

A null rectangle is also empty by definition.

.. seealso:: :py:func:`isNull`

.. seealso:: :py:func:`isEmpty`

.. versionadded:: 3.34
%End

void setMinimal() /Deprecated/;
%Docstring
Set a rectangle so that min corner is at max
and max corner is at min. It is NOT normalized.

.. deprecated:: QGIS 3.34
- will be removed in QGIS 4.0. Use :py:func:`~QgsRectangle.setNull`.
%End

double xMaximum() const /HoldGIL/;
Expand Down Expand Up @@ -290,15 +306,23 @@ Returns the distance from ``point`` to the nearest point on the boundary of the

bool isEmpty() const;
%Docstring
Returns ``True`` if the rectangle is empty.
An empty rectangle may still be non-null if it contains valid information (e.g. bounding box of a point).
Returns ``True`` if the rectangle has no area.

An empty rectangle may still be non-null if it contains valid
spatial information (e.g. bounding box of a point or of a vertical
or horizontal segment).

.. seealso:: :py:func:`isNull`
%End

bool isNull() const;
%Docstring
Test if the rectangle is null (all coordinates zero or after call to :py:func:`~QgsRectangle.setMinimal`).
Test if the rectangle is null (holding no spatial information).

A null rectangle is also an empty rectangle.

.. seealso:: :py:func:`setNull`

.. versionadded:: 2.4
%End

Expand Down
2 changes: 1 addition & 1 deletion src/app/3d/qgs3dmapcanvaswidget.cpp
Expand Up @@ -604,7 +604,7 @@ void Qgs3DMapCanvasWidget::onViewed2DExtentFrom3DChanged( QVector<QgsPointXY> ex
if ( mCanvas->map()->viewSyncMode().testFlag( Qgis::ViewSyncModeFlag::Sync2DTo3D ) )
{
QgsRectangle extentRect;
extentRect.setMinimal();
extentRect.setNull();
for ( QgsPointXY &pt : extent )
{
extentRect.include( pt );
Expand Down
43 changes: 34 additions & 9 deletions src/core/geometry/qgsrectangle.h
Expand Up @@ -165,16 +165,31 @@ class CORE_EXPORT QgsRectangle
*/
void setYMaximum( double y ) SIP_HOLDGIL { mYmax = y; }

/**
* Mark a rectangle as being null (holding no spatial information).
*
* A null rectangle is also empty by definition.
*
* \see isNull()
* \see isEmpty()
*
* \since QGIS 3.34
*/
void setNull() SIP_HOLDGIL
{
mXmin = mYmin = std::numeric_limits<double>::max();
mXmax = mYmax = -std::numeric_limits<double>::max();
}

/**
* Set a rectangle so that min corner is at max
* and max corner is at min. It is NOT normalized.
*
* \deprecated since QGIS 3.34 - will be removed in QGIS 4.0. Use setNull().
*/
void setMinimal() SIP_HOLDGIL
Q_DECL_DEPRECATED void setMinimal() SIP_DEPRECATED
{
mXmin = std::numeric_limits<double>::max();
mYmin = std::numeric_limits<double>::max();
mXmax = -std::numeric_limits<double>::max();
mYmax = -std::numeric_limits<double>::max();
setNull();
}

/**
Expand Down Expand Up @@ -473,22 +488,32 @@ class CORE_EXPORT QgsRectangle
QgsRectangle &operator+=( QgsVector v );

/**
* Returns TRUE if the rectangle is empty.
* An empty rectangle may still be non-null if it contains valid information (e.g. bounding box of a point).
* Returns TRUE if the rectangle has no area.
*
* An empty rectangle may still be non-null if it contains valid
* spatial information (e.g. bounding box of a point or of a vertical
* or horizontal segment).
*
* \see isNull()
*/
bool isEmpty() const
{
return mXmax < mXmin || mYmax < mYmin || qgsDoubleNear( mXmax, mXmin ) || qgsDoubleNear( mYmax, mYmin );
}

/**
* Test if the rectangle is null (all coordinates zero or after call to setMinimal()).
* Test if the rectangle is null (holding no spatial information).
*
* A null rectangle is also an empty rectangle.
*
* \see setNull()
*
* \since QGIS 2.4
*/
bool isNull() const
{
// rectangle created QgsRectangle() or with rect.setMinimal() ?
// rectangle created QgsRectangle() or with rect.setNull() or
// otherwise having NaN ordinates
return ( std::isnan( mXmin ) && std::isnan( mXmax ) && std::isnan( mYmin ) && std::isnan( mYmax ) ) ||
( qgsDoubleNear( mXmin, 0.0 ) && qgsDoubleNear( mXmax, 0.0 ) && qgsDoubleNear( mYmin, 0.0 ) && qgsDoubleNear( mYmax, 0.0 ) ) ||
( qgsDoubleNear( mXmin, std::numeric_limits<double>::max() ) && qgsDoubleNear( mYmin, std::numeric_limits<double>::max() ) &&
Expand Down
2 changes: 1 addition & 1 deletion src/core/maprenderer/qgsmaprenderercache.cpp
Expand Up @@ -35,7 +35,7 @@ void QgsMapRendererCache::clear()

void QgsMapRendererCache::clearInternal()
{
mExtent.setMinimal();
mExtent.setNull();
mScale = 0;

// make sure we are disconnected from all layers
Expand Down
2 changes: 1 addition & 1 deletion src/core/mesh/qgsmeshlayer.cpp
Expand Up @@ -153,7 +153,7 @@ QgsRectangle QgsMeshLayer::extent() const
else
{
QgsRectangle rec;
rec.setMinimal();
rec.setNull();
return rec;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/core/mesh/qgstriangularmesh.cpp
Expand Up @@ -187,7 +187,7 @@ bool QgsTriangularMesh::update( QgsMesh *nativeMesh, const QgsCoordinateTransfor
// TRANSFORM VERTICES
mCoordinateTransform = transform;
mTriangularMesh.vertices.resize( nativeMesh->vertices.size() );
mExtent.setMinimal();
mExtent.setNull();
for ( int i = 0; i < nativeMesh->vertices.size(); ++i )
{
mTriangularMesh.vertices[i] = nativeToTriangularCoordinates( nativeMesh->vertices.at( i ) );
Expand Down Expand Up @@ -316,7 +316,7 @@ QgsRectangle QgsTriangularMesh::extent() const
{
if ( !mIsExtentValid )
{
mExtent.setMinimal();
mExtent.setNull();
for ( int i = 0; i < mTriangularMesh.vertices.size(); ++i )
if ( !mTriangularMesh.vertices.at( i ).isEmpty() )
mExtent.include( mTriangularMesh.vertices.at( i ) );
Expand Down
2 changes: 1 addition & 1 deletion src/core/proj/qgscoordinatetransform.cpp
Expand Up @@ -616,7 +616,7 @@ QgsRectangle QgsCoordinateTransform::transformBoundingBox( const QgsRectangle &r
const int nYPoints = std::min( static_cast< int >( std::ceil( ( yMax - yMin ) / dst ) ) + 1, 1000 );

QgsRectangle bb_rect;
bb_rect.setMinimal();
bb_rect.setNull();

// We're interfacing with C-style vectors in the
// end, so let's do C-style vectors here too.
Expand Down
10 changes: 5 additions & 5 deletions src/core/providers/memory/qgsmemoryprovider.cpp
Expand Up @@ -337,7 +337,7 @@ QgsRectangle QgsMemoryProvider::extent() const
{
if ( mExtent.isEmpty() && !mFeatures.isEmpty() )
{
mExtent.setMinimal();
mExtent.setNull();
if ( mSubsetString.isEmpty() )
{
// fast way - iterate through all features
Expand All @@ -361,7 +361,7 @@ QgsRectangle QgsMemoryProvider::extent() const
}
else if ( mFeatures.isEmpty() )
{
mExtent.setMinimal();
mExtent.setNull();
}

return mExtent;
Expand Down Expand Up @@ -758,7 +758,7 @@ bool QgsMemoryProvider::setSubsetString( const QString &theSQL, bool updateFeatu

mSubsetString = theSQL;
clearMinMaxCache();
mExtent.setMinimal();
mExtent.setNull();

emit dataChanged();
return true;
Expand Down Expand Up @@ -795,13 +795,13 @@ bool QgsMemoryProvider::truncate()
{
mFeatures.clear();
clearMinMaxCache();
mExtent.setMinimal();
mExtent.setNull();
return true;
}

void QgsMemoryProvider::updateExtents()
{
mExtent.setMinimal();
mExtent.setNull();
}

QString QgsMemoryProvider::name() const
Expand Down
Expand Up @@ -640,7 +640,7 @@ void QgsMeshMemoryDataProvider::close()
QgsRectangle QgsMeshMemoryDataProvider::calculateExtent() const
{
QgsRectangle rec;
rec.setMinimal();
rec.setNull();
for ( const QgsMeshVertex &v : mVertices )
{
rec.setXMinimum( std::min( rec.xMinimum(), v.x() ) );
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsgeometrysimplifier.cpp
Expand Up @@ -28,7 +28,7 @@ bool QgsAbstractGeometrySimplifier::isGeneralizableByDeviceBoundingBox( const Qg
bool QgsAbstractGeometrySimplifier::isGeneralizableByDeviceBoundingBox( const QVector<QPointF> &points, float mapToPixelTol )
{
QgsRectangle r;
r.setMinimal();
r.setNull();

for ( int i = 0, numPoints = points.size(); i < numPoints; ++i )
{
Expand Down
4 changes: 2 additions & 2 deletions src/core/qgsgml.cpp
Expand Up @@ -61,7 +61,7 @@ QgsGml::QgsGml(
int QgsGml::getFeatures( const QString &uri, Qgis::WkbType *wkbType, QgsRectangle *extent, const QString &userName, const QString &password, const QString &authcfg )
{
//start with empty extent
mExtent.setMinimal();
mExtent.setNull();

QNetworkRequest request( uri );
QgsSetRequestInitiatorClass( request, QStringLiteral( "QgsGml" ) );
Expand Down Expand Up @@ -178,7 +178,7 @@ int QgsGml::getFeatures( const QString &uri, Qgis::WkbType *wkbType, QgsRectangl

int QgsGml::getFeatures( const QByteArray &data, Qgis::WkbType *wkbType, QgsRectangle *extent )
{
mExtent.setMinimal();
mExtent.setNull();

QString errorMsg;
if ( !mParser.processData( data, true /* atEnd */, errorMsg ) )
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsmaplayerutils.cpp
Expand Up @@ -31,7 +31,7 @@ QgsRectangle QgsMapLayerUtils::combinedExtent( const QList<QgsMapLayer *> &layer
{
// We can't use a constructor since QgsRectangle normalizes the rectangle upon construction
QgsRectangle fullExtent;
fullExtent.setMinimal();
fullExtent.setNull();

// iterate through the map layers and test each layers extent
// against the current min and max values
Expand Down
2 changes: 1 addition & 1 deletion src/core/qgsmapsettings.cpp
Expand Up @@ -692,7 +692,7 @@ QgsRectangle QgsMapSettings::fullExtent() const
// reset the map canvas extent since the extent may now be smaller
// We can't use a constructor since QgsRectangle normalizes the rectangle upon construction
QgsRectangle fullExtent;
fullExtent.setMinimal();
fullExtent.setNull();

// iterate through the map layers and test each layers extent
// against the current min and max values
Expand Down
4 changes: 2 additions & 2 deletions src/core/raster/qgsrasterlayerrenderer.cpp
Expand Up @@ -131,7 +131,7 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender
catch ( QgsCsException &cs )
{
QgsMessageLog::logMessage( QObject::tr( "Could not reproject view extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
myProjectedViewExtent.setMinimal();
myProjectedViewExtent.setNull();
}
}

Expand All @@ -144,7 +144,7 @@ QgsRasterLayerRenderer::QgsRasterLayerRenderer( QgsRasterLayer *layer, QgsRender
catch ( QgsCsException &cs )
{
QgsMessageLog::logMessage( QObject::tr( "Could not reproject layer extent: %1" ).arg( cs.what() ), QObject::tr( "Raster" ) );
myProjectedLayerExtent.setMinimal();
myProjectedLayerExtent.setNull();
}
}
else
Expand Down
4 changes: 2 additions & 2 deletions src/core/vector/qgsvectorlayer.cpp
Expand Up @@ -830,7 +830,7 @@ QgsRectangle QgsVectorLayer::boundingBoxOfSelected() const
}

QgsRectangle r, retval;
retval.setMinimal();
retval.setNull();

QgsFeature fet;
if ( mDataProvider->capabilities() & QgsVectorDataProvider::SelectAtId )
Expand Down Expand Up @@ -1011,7 +1011,7 @@ QgsRectangle QgsVectorLayer::extent() const
QGIS_PROTECT_QOBJECT_THREAD_ACCESS

QgsRectangle rect;
rect.setMinimal();
rect.setNull();

if ( !isSpatial() )
return rect;
Expand Down
2 changes: 1 addition & 1 deletion src/gui/layertree/qgslayertreeviewdefaultactions.cpp
Expand Up @@ -372,7 +372,7 @@ void QgsLayerTreeViewDefaultActions::zoomToLayers( QgsMapCanvas *canvas, const Q
QgsTemporaryCursorOverride cursorOverride( Qt::WaitCursor );

QgsRectangle extent;
extent.setMinimal();
extent.setNull();

if ( !layers.empty() )
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsexpressionselectiondialog.cpp
Expand Up @@ -164,7 +164,7 @@ void QgsExpressionSelectionDialog::mButtonZoomToFeatures_clicked()
QgsFeatureIterator features = mLayer->getFeatures( request );

QgsRectangle bbox;
bbox.setMinimal();
bbox.setNull();
QgsFeature feat;
int featureCount = 0;
while ( features.nextFeature( feat ) )
Expand Down
6 changes: 3 additions & 3 deletions src/gui/qgsmapcanvas.cpp
Expand Up @@ -1790,9 +1790,9 @@ void QgsMapCanvas::zoomToSelected( QgsMapLayer *layer )
void QgsMapCanvas::zoomToSelected( const QList<QgsMapLayer *> &layers )
{
QgsRectangle rect;
rect.setMinimal();
rect.setNull();
QgsRectangle selectionExtent;
selectionExtent.setMinimal();
selectionExtent.setNull();

for ( QgsMapLayer *mapLayer : layers )
{
Expand Down Expand Up @@ -2054,7 +2054,7 @@ void QgsMapCanvas::panToSelected( QgsMapLayer *layer )
void QgsMapCanvas::panToSelected( const QList<QgsMapLayer *> &layers )
{
QgsRectangle selectionExtent;
selectionExtent.setMinimal();
selectionExtent.setNull();

for ( QgsMapLayer *mapLayer : layers )
{
Expand Down
2 changes: 1 addition & 1 deletion src/gui/qgsmapcanvasutils.cpp
Expand Up @@ -30,7 +30,7 @@ long QgsMapCanvasUtils::zoomToMatchingFeatures( QgsMapCanvas *canvas, QgsVectorL
QgsFeatureIterator features = layer->getFeatures( request );

QgsRectangle bbox;
bbox.setMinimal();
bbox.setNull();
QgsFeature feat;
int featureCount = 0;
while ( features.nextFeature( feat ) )
Expand Down
4 changes: 2 additions & 2 deletions src/providers/mssql/qgsmssqlprovider.cpp
Expand Up @@ -1826,7 +1826,7 @@ bool QgsMssqlProvider::deleteFeatures( const QgsFeatureIds &ids )

void QgsMssqlProvider::updateExtents()
{
mExtent.setMinimal();
mExtent.setNull();
}

QgsVectorDataProvider::Capabilities QgsMssqlProvider::capabilities() const
Expand Down Expand Up @@ -2011,7 +2011,7 @@ bool QgsMssqlProvider::setSubsetString( const QString &theSQL, bool )

setDataSourceUri( anUri.uri() );

mExtent.setMinimal();
mExtent.setNull();

emit dataChanged();

Expand Down

0 comments on commit 0ec5f0d

Please sign in to comment.