Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Fix loading of embedded layers and groups in WMS server
  • Loading branch information
mhugent committed Apr 16, 2014
1 parent 394a80c commit f132b43
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 107 deletions.
17 changes: 17 additions & 0 deletions src/mapserver/qgsconfigparserutils.cpp
Expand Up @@ -203,3 +203,20 @@ void QgsConfigParserUtils::fallbackServiceCapabilities( QDomElement& parentEleme
}
}
}

QList<QgsMapLayer*> QgsConfigParserUtils::layerMapToList( const QMap< int, QgsMapLayer* >& layerMap, bool reverseOrder )
{
if ( reverseOrder ) //reverse order
{
QList<QgsMapLayer*> list;
QMapIterator< int, QgsMapLayer* > layerMapIt( layerMap );
layerMapIt.toBack();
while ( layerMapIt.hasPrevious() )
{
layerMapIt.previous();
list.append( layerMapIt.value() );
}
return list;
}
return layerMap.values(); //take numbered drawing order
}
2 changes: 2 additions & 0 deletions src/mapserver/qgsconfigparserutils.h
Expand Up @@ -41,6 +41,8 @@ class QgsConfigParserUtils

/**Returns default service capabilities from wms_metadata.xml if nothing else is defined*/
static void fallbackServiceCapabilities( QDomElement& parentElement, QDomDocument& doc );

static QList<QgsMapLayer*> layerMapToList( const QMap< int, QgsMapLayer* >& layerMap, bool reverseOrder = false );
};

#endif // QGSCONFIGPARSERUTILS_H
74 changes: 9 additions & 65 deletions src/mapserver/qgsserverprojectparser.cpp
Expand Up @@ -334,6 +334,11 @@ int QgsServerProjectParser::numberOfLayers() const
return mProjectLayerElements.size();
}

bool QgsServerProjectParser::updateLegendDrawingOrder() const
{
return legendElem().attribute( "updateDrawingOrder", "true" ).compare( "true", Qt::CaseInsensitive ) == 0;
}

QString QgsServerProjectParser::layerName( const QDomElement& layerElem ) const
{
if ( layerElem.isNull() )
Expand Down Expand Up @@ -831,72 +836,11 @@ QSet<QString> QgsServerProjectParser::findRestrictedLayers() const
return restrictedLayerSet;
}

void QgsServerProjectParser::addLayersFromGroup( const QDomElement& legendGroupElem, QList<QgsMapLayer*>& layerList, bool useCache ) const
{
if ( legendGroupElem.attribute( "embedded" ) == "1" ) //embedded group
{
//get project parser
//get group elements from project parser, find the group
//iterate over layers and add them (embedding in embedded groups does not work)
QString groupName = legendGroupElem.attribute( "name" );
QString project = convertToAbsolutePath( legendGroupElem.attribute( "project" ) );

#if 0 //todo: fixme
QgsProjectParser* p = 0; //dynamic_cast<QgsProjectParser*>( QgsConfigCache::instance()->searchConfiguration( project ) );
if ( !p )
{
return;
}

QList<QDomElement> pLegendGroupElems = p->mLegendGroupElements;
QList<QDomElement>::const_iterator pGroupIt = pLegendGroupElems.constBegin();
for ( ; pGroupIt != pLegendGroupElems.constEnd(); ++pGroupIt )
{
if ( pGroupIt->attribute( "name" ) == groupName )
{
p->addLayersFromGroup( *pGroupIt, layerList, useCache );
return;
}
}
#endif //0
}
else //normal group
{
bool updateDrawingOrder = ( legendGroupElem.parentNode().toElement().attribute( "updateDrawingOrder" ) == "true" );
QMap< int, QDomElement > layerOrderList;
QDomNodeList groupElemChildren = legendGroupElem.childNodes();
for ( int i = 0; i < groupElemChildren.size(); ++i )
{
QDomElement elem = groupElemChildren.at( i ).toElement();
if ( elem.tagName() == "legendgroup" )
{
addLayersFromGroup( elem, layerList, useCache );
}
else if ( elem.tagName() == "legendlayer" )
{
int drawingOrder = updateDrawingOrder ? -1 : elem.attribute( "drawingOrder", "-1" ).toInt();
if ( drawingOrder == -1 )
{
addLayerFromLegendLayer( elem, layerList, useCache );
}
else
{
layerOrderList.insert( drawingOrder, elem );
}
}
}

QMap< int, QDomElement >::const_iterator layerOrderIt = layerOrderList.constBegin();
for ( ; layerOrderIt != layerOrderList.constEnd(); ++layerOrderIt )
{
addLayerFromLegendLayer( layerOrderIt.value(), layerList, useCache );
}
}
}

