diff --git a/src/mapserver/qgsconfigcache.cpp b/src/mapserver/qgsconfigcache.cpp index e25ce934558d..297e2b9444f4 100644 --- a/src/mapserver/qgsconfigcache.cpp +++ b/src/mapserver/qgsconfigcache.cpp @@ -17,6 +17,7 @@ #include "qgsconfigcache.h" #include "qgsmapserverlogger.h" +#include "qgsmslayercache.h" #include "qgsprojectparser.h" #include "qgssldparser.h" @@ -35,17 +36,25 @@ QgsConfigCache::~QgsConfigCache() QgsConfigParser* QgsConfigCache::searchConfiguration( const QString& filePath ) { + QgsConfigParser* p = 0; QMap::const_iterator configIt = mCachedConfigurations.find( filePath ); if ( configIt == mCachedConfigurations.constEnd() ) { QgsMSDebugMsg( "Create new configuration" ); - return insertConfiguration( filePath ); + p = insertConfiguration( filePath ); } else { QgsMSDebugMsg( "Return configuration from cache" ); - return configIt.value(); + p = configIt.value(); } + + if ( p ) + { + //there could be more layers in a project than allowed by the cache per default + QgsMSLayerCache::instance()->setProjectMaxLayers( p->numberOfLayers() ); + } + return p; } QgsConfigParser* QgsConfigCache::insertConfiguration( const QString& filePath ) diff --git a/src/mapserver/qgsconfigparser.h b/src/mapserver/qgsconfigparser.h index f08bdf4c3ba9..4a3ef2e9abd1 100644 --- a/src/mapserver/qgsconfigparser.h +++ b/src/mapserver/qgsconfigparser.h @@ -44,6 +44,9 @@ class QgsConfigParser If no layers/style are found, an empty list is returned*/ virtual QList mapLayerFromStyle( const QString& layerName, const QString& styleName, bool allowCaching = true ) const = 0; + /**Returns number of layers in configuration*/ + virtual int numberOfLayers() const = 0; + /**Fills a layer and a style list. The two list have the same number of entries and the style and the layer at a position belong together (similar to the HTTP parameters 'Layers' and 'Styles'. Returns 0 in case of success*/ virtual int layersAndStyles( QStringList& layers, QStringList& styles ) const = 0; diff --git a/src/mapserver/qgsmslayercache.cpp b/src/mapserver/qgsmslayercache.cpp index bc4f62c94202..8142b277ebc2 100644 --- a/src/mapserver/qgsmslayercache.cpp +++ b/src/mapserver/qgsmslayercache.cpp @@ -20,7 +20,7 @@ #include "qgsmapserverlogger.h" //maximum number of layers in the cache (and upper limit for layers in one published project) -#define MAX_N_LAYERS 100 +#define DEFAULT_MAX_N_LAYERS 50 QgsMSLayerCache* QgsMSLayerCache::mInstance = 0; @@ -52,7 +52,7 @@ QgsMSLayerCache::~QgsMSLayerCache() void QgsMSLayerCache::insertLayer( const QString& url, const QString& layerName, QgsMapLayer* layer, const QList& tempFiles ) { QgsMSDebugMsg( "inserting layer" ); - if ( mEntries.size() > MAX_N_LAYERS ) //force cache layer examination after 10 inserted layers + if ( mEntries.size() > std::max( DEFAULT_MAX_N_LAYERS, mProjectMaxLayers ) ) //force cache layer examination after 10 inserted layers { updateEntries(); } @@ -102,7 +102,7 @@ QgsMapLayer* QgsMSLayerCache::searchLayer( const QString& url, const QString& la void QgsMSLayerCache::updateEntries() { QgsMSDebugMsg( "updateEntries" ); - int entriesToDelete = mEntries.size() - MAX_N_LAYERS; + int entriesToDelete = mEntries.size() - std::max( DEFAULT_MAX_N_LAYERS, mProjectMaxLayers ); if ( entriesToDelete < 1 ) { return; diff --git a/src/mapserver/qgsmslayercache.h b/src/mapserver/qgsmslayercache.h index e3927a73b3fc..6454c6e31780 100644 --- a/src/mapserver/qgsmslayercache.h +++ b/src/mapserver/qgsmslayercache.h @@ -51,6 +51,10 @@ class QgsMSLayerCache @return a pointer to the layer or 0 if no such layer*/ QgsMapLayer* searchLayer( const QString& url, const QString& layerName ); + int projectsMaxLayers() const { return mProjectMaxLayers; } + + void setProjectMaxLayers( int n ) { mProjectMaxLayers = n; } + protected: /**Protected singleton constructor*/ QgsMSLayerCache(); @@ -70,6 +74,9 @@ class QgsMSLayerCache url is used several time in a request. It ensures that different layer instances are created for different layer names*/ QHash, QgsMSLayerCacheEntry> mEntries; + + /**Maximum number of layers in the cache, overrides DEFAULT_MAX_N_LAYERS if larger*/ + int mProjectMaxLayers; }; #endif diff --git a/src/mapserver/qgsprojectparser.cpp b/src/mapserver/qgsprojectparser.cpp index fa1f4a326852..3cbd9fa2b139 100644 --- a/src/mapserver/qgsprojectparser.cpp +++ b/src/mapserver/qgsprojectparser.cpp @@ -47,6 +47,12 @@ QgsProjectParser::~QgsProjectParser() delete mXMLDoc; } +int QgsProjectParser::numberOfLayers() const +{ + QList layerElems = projectLayerElements(); + return layerElems.size(); +} + void QgsProjectParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const { QList layerElems = projectLayerElements(); diff --git a/src/mapserver/qgsprojectparser.h b/src/mapserver/qgsprojectparser.h index ecbbf26bb763..57abe58010dd 100644 --- a/src/mapserver/qgsprojectparser.h +++ b/src/mapserver/qgsprojectparser.h @@ -38,6 +38,8 @@ class QgsProjectParser: public QgsConfigParser /**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const; + int numberOfLayers() const; + /**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/ virtual QList mapLayerFromStyle( const QString& lName, const QString& styleName, bool allowCaching = true ) const; diff --git a/src/mapserver/qgssldparser.cpp b/src/mapserver/qgssldparser.cpp index 74cf68d1052a..e1da17ebac31 100644 --- a/src/mapserver/qgssldparser.cpp +++ b/src/mapserver/qgssldparser.cpp @@ -142,6 +142,23 @@ QgsSLDParser::~QgsSLDParser() delete mXMLDoc; } +int QgsSLDParser::numberOfLayers() const +{ + if ( !mXMLDoc ) + { + return 0; + } + + QDomElement sldElem = mXMLDoc->documentElement().toElement(); + if ( sldElem.isNull() ) + { + return 0; + } + QDomNodeList userLayerList = sldElem.elementsByTagName( "UserLayer" ); + QDomNodeList namedLayerList = sldElem.elementsByTagName( "NamedLayer" ); + return ( userLayerList.size() + namedLayerList.size() ); +} + void QgsSLDParser::layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const { //iterate over all nodes diff --git a/src/mapserver/qgssldparser.h b/src/mapserver/qgssldparser.h index b5c03eb641a5..6047c49578a1 100644 --- a/src/mapserver/qgssldparser.h +++ b/src/mapserver/qgssldparser.h @@ -57,6 +57,9 @@ class QgsSLDParser: public QgsConfigParser /**Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.*/ void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc ) const; + /**Returns number of layers in configuration*/ + int numberOfLayers() const; + /**Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/ QList mapLayerFromStyle( const QString& layerName, const QString& styleName, bool allowCaching = true ) const;