Skip to content

Commit b1c8d03

Browse files
Marco Hugentoblermhugent
authored andcommittedJun 8, 2011
Support embedded layers and groups in server
1 parent c4cd43b commit b1c8d03

File tree

4 files changed

+181
-34
lines changed

4 files changed

+181
-34
lines changed
 

‎src/mapserver/qgis_map_serv.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,7 +176,6 @@ int main( int argc, char * argv[] )
176176

177177
//create config cache and search for config files in the current directory.
178178
//These configurations are used if no mapfile parameter is present in the request
179-
QgsConfigCache configCache;
180179
QString defaultConfigFilePath;
181180
QFileInfo projectFileInfo = defaultProjectFile(); //try to find a .qgs file in the server directory
182181
if ( projectFileInfo.exists() )
@@ -245,7 +244,7 @@ int main( int argc, char * argv[] )
245244
configFilePath = mapFileIt->second;
246245
}
247246

248-
QgsConfigParser* adminConfigParser = configCache.searchConfiguration( configFilePath );
247+
QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
249248
if ( !adminConfigParser )
250249
{
251250
QgsMSDebugMsg( "parse error on config file " + configFilePath );

‎src/mapserver/qgsconfigcache.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,17 @@
2222
#include "qgssldparser.h"
2323
#include <QCoreApplication>
2424

25+
QgsConfigCache* QgsConfigCache::mInstance = 0;
26+
27+
QgsConfigCache* QgsConfigCache::instance()
28+
{
29+
if ( !mInstance )
30+
{
31+
mInstance = new QgsConfigCache();
32+
}
33+
return mInstance;
34+
}
35+
2536
QgsConfigCache::QgsConfigCache()
2637
{
2738
QObject::connect( &mFileSystemWatcher, SIGNAL( fileChanged( const QString& ) ), this, SLOT( removeChangedEntry( const QString& ) ) );

‎src/mapserver/qgsconfigcache.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,18 @@ class QgsConfigCache: public QObject
3030
{
3131
Q_OBJECT
3232
public:
33-
QgsConfigCache();
33+
static QgsConfigCache* instance();
3434
~QgsConfigCache();
3535

3636
/**Returns configuration for given config file path. The calling function does _not_ take ownership*/
3737
QgsConfigParser* searchConfiguration( const QString& filePath );
3838

39+
protected:
40+
QgsConfigCache();
41+
3942
private:
43+
static QgsConfigCache* mInstance;
44+
4045
/**Creates configuration parser depending on the file type and, if successfull, inserts it to the cached configuration map
4146
@param filePath path of the configuration file
4247
@return the inserted config parser or 0 in case of error*/

‎src/mapserver/qgsprojectparser.cpp

Lines changed: 163 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
***************************************************************************/
1717

1818
#include "qgsprojectparser.h"
19+
#include "qgsconfigcache.h"
1920
#include "qgsepsgcache.h"
2021
#include "qgsmslayercache.h"
2122
#include "qgsmapserverlogger.h"
@@ -143,7 +144,43 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
143144
titleElem.appendChild( titleText );
144145
layerElem.appendChild( titleElem );
145146

146-
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, mapExtent, mapCRS );
147+
if( currentChildElem.attribute("embedded") == "1" )
148+
{
149+
//add layers from other project files and embed into this group
150+
QString project = convertToAbsolutePath( currentChildElem.attribute("project") );
151+
QString embeddedGroupName = currentChildElem.attribute("name");
152+
QgsProjectParser* p = dynamic_cast<QgsProjectParser*>( QgsConfigCache::instance()->searchConfiguration( project ) );
153+
if( p )
154+
{
155+
QStringList pIdDisabled = p->identifyDisabledLayers();
156+
157+
QDomElement embeddedGroupElem;
158+
QList<QDomElement> pLegendElems = p->legendGroupElements();
159+
QList<QDomElement>::const_iterator pLegendIt = pLegendElems.constBegin();
160+
for(; pLegendIt != pLegendElems.constEnd(); ++pLegendIt )
161+
{
162+
if( pLegendIt->attribute("name") == embeddedGroupName )
163+
{
164+
embeddedGroupElem = *pLegendIt;
165+
break;
166+
}
167+
}
168+
169+
QList<QDomElement> pLayerElems = p->projectLayerElements();
170+
QMap<QString, QgsMapLayer *> pLayerMap;
171+
QList<QDomElement>::const_iterator pLayerIt = pLayerElems.constBegin();
172+
for(; pLayerIt != pLayerElems.constEnd(); ++pLayerIt )
173+
{
174+
pLayerMap.insert( layerId( *pLayerIt ), p->createLayerFromElement( *pLayerIt ) );
175+
}
176+
177+
p->addLayers( doc, layerElem, embeddedGroupElem, pLayerMap, pIdDisabled, mapExtent, mapCRS);
178+
}
179+
}
180+
else //normal (not embedded) legend group
181+
{
182+
addLayers( doc, layerElem, currentChildElem, layerMap, nonIdentifiableLayers, mapExtent, mapCRS );
183+
}
147184

148185
// combine bounding boxes of childs (groups/layers)
149186

@@ -283,7 +320,6 @@ void QgsProjectParser::addLayers( QDomDocument &doc,
283320
QList<QgsMapLayer*> QgsProjectParser::mapLayerFromStyle( const QString& lName, const QString& styleName, bool allowCaching ) const
284321
{
285322
QList<QgsMapLayer*> layerList;
286-
bool layerFound = false;
287323

288324
//first assume lName refers to a leaf layer
289325
QMap< QString, QDomElement > layerElemMap = projectLayerElementsByName();
@@ -294,18 +330,11 @@ QList<QgsMapLayer*> QgsProjectParser::mapLayerFromStyle( const QString& lName, c
294330
if ( layer )
295331
{
296332
layerList.push_back( layer );
333+
return layerList;
297334
}
298-
layerFound = true;
299-
}
300-
301-
if ( layerFound )
302-
{
303-
return layerList;
304335
}
305336

306337
//Check if layer name refers to the top level group for the project.
307-
//The project group is not contained in the groupLayerRelationship list
308-
//because the list (and the qgis legend) does not support nested groups
309338
if ( lName == projectTitle() )
310339
{
311340
QList<QDomElement> layerElemList = projectLayerElements();
@@ -326,18 +355,110 @@ QList<QgsMapLayer*> QgsProjectParser::mapLayerFromStyle( const QString& lName, c
326355
{
327356
if ( groupIt->attribute( "name" ) == lName )
328357
{
329-
QDomNodeList layerFileList = groupIt->elementsByTagName( "legendlayerfile" );
330-
for ( int i = 0; i < layerFileList.size(); ++i )
358+
if( groupIt->attribute("embedded") == "1") //requested group is embedded from another project
331359
{
332-
QMap< QString, QDomElement >::const_iterator layerEntry = idLayerMap.find( layerFileList.at( i ).toElement().attribute( "layerid" ) );
333-
if ( layerEntry != idLayerMap.constEnd() )
360+
QgsProjectParser* p = dynamic_cast<QgsProjectParser*>(QgsConfigCache::instance()->searchConfiguration( convertToAbsolutePath(groupIt->attribute("project") ) ) );
361+
if( p )
334362
{
335-
layerList.push_back( createLayerFromElement( layerEntry.value() ) );
363+
QList<QDomElement> pGroupElems = p->legendGroupElements();
364+
QList<QDomElement>::const_iterator pGroupIt = pGroupElems.constBegin();
365+
QDomElement embeddedGroupElem;
366+
367+
for(; pGroupIt != pGroupElems.constEnd(); ++pGroupIt )
368+
{
369+
if( pGroupIt->attribute("name") == lName )
370+
{
371+
embeddedGroupElem = *pGroupIt;
372+
break;
373+
}
374+
}
375+
376+
if( !embeddedGroupElem.isNull() )
377+
{
378+
//add all the layers under the group
379+
QMap< QString, QDomElement > pLayerElems = p->projectLayerElementsById();
380+
QDomNodeList pLayerNodes = embeddedGroupElem.elementsByTagName("legendlayer");
381+
for( int i = 0; i < pLayerNodes.size(); ++i )
382+
{
383+
QString pLayerId = pLayerNodes.at(i).toElement().firstChildElement("filegroup").firstChildElement("legendlayerfile").attribute("layerid");
384+
QgsMapLayer* pLayer = p->createLayerFromElement( pLayerElems[pLayerId] );
385+
if( pLayer )
386+
{
387+
layerList.push_back( pLayer );
388+
}
389+
}
390+
}
336391
}
337392
}
393+
else //normal (not embedded) group
394+
{
395+
QDomNodeList layerFileList = groupIt->elementsByTagName( "legendlayerfile" );
396+
for ( int i = 0; i < layerFileList.size(); ++i )
397+
{
398+
QMap< QString, QDomElement >::const_iterator layerEntry = idLayerMap.find( layerFileList.at( i ).toElement().attribute( "layerid" ) );
399+
if ( layerEntry != idLayerMap.constEnd() )
400+
{
401+
layerList.push_back( createLayerFromElement( layerEntry.value() ) );
402+
}
403+
}
404+
}
405+
return layerList;
338406
}
339407
}
340408

409+
//maybe the layer is embedded from another project
410+
QMap< QString, QDomElement >::const_iterator layerIt = idLayerMap.constBegin();
411+
for(; layerIt != idLayerMap.constEnd(); ++layerIt )
412+
{
413+
if( layerIt.value().attribute("embedded") == "1" )
414+
{
415+
QString id = layerIt.value().attribute("id");
416+
QString project = layerIt.value().attribute("project");
417+
418+
//get config parser from cache
419+
QgsProjectParser* otherParser = dynamic_cast<QgsProjectParser*>(QgsConfigCache::instance()->searchConfiguration( project ) );
420+
if( otherParser )
421+
{
422+
//get element by id
423+
QMap< QString, QDomElement > otherLayerElems = otherParser->projectLayerElementsById();
424+
QMap< QString, QDomElement >::const_iterator otherLayerIt = otherLayerElems.find( id );
425+
if( otherLayerIt != otherLayerElems.constEnd() )
426+
{
427+
if( otherLayerIt.value().firstChildElement("layername").text() == lName )
428+
{
429+
layerList.push_back( otherParser->createLayerFromElement( otherLayerIt.value() ) );
430+
return layerList;
431+
}
432+
}
433+
}
434+
}
435+
}
436+
437+
//layer still not found. Check if it is a single layer contained in a embedded layer group
438+
groupIt = legendGroups.constBegin();
439+
for(; groupIt != legendGroups.constEnd(); ++groupIt )
440+
{
441+
if( groupIt->attribute("embedded") == "1")
442+
{
443+
QgsProjectParser* p = dynamic_cast<QgsProjectParser*>(QgsConfigCache::instance()->searchConfiguration( convertToAbsolutePath(groupIt->attribute("project") ) ) );
444+
if( p )
445+
{
446+
QMap< QString, QDomElement > pLayers = p->projectLayerElementsByName();
447+
QMap< QString, QDomElement >::const_iterator pLayerIt = pLayers.find( lName );
448+
if( pLayerIt != pLayers.constEnd() )
449+
{
450+
QgsMapLayer* layer = p->createLayerFromElement( pLayerIt.value() );
451+
if( layer )
452+
{
453+
layerList.push_back( layer );
454+
return layerList;
455+
}
456+
}
457+
}
458+
}
459+
}
460+
461+
//layer not found, return empty list
341462
return layerList;
342463
}
343464

@@ -728,27 +849,22 @@ QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem )
728849
return 0;
729850
}
730851

852+
QString uri;
853+
QString absoluteUri;
731854
QDomElement dataSourceElem = elem.firstChildElement( "datasource" );
732-
if ( dataSourceElem.isNull() )
855+
if ( !dataSourceElem.isNull() )
733856
{
734-
return 0;
735-
}
736-
737-
//convert relative pathes to absolute ones if necessary
738-
QString uri = dataSourceElem.text();
739-
QString absoluteUri = convertToAbsolutePath( uri );
740-
if ( uri != absoluteUri )
741-
{
742-
QDomText absoluteTextNode = mXMLDoc->createTextNode( absoluteUri );
743-
dataSourceElem.replaceChild( absoluteTextNode, dataSourceElem.firstChild() );
857+
//convert relative pathes to absolute ones if necessary
858+
uri = dataSourceElem.text();
859+
absoluteUri = convertToAbsolutePath( uri );
860+
if ( uri != absoluteUri )
861+
{
862+
QDomText absoluteTextNode = mXMLDoc->createTextNode( absoluteUri );
863+
dataSourceElem.replaceChild( absoluteTextNode, dataSourceElem.firstChild() );
864+
}
744865
}
745866

746867
QString id = layerId( elem );
747-
if ( id.isNull() )
748-
{
749-
return 0;
750-
}
751-
752868
QgsMapLayer* layer = QgsMSLayerCache::instance()->searchLayer( absoluteUri, id );
753869
if ( layer )
754870
{
@@ -767,6 +883,22 @@ QgsMapLayer* QgsProjectParser::createLayerFromElement( const QDomElement& elem )
767883
{
768884
layer = new QgsRasterLayer();
769885
}
886+
else if ( elem.attribute("embedded") == "1" ) //layer is embedded from another project file
887+
{
888+
QgsProjectParser* otherConfig = dynamic_cast<QgsProjectParser*>( QgsConfigCache::instance()->searchConfiguration( convertToAbsolutePath( elem.attribute( "project" ) ) ) );
889+
if( !otherConfig )
890+
{
891+
return 0;
892+
}
893+
894+
QMap< QString, QDomElement > layerMap = otherConfig->projectLayerElementsById();
895+
QMap< QString, QDomElement >::const_iterator layerIt = layerMap.find( elem.attribute( "id" ) );
896+
if( layerIt == layerMap.constEnd() )
897+
{
898+
return 0;
899+
}
900+
return otherConfig->createLayerFromElement( layerIt.value() );
901+
}
770902

771903
if ( layer )
772904
{

0 commit comments

Comments
 (0)
Please sign in to comment.