void QgsServerProjectParser::addLayerFromLegendLayer( const QDomElement& legendLayerElem, QList<QgsMapLayer*>& layerList, bool useCache ) const
void QgsServerProjectParser::layerFromLegendLayer( const QDomElement& legendLayerElem, QMap< int, QgsMapLayer*>& layers, bool useCache ) const
{
QString id = legendLayerElem.firstChild().firstChild().toElement().attribute( "layerid" );
int drawingOrder = updateLegendDrawingOrder() ? -1 : legendLayerElem.attribute( "drawingOrder", "-1" ).toInt();

QHash< QString, QDomElement >::const_iterator layerIt = mProjectLayerElementsById.find( id );
if ( layerIt != mProjectLayerElementsById.constEnd() )
{
Expand All @@ -906,7 +850,7 @@ void QgsServerProjectParser::addLayerFromLegendLayer( const QDomElement& legendL
QgsMapLayer* layer = createLayerFromElement( layerIt.value(), useCache );
if ( layer )
{
layerList.append( layer );
layers.insertMulti( drawingOrder, layer );
}
}
}
Expand Down
7 changes: 3 additions & 4 deletions src/mapserver/qgsserverprojectparser.h
Expand Up @@ -86,10 +86,7 @@ class QgsServerProjectParser

const QHash< QString, QDomElement >& projectLayerElementsByName() const { return mProjectLayerElementsByName; }

/**Adds layers from a legend group to list (could be embedded or a normal group)*/
void addLayersFromGroup( const QDomElement& legendGroupElem, QList<QgsMapLayer*>& layerList, bool useCache = true ) const;

void addLayerFromLegendLayer( const QDomElement& legendLayerElem, QList<QgsMapLayer*>& layerList, bool useCache = true ) const;
void layerFromLegendLayer( const QDomElement& legendLayerElem, QMap< int, QgsMapLayer*>& layers, bool useCache = true ) const;

QStringList wfsLayerNames() const;

Expand Down Expand Up @@ -119,6 +116,8 @@ class QgsServerProjectParser

int numberOfLayers() const;

bool updateLegendDrawingOrder() const;

private:

/**Content of project file*/
Expand Down
104 changes: 66 additions & 38 deletions src/mapserver/qgswmsprojectparser.cpp
Expand Up @@ -93,27 +93,20 @@ void QgsWMSProjectParser::layersAndStylesCapabilities( QDomElement& parentElemen
QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName, const QString& styleName, bool useCache ) const
{
Q_UNUSED( styleName );
QList<QgsMapLayer*> layerList;
QMap< int, QgsMapLayer* > layers;

//first check if the layer name refers an unpublished layer / group
if ( mProjectParser.restrictedLayers().contains( lName ) )
{
return layerList;
return QList<QgsMapLayer*>();
}

//does lName refer to a leaf layer
const QHash< QString, QDomElement >& projectLayerElementsByName = mProjectParser.projectLayerElementsByName();
QHash< QString, QDomElement >::const_iterator layerElemIt = projectLayerElementsByName.find( lName );
if ( layerElemIt != projectLayerElementsByName.constEnd() )
{
mProjectParser.addJoinLayersForElement( layerElemIt.value(), useCache );
mProjectParser.addValueRelationLayersForElement( layerElemIt.value(), useCache );
QgsMapLayer* layer = mProjectParser.createLayerFromElement( layerElemIt.value(), useCache );
if ( layer )
{
layerList.push_back( layer );
return layerList;
}
return ( QList<QgsMapLayer*>() << mProjectParser.createLayerFromElement( layerElemIt.value(), useCache ) );
}

//group or project name
Expand All @@ -138,28 +131,8 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName

if ( !groupElement.isNull() )
{
//embedded group has no children in this project file
if ( groupElement.attribute( "embedded" ) == "1" )
{
mProjectParser.addLayersFromGroup( groupElement, layerList, useCache );
return layerList;
}

//group element found, iterate children and call addLayersFromGroup / addLayerFromLegendLayer for each
QDomNodeList childList = groupElement.childNodes();
for ( uint i = 0; i < childList.length(); ++i )
{
QDomElement childElem = childList.at( i ).toElement();
if ( childElem.tagName() == "legendgroup" )
{
mProjectParser.addLayersFromGroup( childElem, layerList, useCache );
}
else if ( childElem.tagName() == "legendlayer" )
{
mProjectParser.addLayerFromLegendLayer( childElem, layerList, useCache );
}
}
return layerList;
addLayersFromGroup( groupElement, layers, useCache );
return QgsConfigParserUtils::layerMapToList( layers, mProjectParser.updateLegendDrawingOrder() );
}

//still not found. Check if it is a single embedded layer (embedded layers are not contained in mProjectLayerElementsByName)
Expand All @@ -170,7 +143,7 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName
QDomElement legendLayerElem = legendLayerList.at( i ).toElement();
if ( legendLayerElem.attribute( "name" ) == lName )
{
mProjectParser.addLayerFromLegendLayer( legendLayerElem, layerList, useCache );
mProjectParser.layerFromLegendLayer( legendLayerElem, layers, useCache );
}
}

Expand All @@ -193,9 +166,7 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName
QHash< QString, QDomElement >::const_iterator pLayerNameIt = pLayerByName.find( lName );
if ( pLayerNameIt != pLayerByName.constEnd() )
{
pp.addJoinLayersForElement( pLayerNameIt.value(), useCache );
pp.addValueRelationLayersForElement( pLayerNameIt.value(), useCache );
layerList.push_back( pp.createLayerFromElement( pLayerNameIt.value(), useCache ) );
pp.layerFromLegendLayer( pLayerNameIt.value(), layers, useCache );
break;
}

Expand All @@ -205,15 +176,72 @@ QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName
{
if ( pLegendGroupIt->attribute( "name" ) == lName )
{
pp.addLayersFromGroup( *pLegendGroupIt, layerList, useCache );
addLayersFromGroup( *pLegendGroupIt, layers, useCache );
break;
}
}
}
}
}

