Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
server: fix 'LayerDrawingOrder' (fixes #12484)
  • Loading branch information
jef-n committed Apr 9, 2015
1 parent 6ccfbba commit de5a3f5
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 179 deletions.
16 changes: 14 additions & 2 deletions src/server/qgsserverprojectparser.cpp
Expand Up @@ -63,6 +63,18 @@ QgsServerProjectParser::QgsServerProjectParser( QDomDocument* xmlDoc, const QStr

mRestrictedLayers = findRestrictedLayers();
mUseLayerIDs = findUseLayerIDs();

mCustomLayerOrder.clear();

QDomElement customOrder = mXMLDoc->documentElement().firstChildElement( "layer-tree-canvas" ).firstChildElement( "custom-order" );
if ( customOrder.attribute( "enabled" ) == "1" )
{
QDomNodeList items = customOrder.childNodes();
for ( int i = 0; i < items.size(); ++i )
{
mCustomLayerOrder << items.item( i ).toElement().text();
}
}
}
}

Expand Down Expand Up @@ -349,7 +361,7 @@ int QgsServerProjectParser::numberOfLayers() const

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

void QgsServerProjectParser::serviceCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& service, bool sia2045 ) const
Expand Down Expand Up @@ -1069,7 +1081,7 @@ bool QgsServerProjectParser::findUseLayerIDs() 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();
int drawingOrder = updateLegendDrawingOrder() ? -1 : mCustomLayerOrder.indexOf( id );

QHash< QString, QDomElement >::const_iterator layerIt = mProjectLayerElementsById.find( id );
if ( layerIt != mProjectLayerElementsById.constEnd() )
Expand Down
4 changes: 4 additions & 0 deletions src/server/qgsserverprojectparser.h
Expand Up @@ -126,6 +126,8 @@ class QgsServerProjectParser

void serviceCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& service, bool sia2045 = false ) const;

QStringList customLayerOrder() const { return mCustomLayerOrder; }

private:

/**Content of project file*/
Expand Down Expand Up @@ -156,6 +158,8 @@ class QgsServerProjectParser
/**Returns a complete string set with all the restricted layer names (layers/groups that are not to be published)*/
QSet<QString> findRestrictedLayers() const;

QStringList mCustomLayerOrder;

bool findUseLayerIDs() const;

/**Adds sublayers of an embedded group to layer set*/
Expand Down
209 changes: 40 additions & 169 deletions src/server/qgswmsprojectparser.cpp
Expand Up @@ -72,11 +72,6 @@ void QgsWMSProjectParser::layersAndStylesCapabilities( QDomElement& parentElemen
return;
}

if ( fullProjectSettings )
{
addDrawingOrder( parentElement, doc );
}

QMap<QString, QgsMapLayer *> layerMap;
mProjectParser->projectLayerMap( layerMap );

Expand All @@ -96,10 +91,18 @@ void QgsWMSProjectParser::layersAndStylesCapabilities( QDomElement& parentElemen

QDomElement legendElem = mProjectParser->legendElem();

addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
QHash<QString, QString> idNameMap;
QStringList layerIDList;

addLayers( doc, layerParentElem, legendElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings, idNameMap, layerIDList );

parentElement.appendChild( layerParentElem );
mProjectParser->combineExtentAndCrsOfGroupChildren( layerParentElem, doc, true );

if ( fullProjectSettings )
{
addDrawingOrder( parentElement, doc, idNameMap, layerIDList );
}
}

QList<QgsMapLayer*> QgsWMSProjectParser::mapLayerFromStyle( const QString& lName, const QString& styleName, bool useCache ) const
Expand Down Expand Up @@ -734,177 +737,42 @@ QStringList QgsWMSProjectParser::identifyDisabledLayers() const
return disabledList;
}

void QgsWMSProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const
{
const QDomDocument* projectDoc = mProjectParser->xmlDocument();
if ( !projectDoc )
{
return;
}

//find legend section
QDomElement legendElement = projectDoc->documentElement().firstChildElement( "legend" );
if ( legendElement.isNull() )
{
return;
}

bool useDrawingOrder = legendElement.attribute( "updateDrawingOrder" ) == "false";
QMap<int, QString> orderedLayerNames;

QDomNodeList legendChildren = legendElement.childNodes();
QDomElement childElem;
for ( int i = 0; i < legendChildren.size(); ++i )
{
addDrawingOrder( legendChildren.at( i ).toElement(), useDrawingOrder, orderedLayerNames );
}

QStringList layerList;
QMap<int, QString>::const_iterator nameIt = orderedLayerNames.constBegin();
for ( ; nameIt != orderedLayerNames.constEnd(); ++nameIt )
{
layerList.prepend( nameIt.value() );
}

QDomElement layerDrawingOrderElem = doc.createElement( "LayerDrawingOrder" );
QDomText drawingOrderText = doc.createTextNode( layerList.join( "," ) );
layerDrawingOrderElem.appendChild( drawingOrderText );
parentElem.appendChild( layerDrawingOrderElem );
}

