mirror of
https://github.com/qgis/QGIS.git
synced 2025-12-25 00:12:17 -05:00
Refactor topological point addition into a static method
This commit is contained in:
parent
d0d74da7a1
commit
a8a98e9ee8
@ -343,6 +343,7 @@ Merge features into a single one.
|
||||
%End
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
||||
@ -343,6 +343,7 @@ Merge features into a single one.
|
||||
%End
|
||||
|
||||
|
||||
|
||||
};
|
||||
|
||||
/************************************************************************
|
||||
|
||||
@ -144,68 +144,8 @@ void QgsMapToolAddFeature::featureDigitized( const QgsFeature &feature )
|
||||
}
|
||||
if ( topologicalEditing )
|
||||
{
|
||||
QgsFeatureRequest request = QgsFeatureRequest().setNoAttributes().setFlags( Qgis::FeatureRequestFlag::NoGeometry ).setLimit( 1 );
|
||||
const QgsRectangle bbox = feature.geometry().boundingBox();
|
||||
const QList<QgsMapLayer *> layers = canvas()->layers( true );
|
||||
|
||||
for ( QgsMapLayer *layer : layers )
|
||||
{
|
||||
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
QgsRectangle searchRect;
|
||||
QgsFeature f;
|
||||
QgsCoordinateTransform transform;
|
||||
|
||||
if ( !vectorLayer || !vectorLayer->isEditable() )
|
||||
continue;
|
||||
|
||||
if ( !( vectorLayer->geometryType() == Qgis::GeometryType::Polygon || vectorLayer->geometryType() == Qgis::GeometryType::Line ) )
|
||||
continue;
|
||||
|
||||
if ( vectorLayer->crs() == vlayer->crs() )
|
||||
{
|
||||
searchRect = QgsRectangle( bbox );
|
||||
}
|
||||
else
|
||||
{
|
||||
transform = QgsCoordinateTransform( vlayer->crs(), vectorLayer->crs(), vectorLayer->transformContext() );
|
||||
searchRect = transform.transformBoundingBox( bbox );
|
||||
}
|
||||
|
||||
searchRect.grow( QgsVectorLayerEditUtils::getTopologicalSearchRadius( vectorLayer ) );
|
||||
request.setFilterRect( searchRect );
|
||||
|
||||
// We check that there is actually at least one feature intersecting our geometry in the layer to avoid creating an empty edit command and calling costly addTopologicalPoint
|
||||
if ( !vectorLayer->getFeatures( request ).nextFeature( f ) )
|
||||
continue;
|
||||
|
||||
vectorLayer->beginEditCommand( tr( "Topological points added by 'Add Feature'" ) );
|
||||
|
||||
int res = 2;
|
||||
if ( vectorLayer->crs() != vlayer->crs() )
|
||||
{
|
||||
QgsGeometry transformedGeom = feature.geometry();
|
||||
try
|
||||
{
|
||||
// transform digitized geometry from vlayer crs to vectorLayer crs and add topological points
|
||||
transformedGeom.transform( transform );
|
||||
res = vectorLayer->addTopologicalPoints( transformedGeom );
|
||||
}
|
||||
catch ( QgsCsException &cse )
|
||||
{
|
||||
Q_UNUSED( cse )
|
||||
QgsDebugError( QStringLiteral( "transformation to vectorLayer coordinate failed" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
res = vectorLayer->addTopologicalPoints( feature.geometry() );
|
||||
}
|
||||
|
||||
if ( res == 0 ) // i.e. if any points were added
|
||||
vectorLayer->endEditCommand();
|
||||
else
|
||||
vectorLayer->destroyEditCommand();
|
||||
}
|
||||
QgsVectorLayerEditUtils::addTopologicalPointsToLayers( feature.geometry(), vlayer, layers, mToolName );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,68 +218,8 @@ void QgsMapToolReshape::reshape( QgsVectorLayer *vlayer )
|
||||
{
|
||||
//check if we need to add topological points to other layers
|
||||
const QList<QgsMapLayer *> layers = canvas()->layers( true );
|
||||
QgsFeatureRequest request = QgsFeatureRequest().setNoAttributes().setFlags( Qgis::FeatureRequestFlag::NoGeometry ).setLimit( 1 );
|
||||
QgsGeometry pointsAsGeom( new QgsMultiPoint( pts ) );
|
||||
QgsRectangle bbox = pointsAsGeom.boundingBox();
|
||||
|
||||
for ( QgsMapLayer *layer : layers )
|
||||
{
|
||||
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( vectorLayer && vectorLayer->isEditable() && vectorLayer->isSpatial() && ( vectorLayer->geometryType() == Qgis::GeometryType::Line || vectorLayer->geometryType() == Qgis::GeometryType::Polygon ) )
|
||||
{
|
||||
QgsCoordinateTransform ct;
|
||||
if ( vectorLayer->crs() != vlayer->crs() )
|
||||
{
|
||||
ct = QgsCoordinateTransform( vlayer->crs(), vectorLayer->crs(), vectorLayer->transformContext() );
|
||||
try
|
||||
{
|
||||
bbox = ct.transformBoundingBox( bbox );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "Bounding box transformation failed, skipping topological points for layer %1" ).arg( vlayer->id() ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bbox.grow( QgsVectorLayerEditUtils::getTopologicalSearchRadius( vectorLayer ) );
|
||||
request.setFilterRect( bbox );
|
||||
|
||||
// We check that there is actually at least one feature intersecting our geometry in the layer to avoid creating an empty edit command and calling costly addTopologicalPoint
|
||||
if ( !vectorLayer->getFeatures( request ).nextFeature( f ) )
|
||||
continue;
|
||||
|
||||
vectorLayer->beginEditCommand( tr( "Topological points added by Reshape" ) );
|
||||
|
||||
int returnValue = 2;
|
||||
if ( vectorLayer->crs() != vlayer->crs() )
|
||||
{
|
||||
try
|
||||
{
|
||||
// transform digitized geometry from vlayer crs to vectorLayer crs and add topological points
|
||||
pointsAsGeom.transform( ct );
|
||||
returnValue = vectorLayer->addTopologicalPoints( pointsAsGeom );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "transformation to vectorLayer coordinate failed" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = vectorLayer->addTopologicalPoints( pts );
|
||||
}
|
||||
|
||||
if ( returnValue == 0 )
|
||||
{
|
||||
vectorLayer->endEditCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// the layer was not modified, leave the undo buffer intact
|
||||
vectorLayer->destroyEditCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
QgsVectorLayerEditUtils::addTopologicalPointsToLayers( pointsAsGeom, vlayer, layers, mToolName );
|
||||
}
|
||||
|
||||
vlayer->endEditCommand();
|
||||
|
||||
@ -231,6 +231,74 @@ double QgsVectorLayerEditUtils::getTopologicalSearchRadius( const QgsVectorLayer
|
||||
}
|
||||
return threshold;
|
||||
}
|
||||
|
||||
void QgsVectorLayerEditUtils::addTopologicalPointsToLayers( const QgsGeometry &geom, QgsVectorLayer *vlayer, const QList<QgsMapLayer *> &layers, const QString &toolName )
|
||||
{
|
||||
QgsFeatureRequest request = QgsFeatureRequest().setNoAttributes().setFlags( Qgis::FeatureRequestFlag::NoGeometry ).setLimit( 1 );
|
||||
QgsFeature f;
|
||||
|
||||
for ( QgsMapLayer *layer : layers )
|
||||
{
|
||||
QgsVectorLayer *vectorLayer = qobject_cast<QgsVectorLayer *>( layer );
|
||||
if ( vectorLayer && vectorLayer->isEditable() && vectorLayer->isSpatial() && ( vectorLayer->geometryType() == Qgis::GeometryType::Line || vectorLayer->geometryType() == Qgis::GeometryType::Polygon ) )
|
||||
{
|
||||
// boundingBox() is cached, it doesn't matter calling it in the loop
|
||||
QgsRectangle bbox = geom.boundingBox();
|
||||
QgsCoordinateTransform ct;
|
||||
if ( vectorLayer->crs() != vlayer->crs() )
|
||||
{
|
||||
ct = QgsCoordinateTransform( vlayer->crs(), vectorLayer->crs(), vectorLayer->transformContext() );
|
||||
try
|
||||
{
|
||||
bbox = ct.transformBoundingBox( bbox );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "Bounding box transformation failed, skipping topological points for layer %1" ).arg( vlayer->id() ) );
|
||||
continue;
|
||||
}
|
||||
}
|
||||
bbox.grow( getTopologicalSearchRadius( vectorLayer ) );
|
||||
request.setFilterRect( bbox );
|
||||
|
||||
// We check that there is actually at least one feature intersecting our geometry in the layer to avoid creating an empty edit command and calling costly addTopologicalPoint
|
||||
if ( !vectorLayer->getFeatures( request ).nextFeature( f ) )
|
||||
continue;
|
||||
|
||||
vectorLayer->beginEditCommand( QObject::tr( "Topological points added by '%1'" ).arg( toolName ) );
|
||||
|
||||
int returnValue = 2;
|
||||
if ( vectorLayer->crs() != vlayer->crs() )
|
||||
{
|
||||
try
|
||||
{
|
||||
// transform digitized geometry from vlayer crs to vectorLayer crs and add topological points
|
||||
QgsGeometry transformedGeom( geom );
|
||||
transformedGeom.transform( ct );
|
||||
returnValue = vectorLayer->addTopologicalPoints( transformedGeom );
|
||||
}
|
||||
catch ( QgsCsException & )
|
||||
{
|
||||
QgsDebugError( QStringLiteral( "transformation to vectorLayer coordinate failed" ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
returnValue = vectorLayer->addTopologicalPoints( geom );
|
||||
}
|
||||
|
||||
if ( returnValue == 0 )
|
||||
{
|
||||
vectorLayer->endEditCommand();
|
||||
}
|
||||
else
|
||||
{
|
||||
// the layer was not modified, leave the undo buffer intact
|
||||
vectorLayer->destroyEditCommand();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
///@endcond
|
||||
|
||||
Qgis::GeometryOperationResult QgsVectorLayerEditUtils::addRing( const QVector<QgsPointXY> &ring, const QgsFeatureIds &targetFeatureIds, QgsFeatureId *modifiedFeatureId )
|
||||
|
||||
@ -284,6 +284,8 @@ class CORE_EXPORT QgsVectorLayerEditUtils
|
||||
|
||||
///@cond PRIVATE
|
||||
static double getTopologicalSearchRadius( const QgsVectorLayer *layer ) SIP_SKIP;
|
||||
|
||||
static void addTopologicalPointsToLayers( const QgsGeometry &geom, QgsVectorLayer *vlayer, const QList<QgsMapLayer *> &layers, const QString &toolName ) SIP_SKIP;
|
||||
///@endcond
|
||||
|
||||
private:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user