Skip to content
Permalink
Browse files
[FEATURE] WMS server: add support for WMS 1.1.1 and port to QMap (fro…
…m std::map)

Thanks Marco Lechner for the initial WMS 1.1.1 patch.
  • Loading branch information
jef-n committed Dec 8, 2011
1 parent 9c89965 commit c62ca9f
Show file tree
Hide file tree
Showing 24 changed files with 466 additions and 538 deletions.
@@ -223,7 +223,7 @@ int main( int argc, char * argv[] )
theRequestHandler = new QgsGetRequestHandler();
}

std::map<QString, QString> parameterMap;
QMap<QString, QString> parameterMap;

try
{
@@ -237,17 +237,11 @@ int main( int argc, char * argv[] )
}

//set admin config file to wms server object
QString configFilePath = defaultConfigFilePath;
std::map<QString, QString>::const_iterator mapFileIt = parameterMap.find( "MAP" );
if ( mapFileIt != parameterMap.end() )
{
configFilePath = mapFileIt->second;
QgsDebugMsg( QString( "Configuration file path set to: %1" ).arg( defaultConfigFilePath ) );
}
else
if ( !parameterMap.contains( "MAP" ) )
{
QgsDebugMsg( QString( "Using default configuration file path: %1" ).arg( defaultConfigFilePath ) );
}
QString configFilePath = parameterMap.value( "MAP", defaultConfigFilePath );

QgsConfigParser* adminConfigParser = QgsConfigCache::instance()->searchConfiguration( configFilePath );
if ( !adminConfigParser )
@@ -261,14 +255,9 @@ int main( int argc, char * argv[] )
adminConfigParser->setParameterMap( parameterMap );

