QGIS API Documentation  2.4.0-Chugiak
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
qgsrelation.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  qgsrelation.cpp
3  --------------------------------------
4  Date : 29.4.2013
5  Copyright : (C) 2013 Matthias Kuhn
6  Email : matthias dot kuhn at gmx dot ch
7  ***************************************************************************
8  * *
9  * This program is free software; you can redistribute it and/or modify *
10  * it under the terms of the GNU General Public License as published by *
11  * the Free Software Foundation; either version 2 of the License, or *
12  * (at your option) any later version. *
13  * *
14  ***************************************************************************/
15 
16 #include "qgsrelation.h"
17 
18 #include "qgsapplication.h"
19 #include "qgslogger.h"
20 #include "qgsmaplayerregistry.h"
21 #include "qgsvectorlayer.h"
22 
24  : mReferencingLayer( NULL )
25  , mReferencedLayer( NULL )
26  , mValid( false )
27 {
28 }
29 
30 QgsRelation QgsRelation::createFromXML( const QDomNode &node )
31 {
32  QDomElement elem = node.toElement();
33 
34  if ( elem.tagName() != "relation" )
35  {
36  QgsLogger::warning( QApplication::translate( "QgsRelation", "Cannot create relation. Unexpected tag '%1'" ).arg( elem.tagName() ) );
37  }
38 
39  QgsRelation relation;
40 
41  QString referencingLayerId = elem.attribute( "referencingLayer" );
42  QString referencedLayerId = elem.attribute( "referencedLayer" );
43  QString id = elem.attribute( "id" );
44  QString name = elem.attribute( "name" );
45 
46  const QMap<QString, QgsMapLayer*>& mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
47 
50 
51  if ( NULL == referencingLayer )
52  {
53  QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencingLayerId ) );
54  }
55  else if ( QgsMapLayer::VectorLayer != referencingLayer->type() )
56  {
57  QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencingLayerId ) );
58  }
59 
60  if ( NULL == referencedLayer )
61  {
62  QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which does not exist." ).arg( referencedLayerId ) );
63  }
64  else if ( QgsMapLayer::VectorLayer != referencedLayer->type() )
65  {
66  QgsLogger::warning( QApplication::translate( "QgsRelation", "Relation defined for layer '%1' which is not of type VectorLayer." ).arg( referencedLayerId ) );
67  }
68 
70  relation.mReferencingLayer = qobject_cast<QgsVectorLayer*>( referencingLayer );
72  relation.mReferencedLayer = qobject_cast<QgsVectorLayer*>( referencedLayer );
73  relation.mRelationId = id;
74  relation.mRelationName = name;
75 
76  QDomNodeList references = elem.elementsByTagName( "fieldRef" );
77  for ( int i = 0; i < references.size(); ++i )
78  {
79  QDomElement refEl = references.at( i ).toElement();
80 
81  QString referencingField = refEl.attribute( "referencingField" );
82  QString referencedField = refEl.attribute( "referencedField" );
83 
84  relation.addFieldPair( referencingField, referencedField );
85  }
86 
87  relation.updateRelationStatus();
88 
89  return relation;
90 }
91 
92 void QgsRelation::writeXML( QDomNode &node, QDomDocument &doc ) const
93 {
94  QDomElement elem = doc.createElement( "relation" );
95  elem.setAttribute( "id", mRelationId );
96  elem.setAttribute( "name", mRelationName );
97  elem.setAttribute( "referencingLayer", mReferencingLayerId );
98  elem.setAttribute( "referencedLayer", mReferencedLayerId );
99 
100  foreach ( FieldPair fields, mFieldPairs )
101  {
102  QDomElement referenceElem = doc.createElement( "fieldRef" );
103  referenceElem.setAttribute( "referencingField", fields.first );
104  referenceElem.setAttribute( "referencedField", fields.second );
105  elem.appendChild( referenceElem );
106  }
107 
108  node.appendChild( elem );
109 }
110 
111 void QgsRelation::setRelationId( QString id )
112 {
113  mRelationId = id;
114 }
115 
116 void QgsRelation::setRelationName( QString name )
117 {
119 }
120 
122 {
124 
126 }
127 
129 {
131 
133 }
134 
135 void QgsRelation::addFieldPair( QString referencingField, QString referencedField )
136 {
137  mFieldPairs << FieldPair( referencingField, referencedField );
139 }
140 
142 {
143  mFieldPairs << fieldPair;
145 }
146 
148 {
150 }
151 
153 {
154  QStringList conditions;
155 
156  foreach ( const QgsRelation::FieldPair& fieldPair, mFieldPairs )
157  {
158  int referencingIdx = referencingLayer()->pendingFields().indexFromName( fieldPair.referencingField() );
159  QgsField referencingField = referencingLayer()->pendingFields().at( referencingIdx );
160 
161  switch ( referencingField.type() )
162  {
163  case QVariant::String:
164  // Use quotes
165  conditions << QString( "\"%1\" = '%2'" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
166  break;
167 
168  default:
169  // No quotes
170  conditions << QString( "\"%1\" = %2" ).arg( fieldPair.referencingField(), feature.attribute( fieldPair.referencedField() ).toString() );
171  break;
172  }
173  }
174 
175  QgsFeatureRequest myRequest;
176 
177  QgsDebugMsg( QString( "Filter conditions: '%1'" ).arg( conditions.join( " AND " ) ) );
178 
179  myRequest.setFilterExpression( conditions.join( " AND " ) );
180 
181  return myRequest;
182 }
183 
184 const QString QgsRelation::name() const
185 {
186  return mRelationName;
187 }
188 
189 const QString& QgsRelation::id() const
190 {
191  return mRelationId;
192 }
193 
195 {
196  return mReferencingLayerId;
197 }
198 
200 {
201  return mReferencingLayer;
202 }
203 
205 {
206  return mReferencedLayerId;
207 }
208 
210 {
211  return mReferencedLayer;
212 }
213 
214 QList<QgsRelation::FieldPair> QgsRelation::fieldPairs() const
215 {
216  return mFieldPairs;
217 }
218 
220 {
221  return mValid;
222 }
223 
225 {
226  const QMap<QString, QgsMapLayer*>& mapLayers = QgsMapLayerRegistry::instance()->mapLayers();
227 
228  mReferencingLayer = qobject_cast<QgsVectorLayer*>( mapLayers[mReferencingLayerId] );
229  mReferencedLayer = qobject_cast<QgsVectorLayer*>( mapLayers[mReferencedLayerId] );
230 
231  mValid = true;
232 
233  if ( !mReferencedLayer || !mReferencingLayer )
234  {
235  mValid = false;
236  }
237  else
238  {
239  if ( mFieldPairs.count() < 1 )
240  {
241  mValid = false;
242  }
243 
244  Q_FOREACH( const FieldPair& fieldPair, mFieldPairs )
245  {
246  if ( -1 == mReferencingLayer->fieldNameIndex( fieldPair.first )
247  || -1 == mReferencedLayer->fieldNameIndex( fieldPair.second ) )
248  {
249  mValid = false;
250  }
251  }
252  }
253 }
254 
256 {
257 
258 }
void setRelationId(QString id)
Set a name for this relation.
Wrapper for iterator of features from vector data provider or vector layer.
bool isValid() const
Returns the validity of this relation.
const QString name() const
Base class for all map layer types.
Definition: qgsmaplayer.h:47
QgsMapLayer::LayerType type() const
Get the type of the layer.
Definition: qgsmaplayer.cpp:86
void setRelationName(QString name)
Set a name for this relation.
#define QgsDebugMsg(str)
Definition: qgslogger.h:36
static void warning(const QString &msg)
Goes to qWarning.
Definition: qgslogger.cpp:162
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
QgsRelation()
Default constructor.
Definition: qgsrelation.cpp:23
QgsVectorLayer * referencedLayer() const
Access the referenced (parent) layer.
static QgsRelation createFromXML(const QDomNode &node)
Creates a relation from an XML structure.
Definition: qgsrelation.cpp:30
void setReferencingLayer(QString id)
Set the referencing layer id.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Definition: qgsfield.h:208
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
Definition: qgsfeature.h:113
QString referencingLayerId() const
Access the referencing (child) layer's id This is the layer which has the field(s) which point to ano...
void writeXML(QDomNode &node, QDomDocument &doc) const
Writes a relation to an XML structure.
Definition: qgsrelation.cpp:92
QgsFeatureRequest & setFilterExpression(const QString &expression)
Set filter expression. {.
void setReferencedLayer(QString id)
Set the referenced layer id.
Defines a relation between matchin fields of the two involved tables of a relation.
Definition: qgsrelation.h:38
QString mRelationId
Unique Id.
Definition: qgsrelation.h:205
const QString & id() const
The id.
QgsVectorLayer * referencingLayer() const
Access the referencing (child) layer This is the layer which has the field(s) which point to another ...
void runChecks()
This class wraps a request for features to a vector layer (or directly its vector data provider)...
QgsVectorLayer * mReferencingLayer
The child layer.
Definition: qgsrelation.h:211
Encapsulate a field in an attribute table or data source.
Definition: qgsfield.h:31
QgsFeatureRequest getRelatedFeaturesRequest(const QgsFeature &feature) const
Creates a request to return all the features on the referencing (child) layer which have a foreign ke...
QString referencedLayerId() const
Access the referenced (parent) layer's id.
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
Definition: qgsfield.h:220
const QString & referencingField() const
Get the name of the referencing field.
Definition: qgsrelation.h:50
QString mRelationName
Human redable name.
Definition: qgsrelation.h:207
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QVariant attribute(const QString &name) const
Lookup attribute value from attribute name.
Definition: qgsfeature.cpp:230
QString mReferencedLayerId
The parent layer id.
Definition: qgsrelation.h:213
QgsFeatureIterator getRelatedFeatures(const QgsFeature &feature) const
Creates an iterator which returns all the features on the referencing (child) layer which have a fore...
QString mReferencingLayerId
The child layer.
Definition: qgsrelation.h:209
const QMap< QString, QgsMapLayer * > & mapLayers()
Retrieve the mapLayers collection (mainly intended for use by projection)
QgsVectorLayer * mReferencedLayer
The parent layer.
Definition: qgsrelation.h:215
void addFieldPair(QString referencingField, QString referencedField)
Add a field pairs which is part of this relation The first element of each pair are the field names f...
QList< FieldPair > fieldPairs() const
Returns the field pairs which form this relation The first element of each pair are the field names f...
const QgsFields & pendingFields() const
returns field list in the to-be-committed state
Represents a vector layer which manages a vector based data sets.
int fieldNameIndex(const QString &fieldName) const
Returns the index of a field name or -1 if the field does not exist.
const QString & referencedField() const
Get the name of the referenced field.
Definition: qgsrelation.h:52
void updateRelationStatus()
QVariant::Type type() const
Gets variant type of the field as it will be retrieved from data source.
Definition: qgsfield.cpp:63
QList< FieldPair > mFieldPairs
A list of fields which define the relation.
Definition: qgsrelation.h:220