For geometry validation GAP errors, allow zooming to gap or context

When a topological check returns a gap, it's sometimes better to zoom to the gap,
sometimes to show the gap in the context of the surrounding polygons. There is no
one-size-suits-all solution.
Therefore it's now possible to zoom to one by enabling the "zoom to feature(s)" button
also for topological errors.
This commit is contained in:
Matthias Kuhn 2019-07-19 11:15:47 +02:00
parent 46807c7eaf
commit 4505a4b03b
8 changed files with 54 additions and 10 deletions

View File

@ -77,6 +77,16 @@ The id of the feature on which this error has been detected.
QgsGeometry geometry() const;
%Docstring
The geometry of the error in map units.
%End
virtual QgsRectangle contextBoundingBox() const;
%Docstring
The context of the error.
For topology checks like gap checks this returns the context of an error
and the involved features.
May be a NULL rectangle.
.. versionadded:: 3.10
%End
virtual QgsRectangle affectedAreaBBox() const;

View File

@ -85,6 +85,11 @@ QgsGeometry QgsGeometryCheckError::geometry() const
return mGeometry;
}
QgsRectangle QgsGeometryCheckError::contextBoundingBox() const
{
return QgsRectangle();
}
QgsRectangle QgsGeometryCheckError::affectedAreaBBox() const
{
return mGeometry.boundingBox();

View File

@ -94,6 +94,16 @@ class ANALYSIS_EXPORT QgsGeometryCheckError
*/
QgsGeometry geometry() const;
/**
* The context of the error.
* For topology checks like gap checks this returns the context of an error
* and the involved features.
* May be a NULL rectangle.
*
* \since QGIS 3.10
*/
virtual QgsRectangle contextBoundingBox() const;
/**
* The bounding box of the affected area of the error.
*/

View File

@ -135,7 +135,8 @@ void QgsGeometryGapCheck::collectErrors( const QMap<QString, QgsFeaturePool *> &
// Add error
double area = gapGeom->area();
errors.append( new QgsGeometryGapCheckError( this, QString(), QgsGeometry( gapGeom.release() ), neighboringIds, area, gapAreaBBox ) );
QgsRectangle gapBbox = gapGeom->boundingBox();
errors.append( new QgsGeometryGapCheckError( this, QString(), QgsGeometry( gapGeom.release() ), neighboringIds, area, gapBbox, gapAreaBBox ) );
}
}
@ -294,6 +295,11 @@ QgsGeometryCheck::CheckType QgsGeometryGapCheck::factoryCheckType()
}
///@endcond private
QgsRectangle QgsGeometryGapCheckError::contextBoundingBox() const
{
return mContextBoundingBox;
}
bool QgsGeometryGapCheckError::isEqual( QgsGeometryCheckError *other ) const
{
QgsGeometryGapCheckError *err = dynamic_cast<QgsGeometryGapCheckError *>( other );

View File

@ -43,13 +43,17 @@ class ANALYSIS_EXPORT QgsGeometryGapCheckError : public QgsGeometryCheckError
const QgsGeometry &geometry,
const QMap<QString, QgsFeatureIds> &neighbors,
double area,
const QgsRectangle &gapAreaBBox )
const QgsRectangle &gapAreaBBox,
const QgsRectangle &contextArea )
: QgsGeometryCheckError( check, layerId, FID_NULL, geometry, geometry.constGet()->centroid(), QgsVertexId(), area, ValueArea )
, mNeighbors( neighbors )
, mGapAreaBBox( gapAreaBBox )
, mContextBoundingBox( contextArea )
{
}
QgsRectangle contextBoundingBox() const override;
/**
* A map of layers and feature ids of the neighbors of the gap.
*/
@ -72,6 +76,7 @@ class ANALYSIS_EXPORT QgsGeometryGapCheckError : public QgsGeometryCheckError
private:
QMap<QString, QgsFeatureIds> mNeighbors;
QgsRectangle mGapAreaBBox;
QgsRectangle mContextBoundingBox;
};

View File

@ -242,8 +242,8 @@ void QgsGeometryValidationDock::onCurrentErrorChanged( const QModelIndex &curren
}
}
bool hasFeature = !FID_IS_NULL( current.data( QgsGeometryValidationModel::ErrorFeatureIdRole ) );
mZoomToFeatureButton->setEnabled( hasFeature );
bool hasContextRectangle = !current.data( QgsGeometryValidationModel::FeatureExtentRole ).isNull();
mZoomToFeatureButton->setEnabled( hasContextRectangle );
}
void QgsGeometryValidationDock::updateMapCanvasExtent()

View File

@ -94,11 +94,19 @@ QVariant QgsGeometryValidationModel::data( const QModelIndex &index, int role )
case FeatureExtentRole:
{
const QgsFeatureId fid = topologyError->featureId();
if ( FID_IS_NULL( fid ) )
return QgsRectangle();
const QgsFeature feature = getFeature( fid );
return feature.geometry().boundingBox();
const QgsRectangle contextBoundingBox = topologyError->contextBoundingBox();
if ( !contextBoundingBox.isNull() )
{
return contextBoundingBox;
}
else
{
const QgsFeatureId fid = topologyError->featureId();
if ( FID_IS_NULL( fid ) )
return QgsRectangle();
const QgsFeature feature = getFeature( fid );
return feature.geometry().boundingBox();
}
}
case ProblemExtentRole:

View File

@ -31,7 +31,7 @@
<item row="0" column="3">
<widget class="QToolButton" name="mZoomToFeatureButton">
<property name="text">
<string>Zoom To Feature</string>
<string>Zoom To Feature(s)</string>
</property>
<property name="icon">
<iconset resource="../../images/images.qrc">