//request to WMS?
QString serviceString( "WMS" );
std::map<QString, QString>::const_iterator serviceIt = parameterMap.find( "SERVICE" );
if ( serviceIt != parameterMap.end() )
{
serviceString = serviceIt->second;
}
QString serviceString = parameterMap.value( "SERVICE", "WMS" );
#if 0
else
if ( !parameterMap.contains( "SERVICE" ) )
{
QgsDebugMsg( "unable to find 'SERVICE' parameter, exiting..." );
theRequestHandler->sendServiceException( QgsMapServiceException( "ServiceNotSpecified", "Service not specified. The SERVICE parameter is mandatory" ) );
@@ -292,8 +281,8 @@ int main( int argc, char * argv[] )


//request type
std::map<QString, QString>::const_iterator requestIt = parameterMap.find( "REQUEST" );
if ( requestIt == parameterMap.end() )
QString request = parameterMap.value( "REQUEST" );
if ( request.isEmpty() )
{
//do some error handling
QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
@@ -303,16 +292,18 @@ int main( int argc, char * argv[] )
continue;
}

if ( requestIt->second == "GetCapabilities" )
QString version = parameterMap.value( "VERSION", "1.3.0" );

if ( request == "GetCapabilities" )
{
const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath );
const QDomDocument* capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
if ( !capabilitiesDocument ) //capabilities xml not in cache. Create a new one
{
QgsDebugMsg( "Capabilities document not found in cache" );
QDomDocument doc;
try
{
doc = theServer->getCapabilities();
doc = theServer->getCapabilities( version );
}
catch ( QgsMapServiceException& ex )
{
@@ -321,8 +312,8 @@ int main( int argc, char * argv[] )
delete theServer;
continue;
}
capabilitiesCache.insertCapabilitiesDocument( configFilePath, &doc );
capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath );
capabilitiesCache.insertCapabilitiesDocument( configFilePath, version, &doc );
capabilitiesDocument = capabilitiesCache.searchCapabilitiesDocument( configFilePath, version );
}
else
{
@@ -337,7 +328,7 @@ int main( int argc, char * argv[] )
delete theServer;
continue;
}
else if ( requestIt->second == "GetMap" )
else if ( request == "GetMap" )
{
QImage* result = 0;
try
@@ -369,12 +360,12 @@ int main( int argc, char * argv[] )
delete theServer;
continue;
}
else if ( requestIt->second == "GetFeatureInfo" )
else if ( request == "GetFeatureInfo" )
{
QDomDocument featureInfoDoc;
try
{
if ( theServer->getFeatureInfo( featureInfoDoc ) != 0 )
if ( theServer->getFeatureInfo( featureInfoDoc, version ) != 0 )
{
delete theRequestHandler;
delete theServer;
@@ -390,19 +381,12 @@ int main( int argc, char * argv[] )
}

//info format for GetFeatureInfo
QString infoFormat;
std::map<QString, QString>::const_iterator p_it = parameterMap.find( "INFO_FORMAT" );
if ( p_it != parameterMap.end() )
{
infoFormat = p_it->second;
}

theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, infoFormat );
theRequestHandler->sendGetFeatureInfoResponse( featureInfoDoc, parameterMap.value( "INFO_FORMAT" ) );
delete theRequestHandler;
delete theServer;
continue;
}
else if ( requestIt->second == "GetStyle" )
else if ( request == "GetStyle" )
{
try
{
@@ -418,7 +402,7 @@ int main( int argc, char * argv[] )
delete theServer;
continue;
}
else if ( requestIt->second == "GetLegendGraphics" )
else if ( request == "GetLegendGraphics" )
{
QImage* result = 0;
try
@@ -447,7 +431,7 @@ int main( int argc, char * argv[] )
continue;

}
else if ( requestIt->second == "GetPrint" )
else if ( request == "GetPrint" )
{
QByteArray* printOutput = 0;
try
@@ -470,7 +454,7 @@ int main( int argc, char * argv[] )
}
else//unknown request
{
QgsMapServiceException e( "OperationNotSupported", "Operation " + requestIt->second + " not supported" );
QgsMapServiceException e( "OperationNotSupported", "Operation " + request + " not supported" );
theRequestHandler->sendServiceException( e );
delete theRequestHandler;
delete theServer;
@@ -28,40 +28,42 @@ QgsCapabilitiesCache::~QgsCapabilitiesCache()
{
}

const QDomDocument* QgsCapabilitiesCache::searchCapabilitiesDocument( const QString& configFilePath ) const
const QDomDocument* QgsCapabilitiesCache::searchCapabilitiesDocument( QString configFilePath, QString version )
{
QCoreApplication::processEvents(); //get updates from file system watcher
QHash< QString, QDomDocument >::const_iterator it = mCachedCapabilities.find( configFilePath );
if ( it == mCachedCapabilities.constEnd() )

if ( mCachedCapabilities.contains( configFilePath ) && mCachedCapabilities[ configFilePath ].contains( version ) )
{
return 0;
return &mCachedCapabilities[configFilePath][version];
}
else
{
return &( it.value() );
return 0;
}
}

void QgsCapabilitiesCache::insertCapabilitiesDocument( const QString& configFilePath, const QDomDocument* doc )
void QgsCapabilitiesCache::insertCapabilitiesDocument( QString configFilePath, QString version, const QDomDocument* doc )
{
if ( mCachedCapabilities.size() > 40 )
{
//remove another cache entry to avoid memory problems
QHash<QString, QDomDocument>::iterator capIt = mCachedCapabilities.begin();
QHash<QString, QHash<QString, QDomDocument> >::iterator capIt = mCachedCapabilities.begin();
mFileSystemWatcher.removePath( capIt.key() );
mCachedCapabilities.erase( capIt );
}
mCachedCapabilities.insert( configFilePath, doc->cloneNode().toDocument() );
mFileSystemWatcher.addPath( configFilePath );

if ( !mCachedCapabilities.contains( configFilePath ) )
{
mFileSystemWatcher.addPath( configFilePath );
mCachedCapabilities.insert( configFilePath, QHash<QString, QDomDocument>() );
}

mCachedCapabilities[ configFilePath ].insert( version, doc->cloneNode().toDocument() );
}

void QgsCapabilitiesCache::removeChangedEntry( const QString& path )
{
QgsDebugMsg( "Remove capabilities cache entry because file changed" );
QHash< QString, QDomDocument >::iterator it = mCachedCapabilities.find( path );
if ( it != mCachedCapabilities.end() )
{
mCachedCapabilities.erase( it );
}
mCachedCapabilities.remove( path );
mFileSystemWatcher.removePath( path );
}
@@ -32,17 +32,17 @@ class QgsCapabilitiesCache: public QObject
~QgsCapabilitiesCache();

/**Returns cached capabilities document (or 0 if document for configuration file not in cache)*/
const QDomDocument* searchCapabilitiesDocument( const QString& configFilePath ) const;
const QDomDocument* searchCapabilitiesDocument( QString configFilePath, QString version );
/**Inserts new capabilities document (creates a copy of the document, does not take ownership)*/
void insertCapabilitiesDocument( const QString& configFilePath, const QDomDocument* doc );
void insertCapabilitiesDocument( QString configFilePath, QString version, const QDomDocument* doc );

private:
QHash< QString, QDomDocument > mCachedCapabilities;
QHash< QString, QHash< QString, QDomDocument > > mCachedCapabilities;
QFileSystemWatcher mFileSystemWatcher;

private slots:
/**Removes changed entry from this cache*/
void removeChangedEntry( const QString& path );
void removeChangedEntry( const QString &path );
};

#endif // QGSCAPABILITIESCACHE_H
@@ -40,34 +40,33 @@ QgsConfigCache::QgsConfigCache()

QgsConfigCache::~QgsConfigCache()
{
QHash<QString, QgsConfigParser*>::iterator configIt = mCachedConfigurations.begin();
for ( ; configIt != mCachedConfigurations.end(); ++configIt )
foreach( QgsConfigParser *parser, mCachedConfigurations.values() )
{
delete configIt.value();
delete parser;
}
}

QgsConfigParser* QgsConfigCache::searchConfiguration( const QString& filePath )
{
QCoreApplication::processEvents(); //check for updates from file system watcher
QgsConfigParser* p = 0;
QHash<QString, QgsConfigParser*>::const_iterator configIt = mCachedConfigurations.find( filePath );
if ( configIt == mCachedConfigurations.constEnd() )
QgsConfigParser* p = mCachedConfigurations.value( filePath, 0 );

if ( p )
{
QgsDebugMsg( "Create new configuration" );
p = insertConfiguration( filePath );
QgsDebugMsg( "Return configuration from cache" );
}
else
{
QgsDebugMsg( "Return configuration from cache" );
p = configIt.value();
QgsDebugMsg( "Create new configuration" );
p = insertConfiguration( filePath );
}

if ( p )
{
//there could be more layers in a project than allowed by the cache per default
QgsMSLayerCache::instance()->setProjectMaxLayers( p->numberOfLayers() );
}

return p;
}

0 comments on commit c62ca9f

Please sign in to comment.