16 #include <QRegularExpression> 38 std::unique_ptr<QgsExpression> expression;
48 if ( expression->hasParserError() || !expression->prepare( &context ) )
57 lst.insert( fieldOrExpression );
59 lst = expression->referencedColumns();
62 .
setFlags( ( expression && expression->needsGeometry() ) ?
80 QList<QVariant> values;
84 std::unique_ptr<QgsExpression> expression;
101 QVariant v = expression->evaluate( &context );
120 QList<double> values;
125 QList<QVariant> variantValues =
getValues( layer, fieldOrExpression, ok, selectedOnly, feedback );
130 Q_FOREACH (
const QVariant &value, variantValues )
132 double val = value.toDouble( &convertOk );
135 else if ( value.isNull() )
156 if ( fieldIndex < 0 || fieldIndex >= fields.
count() )
159 QString fieldName = fields.
at( fieldIndex ).
name();
167 int limit = ignoreIds.size() + 1;
177 if ( ignoreIds.contains( feat.
id() ) )
193 if ( fieldIndex < 0 || fieldIndex >= fields.
count() )
201 QVariant newVar( maxVal.toLongLong() + 1 );
209 switch ( field.
type() )
211 case QVariant::String:
214 if ( seed.isValid() )
215 base = seed.toString();
217 if ( !base.isEmpty() )
220 QRegularExpression rx( QStringLiteral(
"(.*)_\\d+" ) );
221 QRegularExpressionMatch match = rx.match( base );
222 if ( match.hasMatch() )
224 base = match.captured( 1 );
236 base = f.
attribute( fieldIndex ).toString();
243 if ( !base.isEmpty() && !vals.contains( base ) )
246 for (
int i = 1; i < 10000; ++i )
248 QString testVal = base +
'_' + QString::number( i );
249 if ( !vals.contains( testVal ) )
272 if ( attributeIndex < 0 || attributeIndex >= layer->
fields().
count() )
277 QVariant value = feature.
attribute( attributeIndex );
292 valid = expr.
evaluate( &context ).toBool();
294 if ( expr.hasParserError() )
296 errors << QObject::tr(
"parser error: %1" ).arg( expr.parserErrorString() );
298 else if ( expr.hasEvalError() )
300 errors << QObject::tr(
"evaluation error: %1" ).arg( expr.evalErrorString() );
322 valid = valid && !value.isNull();
324 if ( value.isNull() )
326 errors << QObject::tr(
"value is NULL" );
346 valid = valid && !alreadyExists;
350 errors << QObject::tr(
"value is not unique" );
367 std::unique_ptr< QgsExpressionContext > tempContext;
372 evalContext = tempContext.get();
383 for (
int idx = 0; idx < fields.
count(); ++idx )
386 bool checkUnique =
true;
391 if ( attributes.contains( idx ) )
393 v = attributes.value( idx );
404 v = layer->
defaultValue( idx, newFeature, evalContext );
414 if ( !providerDefault.isEmpty() )
437 if ( v.isNull() && attributes.contains( idx ) )
439 v = attributes.value( idx );
445 if ( checkUnique && hasUniqueConstraint )
451 if ( uniqueValue.isValid() )
488 while ( relatedFeaturesIt.
nextFeature( childFeature ) )
491 relation.referencingLayer()->startEditing();
493 const auto pairs = relation.fieldPairs();
499 childFeatureIds.insert(
duplicateFeature( relation.referencingLayer(), childFeature, project, depth, duplicateFeatureContext ).
id() );
503 duplicateFeatureContext.setDuplicatedFeatures( relation.referencingLayer(), childFeatureIds );
514 std::unique_ptr<QgsVectorLayerFeatureSource> featureSource;
518 #if QT_VERSION >= QT_VERSION_CHECK( 5, 10, 0 ) 519 Q_ASSERT( QThread::currentThread() == qApp->thread() || feedback );
533 return featureSource;
541 attributes.reserve( fields.
size() );
543 for (
const QgsField &field : fields )
546 attributes.append( index >= 0 ? feature.
attribute( index ) : QVariant( field.type() ) );
554 if ( lengthDiff > 0 )
560 else if ( lengthDiff < 0 )
564 attributes.reserve( fields.
count() );
567 attributes.append( QVariant( fields.
at( i ).
type() ) );
583 bool newFHasGeom = newFGeomType !=
584 QgsWkbTypes::GeometryType::UnknownGeometry &&
585 newFGeomType != QgsWkbTypes::GeometryType::NullGeometry;
586 bool layerHasGeom = inputWkbType !=
587 QgsWkbTypes::Type::NoGeometry &&
588 inputWkbType != QgsWkbTypes::Type::Unknown;
590 if ( newFHasGeom && ! layerHasGeom )
594 resultFeatures.append( _f );
599 if ( newFHasGeom && layerHasGeom && newF.
geometry().
wkbType() != inputWkbType )
624 std::unique_ptr< QgsAbstractGeometry > exterior( ( *part )->clone() );
625 if (
QgsCurve *curve = qgsgeometry_cast< QgsCurve * >( exterior.get() ) )
629 std::unique_ptr< QgsCurvePolygon > cp = qgis::make_unique< QgsCurvePolygon >();
630 cp->setExteriorRing( curve );
632 gc->addGeometry( cp.release() );
636 std::unique_ptr< QgsPolygon > p = qgis::make_unique< QgsPolygon >();
637 p->setExteriorRing( qgsgeometry_cast< QgsLineString * >( curve ) );
639 gc->addGeometry( p.release() );
653 std::unique_ptr< QgsMultiPoint > mp = qgis::make_unique< QgsMultiPoint >();
655 QSet< QgsPoint > added;
656 for (
auto vertex = source.vertices_begin(); vertex != source.vertices_end(); ++vertex )
658 if ( added.contains( *vertex ) )
660 mp->addGeometry( ( *vertex ).clone() );
661 added.insert( *vertex );
704 const QgsGeometryCollection *parts( static_cast< const QgsGeometryCollection * >( newGeom.constGet() ) );
710 resultFeatures.reserve( parts->partCount() );
711 for (
int i = 0; i < parts->partCount( ); i++ )
715 resultFeatures.append( _f );
720 resultFeatures.append( newF );
725 resultFeatures.append( newF );
728 return resultFeatures;
737 for (
const auto &_f : features )
739 resultFeatures.append( _f );
742 return resultFeatures;
747 QList<QgsVectorLayer *> layers;
748 QMap<QgsVectorLayer *, QgsFeatureIds>::const_iterator i;
749 for ( i = mDuplicatedFeatures.begin(); i != mDuplicatedFeatures.end(); ++i )
750 layers.append( i.key() );
756 return mDuplicatedFeatures[layer];
761 mDuplicatedFeatures.insert( layer, ids );
Class for parsing and evaluation of expressions (formerly called "search strings").
Wrapper for iterator of features from vector data provider or vector layer.
bool isCanceled() const
Tells whether the operation has been canceled already.
QSet< QgsFeatureId > QgsFeatureIds
static bool valueExists(const QgsVectorLayer *layer, int fieldIndex, const QVariant &value, const QgsFeatureIds &ignoreIds=QgsFeatureIds())
Returns true if the specified value already exists within a field.
static QString quotedColumnRef(QString name)
Returns a quoted column reference (in double quotes)
static std::unique_ptr< QgsVectorLayerFeatureSource > getFeatureSource(QPointer< QgsVectorLayer > layer, QgsFeedback *feedback=nullptr)
Gets the feature source from a QgsVectorLayer pointer.
static bool isMultiType(Type type)
Returns true if the WKB type is a multi type.
Contains mainly the QMap with QgsVectorLayer and QgsFeatureIds do list all the duplicated features...
QgsWkbTypes::Type wkbType() const FINAL
Returns the WKBType or WKBUnknown in case of error.
void setFeature(const QgsFeature &feature)
Convenience function for setting a feature for the context.
QList< QgsFeature > QgsFeatureList
ConstraintOrigin
Origin of constraints.
static QList< double > getDoubleValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, int *nullCount=nullptr, QgsFeedback *feedback=nullptr)
Fetches all double values from a specified field name or expression.
QVariant evaluate()
Evaluate the feature and return the result.
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
static std::unique_ptr< QgsGeometryCollection > createCollectionOfType(QgsWkbTypes::Type type)
Returns a new geometry collection matching a specified WKB type.
QString constraintDescription() const
Returns the descriptive name for the constraint expression.
Container of fields for a vector layer.
virtual bool addMValue(double mValue=0)=0
Adds a measure to the geometry, initialized to a preset value.
A geometry is the spatial representation of a feature.
void setAttributes(const QgsAttributes &attrs)
Sets the feature's attributes.
bool setAttribute(int field, const QVariant &attr)
Set an attribute's value by field index.
QList< QgsVectorLayer * > layers() const
Returns all the layers on which features have been duplicated.
static QList< QVariant > getValues(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly=false, QgsFeedback *feedback=nullptr)
Fetches all values from a specified field name or expression.
virtual QgsAbstractGeometry * boundary() const =0
Returns the closure of the combinatorial boundary of the geometry (ie the topological boundary of the...
Stores information about constraints which may be present on a field.
Field comes from the underlying data provider of the vector layer (originIndex = index in provider's ...
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
static bool validateAttribute(const QgsVectorLayer *layer, const QgsFeature &feature, int attributeIndex, QStringList &errors, QgsFieldConstraints::ConstraintStrength strength=QgsFieldConstraints::ConstraintStrengthNotSet, QgsFieldConstraints::ConstraintOrigin origin=QgsFieldConstraints::ConstraintOriginNotSet)
Tests an attribute value to check whether it passes all constraints which are present on the correspo...
QgsField at(int i) const
Gets field at particular index (must be in range 0..N-1)
static bool hasZ(Type type)
Tests whether a WKB type contains the z-dimension.
static QgsFeatureIterator getValuesIterator(const QgsVectorLayer *layer, const QString &fieldOrExpression, bool &ok, bool selectedOnly)
Create a feature iterator for a specified field name or expression.
Constraint was set at data provider.
Field has an expression constraint set. See constraintExpression().
Base class for feedback objects to be used for cancellation of something running in a worker thread...
bool isEditable() const FINAL
Returns true if the provider is in editing mode.
const QgsAbstractGeometry * constGet() const
Returns a non-modifiable (const) reference to the underlying abstract geometry primitive.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
Type
The WKB type describes the number of dimensions a geometry has.
bool isMeasure() const
Returns true if the geometry contains m values.
QgsFields fields() const FINAL
Returns the list of fields of this layer.
Defines a relation between matching fields of the two involved tables of a relation.
virtual QgsAbstractGeometry * segmentize(double tolerance=M_PI/180., SegmentationToleranceType toleranceType=MaximumAngle) const
Returns a version of the geometry without curves.
static void matchAttributesToFields(QgsFeature &feature, const QgsFields &fields)
Matches the attributes in feature to the specified fields.
QgsFeatureRequest & setNoAttributes()
Set that no attributes will be fetched.
void initAttributes(int fieldCount)
Initialize this feature with the given number of fields.
Expression contexts are used to encapsulate the parameters around which a QgsExpression should be eva...
static QgsFeature createFeature(const QgsVectorLayer *layer, const QgsGeometry &geometry=QgsGeometry(), const QgsAttributeMap &attributes=QgsAttributeMap(), QgsExpressionContext *context=nullptr)
Creates a new feature ready for insertion into a layer.
void seed(uint32_t value)
QMap< int, QVariant > QgsAttributeMap
int fieldOriginIndex(int fieldIdx) const
Gets field's origin index (its meaning is specific to each type of origin)
static GeometryType geometryType(Type type)
Returns the geometry type for a WKB type, e.g., both MultiPolygon and CurvePolygon would have a Polyg...
QgsFeatureIds duplicatedFeatures(QgsVectorLayer *layer) const
Returns the duplicated features in the given layer.
QStringList uniqueStringsMatching(int index, const QString &substring, int limit=-1, QgsFeedback *feedback=nullptr) const
Returns unique string values of an attribute which contain a specified subset string.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
Reads and writes project states.
int count() const
Returns number of items.
QgsAbstractGeometry::const_part_iterator const_parts_begin() const
Returns STL-style const iterator pointing to the first part of the geometry.
static QList< QgsExpressionContextScope * > globalProjectLayerScopes(const QgsMapLayer *layer)
Creates a list of three scopes: global, layer's project and layer.
QString constraintExpression() const
Returns the constraint expression for the field, if set.
Abstract base class for curved geometry type.
Encapsulate a field in an attribute table or data source.
int lookupField(const QString &fieldName) const
Looks up field's index from the field name.
QgsRelationManager relationManager
QgsExpressionContext createExpressionContext() const FINAL
This method needs to be reimplemented in all classes which implement this interface and return an exp...
static bool runOnMainThread(const Func &func, QgsFeedback *feedback=nullptr)
Guarantees that func is executed on the main thread.
ConstraintStrength constraintStrength(Constraint constraint) const
Returns the strength of a field constraint, or ConstraintStrengthNotSet if the constraint is not pres...
QgsDefaultValue defaultValueDefinition(int index) const
Returns the definition of the expression used when calculating the default value for a field...
static QgsFeatureList makeFeaturesCompatible(const QgsFeatureList &features, const QgsVectorLayer *layer)
Converts input features to be compatible with the given layer.
Partial snapshot of vector layer's state (only the members necessary for access to features) ...
QgsAbstractGeometry * get()
Returns a modifiable (non-const) reference to the underlying abstract geometry primitive.
static QVariant createUniqueValue(const QgsVectorLayer *layer, int fieldIndex, const QVariant &seed=QVariant())
Returns a new attribute value for the specified field index which is guaranteed to be unique...
GeometryType
The geometry types are used to group QgsWkbTypes::Type in a coarse way.
void setValid(bool validity)
Sets the validity of the feature.
QList< QgsRelation > referencedRelations(QgsVectorLayer *layer=nullptr) const
Gets all relations where this layer is the referenced part (i.e.
QgsFieldConstraints constraints
QgsAbstractGeometry::const_part_iterator const_parts_end() const
Returns STL-style iterator pointing to the imaginary part after the last part of the geometry...
bool convertToMultiType()
Converts single type geometry into multitype geometry e.g.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
bool convertCompatible(QVariant &v) const
Converts the provided variant to a compatible format.
ConstraintStrength
Strength of constraints.
static QgsFeature duplicateFeature(QgsVectorLayer *layer, const QgsFeature &feature, QgsProject *project, int depth, QgsDuplicateFeatureContext &duplicateFeatureContext)
Duplicates a feature and it's children (one level deep).
static bool isCurvedType(Type type)
Returns true if the WKB type is a curved type or can contain curved geometries.
virtual bool skipConstraintCheck(int fieldIndex, QgsFieldConstraints::Constraint constraint, const QVariant &value=QVariant()) const
Returns true if a constraint check should be skipped for a specified field (e.g., if the value return...
QVariant defaultValue(int index, const QgsFeature &feature=QgsFeature(), QgsExpressionContext *context=nullptr) const
Returns the calculated default value for the specified field index.
virtual bool addZValue(double zValue=0)=0
Adds a z-dimension to the geometry, initialized to a preset value.
bool isMultipart() const
Returns true if WKB of the geometry is of WKBMulti* type.
virtual QVariant defaultValue(int fieldIndex) const
Returns any literal default values which are present at the provider for a specified field index...
QgsAttributeMap toMap() const
Returns a QgsAttributeMap of the attribute values.
void setGeometry(const QgsGeometry &geometry)
Set the feature's geometry.
int size() const
Returns number of items.
QgsFeatureIterator getSelectedFeatures(QgsFeatureRequest request=QgsFeatureRequest()) const
Returns an iterator of the selected features.
bool addFeature(QgsFeature &feature, QgsFeatureSink::Flags flags=nullptr) FINAL
Adds a single feature to the sink.
FieldOrigin fieldOrigin(int fieldIdx) const
Gets field's origin (value from an enumeration)
QgsFeatureRequest & setLimit(long limit)
Set the maximum number of features to request.
bool is3D() const
Returns true if the geometry is 3D and contains a z-value.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
static bool hasM(Type type)
Tests whether a WKB type contains m values.
QgsVectorDataProvider * dataProvider() FINAL
Returns the layer's data provider.
QList< int > QgsAttributeList
virtual bool dropMValue()=0
Drops any measure values which exist in the geometry.
void appendScopes(const QList< QgsExpressionContextScope * > &scopes)
Appends a list of scopes to the end of the context.
bool nextFeature(QgsFeature &f)
static QString quotedValue(const QVariant &value)
Returns a string representation of a literal value, including appropriate quotations where required...
static QgsFeatureList makeFeatureCompatible(const QgsFeature &feature, const QgsVectorLayer *layer)
Converts input feature to be compatible with the given layer.
Geometry is not required. It may still be returned if e.g. required for a filter condition.
virtual QString defaultValueClause(int fieldIndex) const
Returns any default value clauses which are present at the provider for a specified field index...
ConstraintOrigin constraintOrigin(Constraint constraint) const
Returns the origin of a field constraint, or ConstraintOriginNotSet if the constraint is not present ...
QVariant maximumValue(int index) const FINAL
Returns the maximum value for an attribute column or an invalid variant in case of error...
Represents a vector layer which manages a vector based data sets.
bool isEmpty() const
Checks whether the container is empty.
QgsWkbTypes::GeometryType type() const
Returns type of the geometry as a QgsWkbTypes::GeometryType.
QgsWkbTypes::Type wkbType() const
Returns type of the geometry as a WKB type (point / linestring / polygon etc.)
virtual bool dropZValue()=0
Drops any z-dimensions which exist in the geometry.
Fix relation, related elements are part of the parent and a parent copy will copy any children or del...
QgsFeatureRequest & setFlags(QgsFeatureRequest::Flags flags)
Sets flags that affect how features will be fetched.
Field must have a unique value.
bool isValid() const
Returns if this default value should be applied.