void QgsWMSProjectParser::addDrawingOrderEmbeddedGroup( QDomElement groupElem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList ) const
void QgsWMSProjectParser::addDrawingOrder( QDomElement& parentElem, QDomDocument& doc, const QHash<QString, QString> &idNameMap, const QStringList &layerIDList ) const
{
if ( groupElem.isNull() )
{
return;
}
QStringList layerList( mProjectParser->customLayerOrder() );

QString project = mProjectParser->convertToAbsolutePath( groupElem.attribute( "project" ) );
if ( project.isEmpty() )
if ( layerList.isEmpty() )
{
return;
layerList = layerIDList;
}

int embedDrawingOrder = groupElem.attribute( "drawingOrder", "-1" ).toInt();
QgsWMSProjectParser* p = dynamic_cast<QgsWMSProjectParser*>( QgsConfigCache::instance()->wmsConfiguration( project ) );
if ( !p )
if ( !mProjectParser->useLayerIDs() )
{
return;
}

const QDomDocument* doc = p->mProjectParser->xmlDocument();
if ( !doc )
{
return;
}

//find requested group
QString groupName = groupElem.attribute( "name" );
QDomElement embeddedGroupElem; //group element in source project file
QDomNodeList groupList = doc->elementsByTagName( "legendgroup" );
for ( int i = 0; i < groupList.size(); ++i )
{
if ( groupList.at( i ).toElement().attribute( "name" ) == groupName )
int i = 0;
while ( i < layerList.size() )
{
embeddedGroupElem = groupList.at( i ).toElement();
break;
}
}

if ( embeddedGroupElem.isNull() ) //group does not exist in project file
{
return;
}

//legend or custom drawing order in embedded project?
bool updateDrawingOrder = true;
QDomNodeList legendNode = doc->elementsByTagName( "legend" );
if ( legendNode.size() > 0 )
{
updateDrawingOrder = ( legendNode.at( 0 ).toElement().attribute( "updateDrawingOrder" ) == "true" );
}

QDomNodeList layerNodeList = embeddedGroupElem.elementsByTagName( "legendlayer" );
QDomElement layerElem;
QMap<int, QString > layerNames;
QString layerName;
for ( int i = 0; i < layerNodeList.size(); ++i )
{
layerElem = layerNodeList.at( i ).toElement();
layerName = mProjectParser->useLayerIDs() ? layerElem.attribute( "id" ) : layerElem.attribute( "name" );

int layerDrawingOrder = updateDrawingOrder ? -1 : layerElem.attribute( "drawingOrder", "-1" ).toInt();
if ( layerDrawingOrder == -1 )
{
layerNames.insert( layerNames.size(), layerName );
}
else
{
orderedLayerList.insert( orderedLayerList.size(), layerName );
}
}

if ( useDrawingOrder )
{
QMapIterator<int, QString > layerNamesIt( layerNames );
layerNamesIt.toBack();
while ( layerNamesIt.hasPrevious() )
{
layerNamesIt.previous();
orderedLayerList.insertMulti( embedDrawingOrder, layerNamesIt.value() );
}
}
else
{
QMap<int, QString >::const_iterator layerNamesIt = layerNames.constBegin();
for ( ; layerNamesIt != layerNames.constEnd(); ++layerNamesIt )
{
orderedLayerList.insert( orderedLayerList.size(), layerNamesIt.value() );
}
}
}

