26 : d( new QgsRelationPrivate() )
45 QDomElement elem = node.toElement();
47 if ( elem.tagName() != QLatin1String(
"relation" ) )
49 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
55 QString
referencedLayerId = elem.attribute( QStringLiteral(
"referencedLayer" ) );
56 QString
id = elem.attribute( QStringLiteral(
"id" ) );
58 QString
strength = elem.attribute( QStringLiteral(
"strength" ) );
65 if ( !referencingLayer )
67 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) );
71 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) );
74 if ( !referencedLayer )
76 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) );
80 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
87 relation.d->mRelationId =
id;
88 relation.d->mRelationName =
name;
89 if ( strength == QLatin1String(
"Composition" ) )
91 relation.d->mRelationStrength = RelationStrength::Composition;
95 relation.d->mRelationStrength = RelationStrength::Association;
98 QDomNodeList references = elem.elementsByTagName( QStringLiteral(
"fieldRef" ) );
99 for (
int i = 0; i < references.size(); ++i )
101 QDomElement refEl = references.at( i ).toElement();
103 QString referencingField = refEl.attribute( QStringLiteral(
"referencingField" ) );
104 QString referencedField = refEl.attribute( QStringLiteral(
"referencedField" ) );
106 relation.
addFieldPair( referencingField, referencedField );
116 QDomElement elem = doc.createElement( QStringLiteral(
"relation" ) );
117 elem.setAttribute( QStringLiteral(
"id" ), d->mRelationId );
118 elem.setAttribute( QStringLiteral(
"name" ), d->mRelationName );
119 elem.setAttribute( QStringLiteral(
"referencingLayer" ), d->mReferencingLayerId );
120 elem.setAttribute( QStringLiteral(
"referencedLayer" ), d->mReferencedLayerId );
121 if ( d->mRelationStrength == RelationStrength::Composition )
123 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Composition" ) );
127 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Association" ) );
130 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
132 QDomElement referenceElem = doc.createElement( QStringLiteral(
"fieldRef" ) );
133 referenceElem.setAttribute( QStringLiteral(
"referencingField" ), pair.first );
134 referenceElem.setAttribute( QStringLiteral(
"referencedField" ), pair.second );
135 elem.appendChild( referenceElem );
138 node.appendChild( elem );
152 d->mRelationName =
name;
165 d->mReferencingLayerId =
id;
173 d->mReferencedLayerId =
id;
181 d->mFieldPairs <<
FieldPair( referencingField, referencedField );
188 d->mFieldPairs << fieldPair;
200 QgsDebugMsg( QStringLiteral(
"Filter conditions: '%1'" ).arg( filter ) );
209 QStringList conditions;
211 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
213 QVariant val( feature.
attribute( pair.referencedField() ) );
217 return conditions.join( QStringLiteral(
" AND " ) );
222 QStringList conditions;
224 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
232 QgsDebugMsg( QStringLiteral(
"Filter conditions: '%1'" ).arg( conditions.join(
" AND " ) ) );
234 myRequest.setFilterExpression( conditions.join( QStringLiteral(
" AND " ) ) );
249 d->mReferencedLayer->getFeatures( request ).nextFeature( f );
255 return d->mRelationName;
260 return d->mRelationStrength;
265 return d->mRelationId;
270 d->mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
272 d->mFieldPairs.at( 0 ).referencingField(),
274 d->mFieldPairs.at( 0 ).referencedField() );
280 return d->mReferencingLayerId;
285 return d->mReferencingLayer;
290 return d->mReferencedLayerId;
295 return d->mReferencedLayer;
300 return d->mFieldPairs;
307 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
309 attrs << d->mReferencedLayer->fields().lookupField( pair.second );
318 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
320 attrs << d->mReferencingLayer->fields().lookupField( pair.first );
328 return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayer.isNull() && d->mReferencingLayer.data()->isValid() && d->mReferencedLayer.data()->isValid();
333 return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
338 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
340 if ( pair.first == referencingField )
348 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
350 if ( pair.second == referencedField )
360 d->mReferencingLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
361 d->mReferencedLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );
365 if ( d->mRelationId.isEmpty() )
367 QgsDebugMsg( QStringLiteral(
"Invalid relation: no ID" ) );
372 if ( !d->mReferencedLayer )
374 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
377 else if ( !d->mReferencingLayer )
379 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
384 if ( d->mFieldPairs.count() < 1 )
386 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: no pair of field is specified." ), 4 );
390 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
392 if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) )
394 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
398 else if ( -1 == d->mReferencedLayer->fields().lookupField( pair.second ) )
400 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencedg layer %2" ).arg( pair.second, d->mReferencedLayer->name() ) );
The class is used as a container of context for various read/write operations on other objects...
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
Base class for all map layer types.
void generateId()
Generate a (project-wide) unique id for this relation.
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing (ch...
static void warning(const QString &msg)
Goes to qWarning.
void setReferencingLayer(const QString &id)
Set the referencing (child) layer id.
static QgsRelation createFromXml(const QDomNode &node, QgsReadWriteContext &context)
Creates a relation from an XML structure.
QgsRelation()
Default constructor.
void addFieldPair(const QString &referencingField, const QString &referencedField)
Add a field pairs which is part of this relation The first element of each pair are the field names o...
void setName(const QString &name)
Set a name for this relation.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsMapLayer::LayerType type() const
Returns the type of the layer.
QString id() const
A (project-wide) unique id for this relation.
void setId(const QString &id)
Set an id for this relation.
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
void setStrength(RelationStrength strength)
Set a strength for this relation.
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
RelationStrength strength() const
Returns the relation strength as a string.
QgsFeatureRequest getReferencedFeatureRequest(const QgsAttributes &attributes) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
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.
#define QgsDebugMsgLevel(str, level)
Q_INVOKABLE QString resolveReferencedField(const QString &referencingField) const
Gets the referenced field counterpart given a referencing field.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
Q_INVOKABLE QString resolveReferencingField(const QString &referencedField) const
Gets the referencing field counterpart given a referenced field.
bool hasEqualDefinition(const QgsRelation &other) const
Compares the two QgsRelation, ignoring the name and the ID.
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
QMap< QString, QgsMapLayer * > mapLayers(const bool validOnly=false) const
Returns a map of all registered layers by layer ID.
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
virtual QString translate(const QString &context, const QString &sourceText, const char *disambiguation=nullptr, int n=-1) const =0
The derived translate() translates with QTranslator and qm file the sourceText.
QgsFeatureIterator getRelatedFeatures(const QgsFeature &feature) const
Creates an iterator which returns all the features on the referencing (child) layer which have a fore...
QString referencingLayerId() const
Access the referencing (child) layer's id This is the layer which has the field(s) which point to ano...
RelationStrength
enum for the relation strength Association, Composition
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QList< int > QgsAttributeList
QgsFeature getReferencedFeature(const QgsFeature &feature) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
Represents a vector layer which manages a vector based data sets.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QgsRelation & operator=(const QgsRelation &other)
Copies a relation.
QString referencedLayerId() const
Access the referenced (parent) layer's id.
void writeXml(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
QString name() const
Returns a human readable name for this relation.
void updateRelationStatus()
Updates the validity status of this relation.