QGIS API Documentation  2.2.0-Valmiera
 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 }