26 : d( new QgsRelationPrivate() )
31 : d( new QgsRelationPrivate() )
40 , mContext( other.mContext )
47 mContext = other.mContext;
53 QDomElement elem = node.toElement();
55 if ( elem.tagName() != QLatin1String(
"relation" ) )
57 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
63 QString
referencedLayerId = elem.attribute( QStringLiteral(
"referencedLayer" ) );
64 QString
id = elem.attribute( QStringLiteral(
"id" ) );
66 QString
strength = elem.attribute( QStringLiteral(
"strength" ) );
68 QMap<QString, QgsMapLayer *> mapLayers = relationContext.
project()->
mapLayers();
73 if ( !referencingLayer )
75 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) );
79 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) );
82 if ( !referencedLayer )
84 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) );
88 QgsLogger::warning( QApplication::translate(
"QgsRelation",
"Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
95 relation.d->mRelationId =
id;
96 relation.d->mRelationName =
name;
97 if ( strength == QLatin1String(
"Composition" ) )
99 relation.d->mRelationStrength = RelationStrength::Composition;
103 relation.d->mRelationStrength = RelationStrength::Association;
106 QDomNodeList references = elem.elementsByTagName( QStringLiteral(
"fieldRef" ) );
107 for (
int i = 0; i < references.size(); ++i )
109 QDomElement refEl = references.at( i ).toElement();
111 QString referencingField = refEl.attribute( QStringLiteral(
"referencingField" ) );
112 QString referencedField = refEl.attribute( QStringLiteral(
"referencedField" ) );
114 relation.
addFieldPair( referencingField, referencedField );
124 QDomElement elem = doc.createElement( QStringLiteral(
"relation" ) );
125 elem.setAttribute( QStringLiteral(
"id" ), d->mRelationId );
126 elem.setAttribute( QStringLiteral(
"name" ), d->mRelationName );
127 elem.setAttribute( QStringLiteral(
"referencingLayer" ), d->mReferencingLayerId );
128 elem.setAttribute( QStringLiteral(
"referencedLayer" ), d->mReferencedLayerId );
129 if ( d->mRelationStrength == RelationStrength::Composition )
131 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Composition" ) );
135 elem.setAttribute( QStringLiteral(
"strength" ), QStringLiteral(
"Association" ) );
138 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
140 QDomElement referenceElem = doc.createElement( QStringLiteral(
"fieldRef" ) );
141 referenceElem.setAttribute( QStringLiteral(
"referencingField" ), pair.first );
142 referenceElem.setAttribute( QStringLiteral(
"referencedField" ), pair.second );
143 elem.appendChild( referenceElem );
146 node.appendChild( elem );
160 d->mRelationName =
name;
173 d->mReferencingLayerId =
id;
181 d->mReferencedLayerId =
id;
189 d->mFieldPairs <<
FieldPair( referencingField, referencedField );
196 d->mFieldPairs << fieldPair;
208 QgsDebugMsg( QStringLiteral(
"Filter conditions: '%1'" ).arg( filter ) );
217 QStringList conditions;
219 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
221 QVariant val( feature.
attribute( pair.referencedField() ) );
225 return conditions.join( QStringLiteral(
" AND " ) );
230 QStringList conditions;
232 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
240 QgsDebugMsg( QStringLiteral(
"Filter conditions: '%1'" ).arg( conditions.join(
" AND " ) ) );
242 myRequest.setFilterExpression( conditions.join( QStringLiteral(
" AND " ) ) );
257 d->mReferencedLayer->getFeatures( request ).nextFeature( f );
263 return d->mRelationName;
268 return d->mRelationStrength;
273 return d->mRelationId;
278 d->mRelationId = QStringLiteral(
"%1_%2_%3_%4" )
280 d->mFieldPairs.at( 0 ).referencingField(),
282 d->mFieldPairs.at( 0 ).referencedField() );
288 return d->mReferencingLayerId;
293 return d->mReferencingLayer;
298 return d->mReferencedLayerId;
303 return d->mReferencedLayer;
308 return d->mFieldPairs;
315 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
317 attrs << d->mReferencedLayer->fields().lookupField( pair.second );
326 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
328 attrs << d->mReferencingLayer->fields().lookupField( pair.first );
336 return d->mValid && !d->mReferencingLayer.isNull() && !d->mReferencedLayer.isNull() && d->mReferencingLayer.data()->isValid() && d->mReferencedLayer.data()->isValid();
341 return d->mReferencedLayerId == other.d->mReferencedLayerId && d->mReferencingLayerId == other.d->mReferencingLayerId && d->mFieldPairs == other.d->mFieldPairs;
346 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
348 if ( pair.first == referencingField )
356 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
358 if ( pair.second == referencedField )
366 const QMap<QString, QgsMapLayer *> &mapLayers = mContext.
project()->
mapLayers();
368 d->mReferencingLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[d->mReferencingLayerId] );
369 d->mReferencedLayer = qobject_cast<
QgsVectorLayer *>( mapLayers[d->mReferencedLayerId] );
373 if ( d->mRelationId.isEmpty() )
375 QgsDebugMsg( QStringLiteral(
"Invalid relation: no ID" ) );
380 if ( !d->mReferencedLayer )
382 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referenced layer does not exist. ID: %1" ).arg( d->mReferencedLayerId ), 4 );
385 else if ( !d->mReferencingLayer )
387 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: referencing layer does not exist. ID: %2" ).arg( d->mReferencingLayerId ), 4 );
392 if ( d->mFieldPairs.count() < 1 )
394 QgsDebugMsgLevel( QStringLiteral(
"Invalid relation: no pair of field is specified." ), 4 );
398 for (
const FieldPair &pair : qgis::as_const( d->mFieldPairs ) )
400 if ( -1 == d->mReferencingLayer->fields().lookupField( pair.first ) )
402 QgsDebugMsg( QStringLiteral(
"Invalid relation: field %1 does not exist in referencing layer %2" ).arg( pair.first, d->mReferencingLayer->name() ) );
406 else if ( -1 == d->mReferencedLayer->fields().lookupField( pair.second ) )
408 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.
const QgsProject * project() const
Gets the associated project.
QgsAttributeList referencingFields() const
Returns a list of attributes used to form the referencing fields (foreign key) on the referencing (ch...
QgsMapLayerType 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.
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...
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...
static QgsRelation createFromXml(const QDomNode &node, QgsReadWriteContext &context, const QgsRelationContext &relationContext=QgsRelationContext())
Creates a relation from an XML structure.
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest()) const FINAL
Queries 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.