void QgsWMSProjectParser::addDrawingOrder( QDomElement elem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList ) const
{
if ( elem.isNull() )
{
return;
}

if ( elem.tagName() == "legendgroup" )
{
if ( elem.attribute( "embedded" ) == "1" )
{
addDrawingOrderEmbeddedGroup( elem, useDrawingOrder, orderedLayerList );
}
else
{
QDomNodeList groupChildren = elem.childNodes();
for ( int i = 0; i < groupChildren.size(); ++i )
if ( idNameMap.contains( layerList[i] ) )
{
layerList[i] = idNameMap[ layerList[i] ];
++i;
}
else
{
addDrawingOrder( groupChildren.at( i ).toElement(), useDrawingOrder, orderedLayerList );
QgsDebugMsg( "layer not found" );
layerList.removeAt( i );
}
}
}
else if ( elem.tagName() == "legendlayer" )
{
QString layerName = mProjectParser->useLayerIDs()
? mProjectParser->layerIdFromLegendLayer( elem )
: elem.attribute( "name" );

if ( useDrawingOrder )
{
int drawingOrder = elem.attribute( "drawingOrder", "-1" ).toInt();
orderedLayerList.insert( drawingOrder, layerName );
}
else
{
orderedLayerList.insert( orderedLayerList.size(), layerName );
}
if ( !layerList.isEmpty() )
{
QDomElement layerDrawingOrderElem = doc.createElement( "LayerDrawingOrder" );
QDomText drawingOrderText = doc.createTextNode( layerList.join( "," ) );
layerDrawingOrderElem.appendChild( drawingOrderText );
parentElem.appendChild( layerDrawingOrderElem );
}
}


void QgsWMSProjectParser::addLayerStyles( QgsMapLayer* currentLayer, QDomDocument& doc, QDomElement& layerElem, const QString& version ) const
{
foreach ( QString styleName, currentLayer->styleManager()->styles() )
Expand Down Expand Up @@ -996,7 +864,9 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,
const QMap<QString, QgsMapLayer *> &layerMap,
const QStringList &nonIdentifiableLayers,
QString version, //1.1.1 or 1.3.0
bool fullProjectSettings ) const
bool fullProjectSettings,
QHash<QString, QString> &idNameMap,
QStringList &layerIDList ) const
{
QDomNodeList legendChildren = legendElem.childNodes();
for ( int i = 0; i < legendChildren.size(); ++i )
Expand All @@ -1005,10 +875,9 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,
QDomElement layerElem = doc.createElement( "Layer" );
if ( fullProjectSettings )
{
layerElem.setAttribute( "visible", !( currentChildElem.attribute( "checked" ) == "Qt::Unchecked" ) );
layerElem.setAttribute( "visible", currentChildElem.attribute( "checked" ) != "Qt::Unchecked" );
}


if ( currentChildElem.tagName() == "legendgroup" )
{
layerElem.setAttribute( "queryable", "1" );
Expand Down Expand Up @@ -1058,12 +927,12 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,
pLayerMap.insert( pp->layerId( elem ), pp->createLayerFromElement( elem ) );
}

p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled, version, fullProjectSettings );
p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled, version, fullProjectSettings, idNameMap, layerIDList );
}
}
else //normal (not embedded) legend group
{
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings );
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, version, fullProjectSettings, idNameMap, layerIDList );
}

// combine bounding boxes of children (groups/layers)
Expand All @@ -1075,7 +944,7 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,

if ( !layerMap.contains( id ) )
{
QgsDebugMsg( QString( "layer %1 not found in map - layer cache to small?" ).arg( id ) );
QgsDebugMsg( QString( "layer %1 not found in map - layer cache too small?" ).arg( id ) );
continue;
}

Expand Down Expand Up @@ -1107,6 +976,9 @@ void QgsWMSProjectParser::addLayers( QDomDocument &doc,
nameElem.appendChild( nameText );
layerElem.appendChild( nameElem );

layerIDList << id;
idNameMap.insert( id, currentLayer->name() );

QDomElement titleElem = doc.createElement( "Title" );
QString titleName = currentLayer->title();
if ( titleName.isEmpty() )
Expand Down Expand Up @@ -1321,7 +1193,6 @@ void QgsWMSProjectParser::addOWSLayerStyles( QgsMapLayer* currentLayer, QDomDocu
}



void QgsWMSProjectParser::addOWSLayers( QDomDocument &doc,
QDomElement &parentElem,
const QDomElement &legendElem,
Expand Down
12 changes: 4 additions & 8 deletions src/server/qgswmsprojectparser.h
Expand Up @@ -127,13 +127,7 @@ class QgsWMSProjectParser : public QgsWMSConfigParser
virtual QStringList identifyDisabledLayers() const override;

/**Reads layer drawing order from the legend section of the project file and appends it to the parent elemen (usually the <Capability> element)*/
void addDrawingOrder( QDomElement& parentElem, QDomDocument& doc ) const;

/**Adds drawing order info from layer element or group element (recursive)*/
void addDrawingOrder( QDomElement groupElem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList ) const;

/**Adds drawing order info from embedded layer element or embedded group element (recursive)*/
void addDrawingOrderEmbeddedGroup( QDomElement groupElem, bool useDrawingOrder, QMap<int, QString>& orderedLayerList ) const;
void addDrawingOrder( QDomElement& parentElem, QDomDocument& doc, const QHash<QString, QString> &idNameMap, const QStringList &layerIDList ) const;

void addLayerStyles( QgsMapLayer* currentLayer, QDomDocument& doc, QDomElement& layerElem, const QString& version ) const;

Expand All @@ -143,7 +137,9 @@ class QgsWMSProjectParser : public QgsWMSConfigParser
const QMap<QString, QgsMapLayer *> &layerMap,
const QStringList &nonIdentifiableLayers,
QString version, //1.1.1 or 1.3.0
bool fullProjectSettings = false ) const;
bool fullProjectSettings,
QHash<QString, QString> &idNameMap,
QStringList &layerIDList ) const;

void addOWSLayerStyles( QgsMapLayer* currentLayer, QDomDocument& doc, QDomElement& layerElem ) const;

Expand Down

0 comments on commit de5a3f5

Please sign in to comment.