From e34116d7b9451c167f978fd3fbcd1d93e2c49660 Mon Sep 17 00:00:00 2001 From: rldhont Date: Mon, 10 Oct 2016 15:26:53 +0200 Subject: [PATCH] Redo [BUGFIX][QGIS Server] Joins was not reloaded if the layer is in cache With the commit f6aad8b, the QgsMapLayerRegistry signal `layersWillBeRemoved` is always emit. This imply that the vector layer join buffer is empty and not reloaded if the layer is in cache. To fix it, the QgsServerProjectParser has to have the same method as QgsVectorLayerJoinBuffer::readXml. This commit fixed #15522 Qgis Server doesnt' respect the styling from Desktop --- src/server/qgsserverprojectparser.cpp | 52 +++++++++++++++++++++++++-- src/server/qgsserverprojectparser.h | 3 ++ 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/src/server/qgsserverprojectparser.cpp b/src/server/qgsserverprojectparser.cpp index 42c421fa0de1..c98da2c82309 100644 --- a/src/server/qgsserverprojectparser.cpp +++ b/src/server/qgsserverprojectparser.cpp @@ -234,7 +234,11 @@ QgsMapLayer* QgsServerProjectParser::createLayerFromElement( const QDomElement& if ( !QgsMapLayerRegistry::instance()->mapLayer( id ) ) QgsMapLayerRegistry::instance()->addMapLayer( layer, false, false ); if ( layer->type() == QgsMapLayer::VectorLayer ) - addValueRelationLayersForLayer( dynamic_cast( layer ) ); + { + QgsVectorLayer* vlayer = qobject_cast( layer ); + addValueRelationLayersForLayer( vlayer ); + addJoinsToLayer( const_cast( elem ), vlayer ); + } return layer; } @@ -1541,13 +1545,57 @@ void QgsServerProjectParser::addJoinLayersForElement( const QDomElement& layerEl { QString id = joinNodeList.at( i ).toElement().attribute( "joinLayerId" ); QgsMapLayer* layer = mapLayerFromLayerId( id ); - if ( layer ) + if ( layer && !QgsMapLayerRegistry::instance()->mapLayer( id ) ) { QgsMapLayerRegistry::instance()->addMapLayer( layer, false, false ); } } } +// Based on QgsVectorLayerJoinBuffer::readXml +void QgsServerProjectParser::addJoinsToLayer( const QDomElement& layerElem, QgsVectorLayer *vl ) const +{ + if ( !vl ) + return; + + QDomElement vectorJoinsElem = layerElem.firstChildElement( "vectorjoins" ); + if ( vectorJoinsElem.isNull() ) + { + return; + } + + QDomNodeList joinList = vectorJoinsElem.elementsByTagName( "join" ); + for ( int i = 0; i < joinList.size(); ++i ) + { + QDomElement infoElem = joinList.at( i ).toElement(); + QgsVectorJoinInfo info; + info.joinFieldName = infoElem.attribute( "joinFieldName" ); + info.joinLayerId = infoElem.attribute( "joinLayerId" ); + info.targetFieldName = infoElem.attribute( "targetFieldName" ); + info.memoryCache = infoElem.attribute( "memoryCache" ).toInt(); + + info.joinFieldIndex = infoElem.attribute( "joinField" ).toInt(); //for compatibility with 1.x + info.targetFieldIndex = infoElem.attribute( "targetField" ).toInt(); //for compatibility with 1.x + + QDomElement subsetElem = infoElem.firstChildElement( "joinFieldsSubset" ); + if ( !subsetElem.isNull() ) + { + QStringList* fieldNames = new QStringList; + QDomNodeList fieldNodes = infoElem.elementsByTagName( "field" ); + for ( int i = 0; i < fieldNodes.count(); ++i ) + *fieldNames << fieldNodes.at( i ).toElement().attribute( "name" ); + info.setJoinFieldNamesSubset( fieldNames ); + } + + if ( infoElem.attribute( "hasCustomPrefix" ).toInt() ) + info.prefix = infoElem.attribute( "customPrefix" ); + else + info.prefix = QString::null; + + vl->addJoin( info ); + } +} + void QgsServerProjectParser::addValueRelationLayersForLayer( const QgsVectorLayer *vl ) const { if ( !vl ) diff --git a/src/server/qgsserverprojectparser.h b/src/server/qgsserverprojectparser.h index eaba967259a3..8a067c160329 100644 --- a/src/server/qgsserverprojectparser.h +++ b/src/server/qgsserverprojectparser.h @@ -112,7 +112,10 @@ class SERVER_EXPORT QgsServerProjectParser QStringList wfsLayers() const; QStringList wcsLayers() const; + /** Add layers for vector joins */ void addJoinLayersForElement( const QDomElement& layerElem ) const; + /** Update vector joins to layer, based on QgsVectorLayerJoinBuffer::readXml */ + void addJoinsToLayer( const QDomElement& layerElem, QgsVectorLayer *vl ) const; void addValueRelationLayersForLayer( const QgsVectorLayer *vl ) const; /** Add layers which are necessary for the evaluation of the expression function 'getFeature( layer, attributField, value)'*/