23 #include <QDomElement> 47 if ( mark.
value( n ) == 1 )
49 if ( mark.
value( n ) == 0 )
81 cacheJoinLayer( mVectorJoins.
last() );
90 connect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ), Qt::UniqueConnection );
91 connect( vl, SIGNAL( layerModified() ),
this, SLOT( joinedLayerModified() ), Qt::UniqueConnection );
105 for (
int i = 0; i < mVectorJoins.
size(); ++i )
107 if ( mVectorJoins.
at( i ).joinLayerId == joinLayerId )
116 disconnect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ) );
140 if ( joinFieldIndex < 0 || joinFieldIndex >= cacheLayer->
fields().
count() )
158 if ( !cacheLayerAttrs.contains( joinFieldIndex ) )
159 cacheLayerAttrs.
append( joinFieldIndex );
168 QString key = attrs.
at( joinFieldIndex ).toString();
172 for (
int i = 0; i < subsetIndices.
count(); ++i )
173 subsetAttrs[i] = attrs.
at( subsetIndices.
at( i ) );
179 attrs2.
remove( joinFieldIndex );
192 for (
int i = 0; i < joinFieldsSubset.
count(); ++i )
194 QString joinedFieldName = joinFieldsSubset.
at( i );
198 subsetIndices.
append( index );
202 QgsDebugMsg(
"Join layer subset field not found: " + joinedFieldName );
206 return subsetIndices;
214 for (
int joinIdx = 0 ; joinIt != mVectorJoins.
constEnd(); ++joinIt, ++joinIdx )
224 if ( joinIt->joinFieldName.
isEmpty() && joinIt->joinFieldIndex >= 0 && joinIt->joinFieldIndex < joinFields.
count() )
225 joinFieldName = joinFields.
field( joinIt->joinFieldIndex ).
name();
227 joinFieldName = joinIt->joinFieldName;
230 bool hasSubset =
false;
231 if ( joinIt->joinFieldNamesSubset() )
237 if ( joinIt->prefix.isNull() )
239 prefix = joinLayer->
name() +
'_';
243 prefix = joinIt->prefix;
246 for (
int idx = 0; idx < joinFields.
count(); ++idx )
249 if ( hasSubset && !subset.
contains( joinFields.
at( idx ).
name() ) )
254 if ( hasSubset || joinFields.
at( idx ).
name() != joinFieldName )
268 for ( ; joinIt != mVectorJoins.
end(); ++joinIt )
270 if ( joinIt->memoryCache && joinIt->cacheDirty )
271 cacheJoinLayer( *joinIt );
276 connect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ), Qt::UniqueConnection );
277 connect( vl, SIGNAL( layerModified() ),
this, SLOT( joinedLayerModified() ), Qt::UniqueConnection );
288 for ( ; joinIt != mVectorJoins.
constEnd(); ++joinIt )
292 if ( joinIt->targetFieldName.
isEmpty() )
293 joinElem.
setAttribute(
"targetField", joinIt->targetFieldIndex );
295 joinElem.
setAttribute(
"targetFieldName", joinIt->targetFieldName );
297 joinElem.
setAttribute(
"joinLayerId", joinIt->joinLayerId );
298 if ( joinIt->joinFieldName.
isEmpty() )
299 joinElem.
setAttribute(
"joinField", joinIt->joinFieldIndex );
301 joinElem.
setAttribute(
"joinFieldName", joinIt->joinFieldName );
303 joinElem.
setAttribute(
"memoryCache", joinIt->memoryCache );
305 if ( joinIt->joinFieldNamesSubset() )
308 Q_FOREACH (
const QString& fieldName, *joinIt->joinFieldNamesSubset() )
318 if ( !joinIt->prefix.isNull() )
320 joinElem.
setAttribute(
"customPrefix", joinIt->prefix );
330 mVectorJoins.
clear();
332 if ( !vectorJoinsElem.
isNull() )
335 for (
int i = 0; i < joinList.
size(); ++i )
349 if ( !subsetElem.
isNull() )
353 for (
int i = 0; i < fieldNodes.
count(); ++i )
361 info.
prefix = QString::null;
373 int joinIndex = mVectorJoins.
indexOf( *info );
374 if ( joinIndex == -1 )
377 for (
int i = 0; i < fields.
count(); ++i )
394 int sourceJoinIndex = originIndex / 1000;
395 sourceFieldIndex = originIndex % 1000;
397 if ( sourceJoinIndex < 0 || sourceJoinIndex >= mVectorJoins.
count() )
400 return &( mVectorJoins[sourceJoinIndex] );
406 cloned->mVectorJoins = mVectorJoins;
410 void QgsVectorLayerJoinBuffer::joinedLayerUpdatedFields()
416 Q_ASSERT( joinedLayer );
419 for ( QgsVectorJoinList::iterator it = mVectorJoins.
begin(); it != mVectorJoins.
end(); ++it )
421 if ( joinedLayer->
id() == it->joinLayerId )
423 it->cachedAttributes.clear();
424 cacheJoinLayer( *it );
431 void QgsVectorLayerJoinBuffer::joinedLayerModified()
434 Q_ASSERT( joinedLayer );
437 for ( QgsVectorJoinList::iterator it = mVectorJoins.
begin(); it != mVectorJoins.
end(); ++it )
439 if ( joinedLayer->
id() == it->joinLayerId )
441 it->cacheDirty =
true;
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
bool cacheDirty
True if the cached join attributes need to be updated.
Wrapper for iterator of features from vector data provider or vector layer.
QDomNodeList elementsByTagName(const QString &tagname) const
iterator insert(const Key &key, const T &value)
QString joinFieldName
Join field in the source layer.
field comes from a joined layer (originIndex / 1000 = index of the join, originIndex % 1000 = index w...
QgsAttributes attributes() const
Returns the feature's attributes.
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
QString targetFieldName
Join field in the target layer.
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
QDomNode appendChild(const QDomNode &newChild)
void append(const T &value)
void push_back(const T &value)
QString attribute(const QString &name, const QString &defValue) const
QgsMapLayer * mapLayer(const QString &theLayerId) const
Retrieve a pointer to a registered layer by layer ID.
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
int joinFieldIndex
Join field index in the source layer.
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
const T & at(int i) const
QgsFeatureRequest & setSubsetOfAttributes(const QgsAttributeList &attrs)
Set a subset of attributes that will be fetched.
void readXml(const QDomNode &layer_node)
Reads joins from project file.
Container of fields for a vector layer.
void setName(const QString &name)
Set the field name.
bool memoryCache
True if the join is cached in virtual memory.
int targetFieldIndex
Join field index in the target layer.
The feature class encapsulates a single feature including its id, geometry and a list of field/values...
QgsVectorLayerJoinBuffer(QgsVectorLayer *layer=nullptr)
const QList< QgsVectorJoinInfo > vectorJoins() const
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
int count() const
Return number of items.
const QgsField & at(int i) const
Get field at particular index (must be in range 0..N-1)
Manages joined fields for a vector layer.
QgsFields fields() const
Returns the list of fields of this layer.
int joinedFieldsOffset(const QgsVectorJoinInfo *info, const QgsFields &fields)
Find out what is the first index of the join within fields.
int indexOf(const T &value, int from) const
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
QDomElement toElement() const
QString prefix
An optional prefix.
void setJoinFieldNamesSubset(QStringList *fieldNamesSubset)
Set subset of fields to be used from joined layer.
int count(const T &value) const
bool addJoin(const QgsVectorJoinInfo &joinInfo)
Joins another vector layer to this layer.
void append(const T &value)
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
void setAttribute(const QString &name, const QString &value)
int toInt(bool *ok, int base) const
This class wraps a request for features to a vector layer (or directly its vector data provider)...
bool removeJoin(const QString &joinLayerId)
Removes a vector layer join.
bool append(const QgsField &field, FieldOrigin origin=OriginProvider, int originIndex=-1)
Append a field. The field must have unique name, otherwise it is rejected (returns false) ...
QgsFeatureRequest & setFlags(const QgsFeatureRequest::Flags &flags)
Set flags that affect how features will be fetched.
Encapsulate a field in an attribute table or data source.
~QgsVectorLayerJoinBuffer()
const T value(const Key &key) const
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
bool contains(const T &value) const
const T & at(int i) const
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
QList< T > toList() const
static QgsMapLayerRegistry * instance()
Returns the instance pointer, creating the object on the first call.
QHash< QString, QgsAttributes > cachedAttributes
Cache for joined attributes to provide fast lookup (size is 0 if no memory caching) ...
static bool _hasCycleDFS(QgsVectorLayer *n, QHash< QgsVectorLayer *, int > &mark)
void updateFields(QgsFields &fields)
Updates field map with joined attributes.
QDomElement firstChildElement(const QString &tagName) const
static QList< QgsVectorLayer * > _outEdges(QgsVectorLayer *vl)
static QVector< int > joinSubsetIndices(QgsVectorLayer *joinLayer, const QStringList &joinFieldsSubset)
Return a vector of indices for use in join based on field names from the layer.
int count(const T &value) const
QSet< T > fromList(const QList< T > &list)
void joinedFieldsChanged()
Emitted whenever the list of joined fields changes (e.g.
QString name
Read property of QString layerName.
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
const_iterator constEnd() const
QDomElement createElement(const QString &tagName)
bool nextFeature(QgsFeature &f)
const_iterator constBegin() const
Geometry is not required. It may still be returned if e.g. required for a filter condition.
bool connect(const QObject *sender, const char *signal, const QObject *receiver, const char *method, Qt::ConnectionType type)
Represents a vector layer which manages a vector based data sets.
QString joinLayerId
Source layer.
QStringList * joinFieldNamesSubset() const
Get subset of fields to be used from joined layer.
QgsVectorLayerJoinBuffer * clone() const
Create a copy of the join buffer.
QDomNode at(int index) const