return layerList;
return layers.values();
}

void QgsWMSProjectParser::addLayersFromGroup( const QDomElement& legendGroupElem, QMap< int, QgsMapLayer*>& layers, bool useCache ) const
{
if ( legendGroupElem.isNull() )
{
return;
}

if ( legendGroupElem.attribute( "embedded" ) == "1" ) //embedded group
{
QString groupName = legendGroupElem.attribute( "name" );
int drawingOrder = mProjectParser.updateLegendDrawingOrder() ? legendGroupElem.attribute( "drawingOrder", "-1" ).toInt() : -1;

QString project = mProjectParser.convertToAbsolutePath( legendGroupElem.attribute( "project" ) );
QgsWMSProjectParser* p = dynamic_cast<QgsWMSProjectParser*>( QgsConfigCache::instance()->wmsConfiguration( project ) );
if ( p )
{
QgsServerProjectParser& pp = p->mProjectParser;
const QList<QDomElement>& legendGroups = pp.legendGroupElements();
QList<QDomElement>::const_iterator legendIt = legendGroups.constBegin();
for ( ; legendIt != legendGroups.constEnd(); ++legendIt )
{
if ( legendIt->attribute( "name" ) == groupName )
{
QMap< int, QgsMapLayer*> embeddedGroupLayers;
p->addLayersFromGroup( *legendIt, embeddedGroupLayers, useCache );

//reverse order because it will be reversed again afterwards in insertMulti
QList< QgsMapLayer* > embeddedLayerList = QgsConfigParserUtils::layerMapToList( embeddedGroupLayers, pp.updateLegendDrawingOrder() );

QList< QgsMapLayer* >::const_iterator layerIt = embeddedLayerList.constBegin();
for ( ; layerIt != embeddedLayerList.constEnd(); ++layerIt )
{
layers.insertMulti( drawingOrder, *layerIt );
}
}
}
}
}
else //normal group
{
QMap< int, QDomElement > layerOrderList;
QDomNodeList groupElemChildren = legendGroupElem.childNodes();
for ( int i = 0; i < groupElemChildren.size(); ++i )
{
QDomElement elem = groupElemChildren.at( i ).toElement();
if ( elem.tagName() == "legendgroup" )
{
addLayersFromGroup( elem, layers, useCache );
}
else if ( elem.tagName() == "legendlayer" )
{
mProjectParser.layerFromLegendLayer( elem, layers, useCache );
}
}
}
}

QString QgsWMSProjectParser::serviceUrl() const
Expand Down
3 changes: 3 additions & 0 deletions src/mapserver/qgswmsprojectparser.h
Expand Up @@ -135,6 +135,9 @@ class QgsWMSProjectParser: public QgsWMSConfigParser
const QMap<QString, QgsMapLayer *> &layerMap, const QStringList &nonIdentifiableLayers,
const QString& strHref, QgsRectangle& combinedBBox, QString strGroup ) const;

/**Adds layers from a legend group to list (could be embedded or a normal group)*/
void addLayersFromGroup( const QDomElement& legendGroupElem, QMap< int, QgsMapLayer*>& layers, bool useCache = true ) const;

QDomElement composerByName( const QString& composerName ) const;

static bool annotationPosition( const QDomElement& elem, double scaleFactor, double& xPos, double& yPos );
Expand Down

0 comments on commit f132b43

Please sign in to comment.