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 );
109 relation.updateRelationStatus();
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 );
146 updateRelationStatus();
152 d->mRelationName =
name;
165 d->mReferencingLayerId =
id;
167 updateRelationStatus();
173 d->mReferencedLayerId =
id;
175 updateRelationStatus();
181 d->mFieldPairs <<
FieldPair( referencingField, referencedField );
182 updateRelationStatus();
188 d->mFieldPairs << fieldPair;
189 updateRelationStatus();
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() );
275 updateRelationStatus();
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();
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 )
356 void QgsRelation::updateRelationStatus()
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.
QString getRelatedFeaturesFilter(const QgsFeature &feature) const
Returns a filter expression which returns all the features on the referencing (child) layer which hav...
void generateId()
Generate a (project-wide) unique id for this relation.
QgsMapLayer::LayerType type() const
Returns the type of the layer.
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.
Q_INVOKABLE QString resolveReferencingField(const QString &referencedField) const
Gets the referencing field counterpart given a referenced field.
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.
QString name() const
Returns a human readable name for this relation.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QString referencingLayerId() const
Access the referencing (child) layer's id This is the layer which has the field(s) which point to ano...
QgsAttributeList referencedFields() const
Returns a list of attributes used to form the referenced fields (most likely primary key) on the refe...
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...
QString id() const
A (project-wide) unique id for this relation.
void writeXml(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
void setId(const QString &id)
Set an id for this relation.
Q_INVOKABLE QString resolveReferencedField(const QString &referencingField) const
Gets the referenced field counterpart given a referencing field.
void setStrength(RelationStrength strength)
Set a strength for this relation.
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set the filter expression.
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.
QgsFeature getReferencedFeature(const QgsFeature &feature) const
Creates a request to return the feature on the referenced (parent) layer which is referenced by the p...
#define QgsDebugMsgLevel(str, level)
const QgsProjectTranslator * projectTranslator() const
Returns the project translator.
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
static QString createFieldEqualityExpression(const QString &fieldName, const QVariant &value)
Create an expression allowing to evaluate if a field is equal to a value.
QString referencedLayerId() const
Access the referenced (parent) layer's id.
void setReferencedLayer(const QString &id)
Set the referenced (parent) layer id.
int indexFromName(const QString &fieldName) const
Gets the field index from the field name.
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing (ch...
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
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.
bool hasEqualDefinition(const QgsRelation &other) const
Compares the two QgsRelation, ignoring the name and the ID.
RelationStrength
enum for the relation strength Association, Composition
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
QgsFeatureIterator getRelatedFeatures(const QgsFeature &feature) const
Creates an iterator which returns all the features on the referencing (child) layer which have a fore...
static QgsProject * instance()
Returns the QgsProject singleton instance.
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
QList< QgsRelation::FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names o...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Query the layer for features specified in request.
QList< int > QgsAttributeList
Represents a vector layer which manages a vector based data sets.
QgsRelation & operator=(const QgsRelation &other)
Copies a relation.
QMap< QString, QgsMapLayer * > mapLayers() const
Returns a map of all registered layers by layer ID.