23 #include <QDomElement> 47 if ( mark.
value( n ) == 1 )
49 if ( mark.
value( n ) == 0 )
80 cacheJoinLayer( mVectorJoins.
last() );
89 connect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ), Qt::UniqueConnection );
100 for (
int i = 0; i < mVectorJoins.
size(); ++i )
102 if ( mVectorJoins.
at( i ).joinLayerId == joinLayerId )
111 disconnect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ) );
135 if ( joinFieldIndex < 0 || joinFieldIndex >= cacheLayer->
fields().
count() )
153 if ( !cacheLayerAttrs.contains( joinFieldIndex ) )
154 cacheLayerAttrs.
append( joinFieldIndex );
163 QString key = attrs.
at( joinFieldIndex ).toString();
167 for (
int i = 0; i < subsetIndices.
count(); ++i )
168 subsetAttrs[i] = attrs.
at( subsetIndices.
at( i ) );
174 attrs2.
remove( joinFieldIndex );
186 for (
int i = 0; i < joinFieldsSubset.
count(); ++i )
188 QString joinedFieldName = joinFieldsSubset.
at( i );
192 subsetIndices.
append( index );
196 QgsDebugMsg(
"Join layer subset field not found: " + joinedFieldName );
200 return subsetIndices;
208 for (
int joinIdx = 0 ; joinIt != mVectorJoins.
constEnd(); ++joinIt, ++joinIdx )
218 if ( joinIt->joinFieldName.
isEmpty() && joinIt->joinFieldIndex >= 0 && joinIt->joinFieldIndex < joinFields.
count() )
219 joinFieldName = joinFields.
field( joinIt->joinFieldIndex ).
name();
221 joinFieldName = joinIt->joinFieldName;
224 bool hasSubset =
false;
225 if ( joinIt->joinFieldNamesSubset() )
231 if ( joinIt->prefix.isNull() )
233 prefix = joinLayer->
name() +
'_';
237 prefix = joinIt->prefix;
240 for (
int idx = 0; idx < joinFields.
count(); ++idx )
243 if ( hasSubset && !subset.
contains( joinFields[idx].name() ) )
248 if ( hasSubset || joinFields[idx].
name() != joinFieldName )
261 for ( ; joinIt != mVectorJoins.
end(); ++joinIt )
263 cacheJoinLayer( *joinIt );
267 connect( vl, SIGNAL( updatedFields() ),
this, SLOT( joinedLayerUpdatedFields() ), Qt::UniqueConnection );
277 for ( ; joinIt != mVectorJoins.
constEnd(); ++joinIt )
281 if ( joinIt->targetFieldName.
isEmpty() )
282 joinElem.
setAttribute(
"targetField", joinIt->targetFieldIndex );
284 joinElem.
setAttribute(
"targetFieldName", joinIt->targetFieldName );
286 joinElem.
setAttribute(
"joinLayerId", joinIt->joinLayerId );
287 if ( joinIt->joinFieldName.
isEmpty() )
288 joinElem.
setAttribute(
"joinField", joinIt->joinFieldIndex );
290 joinElem.
setAttribute(
"joinFieldName", joinIt->joinFieldName );
292 joinElem.
setAttribute(
"memoryCache", joinIt->memoryCache );
294 if ( joinIt->joinFieldNamesSubset() )
297 Q_FOREACH (
const QString& fieldName, *joinIt->joinFieldNamesSubset() )
307 if ( !joinIt->prefix.isNull() )
309 joinElem.
setAttribute(
"customPrefix", joinIt->prefix );
319 mVectorJoins.
clear();
321 if ( !vectorJoinsElem.
isNull() )
324 for (
int i = 0; i < joinList.
size(); ++i )
337 if ( !subsetElem.
isNull() )
341 for (
int i = 0; i < fieldNodes.
count(); ++i )
349 info.
prefix = QString::null;
361 int joinIndex = mVectorJoins.
indexOf( *info );
362 if ( joinIndex == -1 )
365 for (
int i = 0; i < fields.
count(); ++i )
382 int sourceJoinIndex = originIndex / 1000;
383 sourceFieldIndex = originIndex % 1000;
385 if ( sourceJoinIndex < 0 || sourceJoinIndex >= mVectorJoins.
count() )
388 return &( mVectorJoins[sourceJoinIndex] );
394 cloned->mVectorJoins = mVectorJoins;
398 void QgsVectorLayerJoinBuffer::joinedLayerUpdatedFields()
401 Q_ASSERT( joinedLayer );
404 for ( QgsVectorJoinList::iterator it = mVectorJoins.
begin(); it != mVectorJoins.
end(); ++it )
406 if ( joinedLayer->
id() == it->joinLayerId )
408 it->cachedAttributes.clear();
409 cacheJoinLayer( *it );
Wrapper for iterator of features from vector data provider or vector layer.
QDomNodeList elementsByTagName(const QString &tagname) const
const QgsField & field(int fieldIdx) const
Get field at particular index (must be in range 0..N-1)
const QList< QgsVectorJoinInfo > vectorJoins() 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...
QString targetFieldName
Join field in the target layer.
void createJoinCaches()
Calls cacheJoinLayer() for all vector joins.
QString name() const
Get the display name of the layer.
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
QgsFields fields() const
Returns the list of fields of this layer.
int fieldNameIndex(const QString &fieldName) const
Look up field's index from name also looks up case-insensitive if there is no match otherwise...
QgsFeatureIterator getFeatures(const QgsFeatureRequest &request=QgsFeatureRequest())
Query the provider for features specified in request.
int joinFieldIndex
Join field index in the source layer.
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)
bool disconnect(const QObject *sender, const char *signal, const QObject *receiver, const char *method)
QgsMapLayer * mapLayer(const QString &theLayerId)
Retrieve a pointer to a loaded layer by id.
Manages joined fields for a vector layer.
const QgsVectorJoinInfo * joinForFieldIndex(int index, const QgsFields &fields, int &sourceFieldIndex) const
Finds the vector join for a layer field index.
int joinedFieldsOffset(const QgsVectorJoinInfo *info, const QgsFields &fields)
Find out what is the first index of the join within fields.
QgsVectorLayerJoinBuffer * clone() const
Create a copy of the join buffer.
int indexOf(const T &value, int from) const
QDomElement toElement() const
QString prefix
An optional prefix.
const char * name() const
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)
QgsAttributes attributes() const
Returns the feature's attributes.
void setAttribute(const QString &name, const QString &value)
QString name() const
Gets the name of the field.
int toInt(bool *ok, int base) const
int fieldOriginIndex(int fieldIdx) const
Get field's origin index (its meaning is specific to each type of origin)
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) ...
QString id() const
Get this layer's unique ID, this ID is used to access this layer from map layer registry.
int count() const
Return number of items.
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.
int indexFromName(const QString &name) const
Look up field's index from name. Returns -1 on error.
~QgsVectorLayerJoinBuffer()
const T value(const Key &key) const
bool contains(const T &value) const
const T & at(int i) const
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) ...
void writeXml(QDomNode &layer_node, QDomDocument &document) const
Saves mVectorJoins to xml under the layer node.
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)
FieldOrigin fieldOrigin(int fieldIdx) const
Get field's origin (value from an enumeration)
void joinedFieldsChanged()
Emitted whenever the list of joined fields changes (e.g.
QStringList * joinFieldNamesSubset() const
Get subset of fields to be used from joined layer.
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.
QDomNode at(int index) const