mirror of
https://github.com/qgis/QGIS.git
synced 2025-10-09 00:08:52 -04:00
fix duplication of feature being stopped at 1 level deep (#39550)
This commit is contained in:
parent
cf37cb94f3
commit
9db2d79244
@ -204,18 +204,21 @@ automatically inserted into the layer.
|
|||||||
.. versionadded:: 3.6
|
.. versionadded:: 3.6
|
||||||
%End
|
%End
|
||||||
|
|
||||||
static QgsFeature duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext /Out/ );
|
static QgsFeature duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext /Out/, const int maxDepth = 0 );
|
||||||
%Docstring
|
%Docstring
|
||||||
Duplicates a feature and it's children (one level deep). It calls CreateFeature, so
|
Duplicates a feature and it's children (one level deep). It calls CreateFeature, so
|
||||||
default values and constraints (e.g., unique constraints) will automatically be handled.
|
default values and constraints (e.g., unique constraints) will automatically be handled.
|
||||||
The duplicated feature will be automatically inserted into the layer.
|
The duplicated feature will be automatically inserted into the layer.
|
||||||
``depth`` the higher this number the deeper the level - With depth > 0 the children of the feature are not duplicated
|
|
||||||
``duplicateFeatureContext`` stores all the layers and the featureids of the duplicated features (incl. children)
|
``duplicateFeatureContext`` stores all the layers and the featureids of the duplicated features (incl. children)
|
||||||
|
``maxDepth`` the maximum depth to duplicate children in relations, 0 is unlimited depth (in any case, limited to 100)
|
||||||
|
``depth`` the current depth, not exposed in Python
|
||||||
|
``referencedLayersBranch`` the current branch of layers across the relations, not exposed in Python, taken by copy not reference, used to avoid infinite loop
|
||||||
|
|
||||||
.. versionadded:: 3.0
|
.. versionadded:: 3.0
|
||||||
%End
|
%End
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
|
static void matchAttributesToFields( QgsFeature &feature, const QgsFields &fields );
|
||||||
%Docstring
|
%Docstring
|
||||||
Matches the attributes in ``feature`` to the specified ``fields``.
|
Matches the attributes in ``feature`` to the specified ``fields``.
|
||||||
|
@ -16478,7 +16478,7 @@ QgsFeature QgisApp::duplicateFeatures( QgsMapLayer *mlayer, const QgsFeature &fe
|
|||||||
{
|
{
|
||||||
QgsVectorLayerUtils::QgsDuplicateFeatureContext duplicateFeatureContext;
|
QgsVectorLayerUtils::QgsDuplicateFeatureContext duplicateFeatureContext;
|
||||||
|
|
||||||
QgsVectorLayerUtils::duplicateFeature( layer, f, QgsProject::instance(), 0, duplicateFeatureContext );
|
QgsVectorLayerUtils::duplicateFeature( layer, f, QgsProject::instance(), duplicateFeatureContext );
|
||||||
featureCount += 1;
|
featureCount += 1;
|
||||||
|
|
||||||
const auto duplicatedFeatureContextLayers = duplicateFeatureContext.layers();
|
const auto duplicatedFeatureContextLayers = duplicateFeatureContext.layers();
|
||||||
@ -16529,7 +16529,7 @@ QgsFeature QgisApp::duplicateFeatureDigitized( QgsMapLayer *mlayer, const QgsFea
|
|||||||
|
|
||||||
QgsFeature newFeature = feature;
|
QgsFeature newFeature = feature;
|
||||||
newFeature.setGeometry( digitizedFeature.geometry() );
|
newFeature.setGeometry( digitizedFeature.geometry() );
|
||||||
QgsVectorLayerUtils::duplicateFeature( layer, newFeature, QgsProject::instance(), 0, duplicateFeatureContext );
|
QgsVectorLayerUtils::duplicateFeature( layer, newFeature, QgsProject::instance(), duplicateFeatureContext );
|
||||||
|
|
||||||
QString childrenInfo;
|
QString childrenInfo;
|
||||||
const auto duplicateFeatureContextLayers = duplicateFeatureContext.layers();
|
const auto duplicateFeatureContextLayers = duplicateFeatureContext.layers();
|
||||||
|
@ -42,6 +42,7 @@
|
|||||||
#include "qgsstyle.h"
|
#include "qgsstyle.h"
|
||||||
#include "qgsauxiliarystorage.h"
|
#include "qgsauxiliarystorage.h"
|
||||||
|
|
||||||
|
|
||||||
QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
|
QgsFeatureIterator QgsVectorLayerUtils::getValuesIterator( const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly )
|
||||||
{
|
{
|
||||||
std::unique_ptr<QgsExpression> expression;
|
std::unique_ptr<QgsExpression> expression;
|
||||||
@ -622,7 +623,7 @@ QgsFeatureList QgsVectorLayerUtils::createFeatures( const QgsVectorLayer *layer,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext )
|
QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext, const int maxDepth, int depth, QList<QgsVectorLayer *> referencedLayersBranch )
|
||||||
{
|
{
|
||||||
if ( !layer )
|
if ( !layer )
|
||||||
return QgsFeature();
|
return QgsFeature();
|
||||||
@ -639,12 +640,16 @@ QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const Q
|
|||||||
|
|
||||||
const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
|
const QList<QgsRelation> relations = project->relationManager()->referencedRelations( layer );
|
||||||
|
|
||||||
|
const int effectiveMaxDepth = maxDepth > 0 ? maxDepth : 100;
|
||||||
|
|
||||||
for ( const QgsRelation &relation : relations )
|
for ( const QgsRelation &relation : relations )
|
||||||
{
|
{
|
||||||
//check if composition (and not association)
|
//check if composition (and not association)
|
||||||
if ( relation.strength() == QgsRelation::Composition && depth < 1 )
|
if ( relation.strength() == QgsRelation::Composition && !referencedLayersBranch.contains( relation.referencedLayer() ) && depth < effectiveMaxDepth )
|
||||||
{
|
{
|
||||||
depth++;
|
depth++;
|
||||||
|
referencedLayersBranch << layer;
|
||||||
|
|
||||||
//get features connected over this relation
|
//get features connected over this relation
|
||||||
QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( feature );
|
QgsFeatureIterator relatedFeaturesIt = relation.getRelatedFeatures( feature );
|
||||||
QgsFeatureIds childFeatureIds;
|
QgsFeatureIds childFeatureIds;
|
||||||
@ -660,7 +665,7 @@ QgsFeature QgsVectorLayerUtils::duplicateFeature( QgsVectorLayer *layer, const Q
|
|||||||
childFeature.setAttribute( fieldPair.first, newFeature.attribute( fieldPair.second ) );
|
childFeature.setAttribute( fieldPair.first, newFeature.attribute( fieldPair.second ) );
|
||||||
}
|
}
|
||||||
//call the function for the child
|
//call the function for the child
|
||||||
childFeatureIds.insert( duplicateFeature( relation.referencingLayer(), childFeature, project, depth, duplicateFeatureContext ).id() );
|
childFeatureIds.insert( duplicateFeature( relation.referencingLayer(), childFeature, project, duplicateFeatureContext, maxDepth, depth, referencedLayersBranch ).id() );
|
||||||
}
|
}
|
||||||
|
|
||||||
//store for feedback
|
//store for feedback
|
||||||
@ -827,6 +832,9 @@ QgsFeatureIds QgsVectorLayerUtils::QgsDuplicateFeatureContext::duplicatedFeature
|
|||||||
|
|
||||||
void QgsVectorLayerUtils::QgsDuplicateFeatureContext::setDuplicatedFeatures( QgsVectorLayer *layer, const QgsFeatureIds &ids )
|
void QgsVectorLayerUtils::QgsDuplicateFeatureContext::setDuplicatedFeatures( QgsVectorLayer *layer, const QgsFeatureIds &ids )
|
||||||
{
|
{
|
||||||
|
if ( mDuplicatedFeatures.contains( layer ) )
|
||||||
|
mDuplicatedFeatures[layer] += ids;
|
||||||
|
else
|
||||||
mDuplicatedFeatures.insert( layer, ids );
|
mDuplicatedFeatures.insert( layer, ids );
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
@ -205,11 +205,14 @@ class CORE_EXPORT QgsVectorLayerUtils
|
|||||||
* Duplicates a feature and it's children (one level deep). It calls CreateFeature, so
|
* Duplicates a feature and it's children (one level deep). It calls CreateFeature, so
|
||||||
* default values and constraints (e.g., unique constraints) will automatically be handled.
|
* default values and constraints (e.g., unique constraints) will automatically be handled.
|
||||||
* The duplicated feature will be automatically inserted into the layer.
|
* The duplicated feature will be automatically inserted into the layer.
|
||||||
* \a depth the higher this number the deeper the level - With depth > 0 the children of the feature are not duplicated
|
|
||||||
* \a duplicateFeatureContext stores all the layers and the featureids of the duplicated features (incl. children)
|
* \a duplicateFeatureContext stores all the layers and the featureids of the duplicated features (incl. children)
|
||||||
|
* \a maxDepth the maximum depth to duplicate children in relations, 0 is unlimited depth (in any case, limited to 100)
|
||||||
|
* \a depth the current depth, not exposed in Python
|
||||||
|
* \a referencedLayersBranch the current branch of layers across the relations, not exposed in Python, taken by copy not reference, used to avoid infinite loop
|
||||||
* \since QGIS 3.0
|
* \since QGIS 3.0
|
||||||
*/
|
*/
|
||||||
static QgsFeature duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext SIP_OUT );
|
static QgsFeature duplicateFeature( QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, QgsDuplicateFeatureContext &duplicateFeatureContext SIP_OUT, const int maxDepth = 0, int depth SIP_PYARGREMOVE = 0, QList<QgsVectorLayer *> referencedLayersBranch SIP_PYARGREMOVE = QList<QgsVectorLayer *>() );
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the feature source from a QgsVectorLayer pointer.
|
* Gets the feature source from a QgsVectorLayer pointer.
|
||||||
|
@ -637,7 +637,7 @@ void QgsRelationEditorWidget::duplicateFeature()
|
|||||||
while ( fit.nextFeature( f ) )
|
while ( fit.nextFeature( f ) )
|
||||||
{
|
{
|
||||||
QgsVectorLayerUtils::QgsDuplicateFeatureContext duplicatedFeatureContext;
|
QgsVectorLayerUtils::QgsDuplicateFeatureContext duplicatedFeatureContext;
|
||||||
QgsVectorLayerUtils::duplicateFeature( layer, f, QgsProject::instance(), 0, duplicatedFeatureContext );
|
QgsVectorLayerUtils::duplicateFeature( layer, f, QgsProject::instance(), duplicatedFeatureContext );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user