mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-13 00:03:09 -04:00
Move wcs as service module
This commit is contained in:
parent
56b2f08865
commit
e17a7d4e21
@ -84,11 +84,16 @@ IF(WITH_APIDOC)
|
||||
${DOXYGEN_INPUT}
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserver.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgscapabilitiescache.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsmapserviceexception.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverexception.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsrequesthandler.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverfilter.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsaccesscontrolfilter.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverinterface.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverrequest.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverresponse.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserverrequest.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsservice.h
|
||||
${CMAKE_SOURCE_DIR}/src/server/qgsserviceregistry.h
|
||||
)
|
||||
ENDIF(WITH_SERVER_PLUGINS)
|
||||
|
||||
|
@ -1898,6 +1898,13 @@ optional property map passing down layer level properties to the SLD encoders. I
|
||||
- usedAttributes is now a const method and returns QSet<QString> instead of QStringList
|
||||
|
||||
|
||||
QgsRequestHandler {#qgis_api_break_3_0_QgsRequestHandler}
|
||||
-----------------
|
||||
|
||||
- Removed infoFormat and setInfoFormat methods: the format of the response is given and set with the "Content-Type" header.
|
||||
- Removed setCoverageResponse
|
||||
|
||||
|
||||
Processing {#qgis_api_break_3_0_Processing}
|
||||
----------
|
||||
|
||||
|
@ -29,9 +29,6 @@ class QgsRequestHandler /Abstract/
|
||||
/** Allow plugins to return a QgsServerException*/
|
||||
void setServiceException( const QgsServerException& ex );
|
||||
|
||||
//! @note not available in Python bindings
|
||||
void setGetCoverageResponse( QByteArray* ba );
|
||||
|
||||
/** Set an HTTP header*/
|
||||
void setHeader( const QString &name, const QString &value );
|
||||
|
||||
@ -50,9 +47,6 @@ class QgsRequestHandler /Abstract/
|
||||
/** Append the bytestream to response body*/
|
||||
void appendBody( const QByteArray &body );
|
||||
|
||||
/** Set the info format string such as "text/xml"*/
|
||||
void setInfoFormat( const QString &format );
|
||||
|
||||
/** Send out HTTP headers and flush output buffer*/
|
||||
void sendResponse();
|
||||
|
||||
@ -77,9 +71,6 @@ class QgsRequestHandler /Abstract/
|
||||
/** Return the requested format string*/
|
||||
QString format() const;
|
||||
|
||||
/** Return the mime type for the response*/
|
||||
QString infoFormat() const;
|
||||
|
||||
/** Return true if the HTTP headers were already sent to the client*/
|
||||
bool headersSent() const;
|
||||
};
|
||||
|
@ -47,6 +47,7 @@ class QgsOgcServiceException
|
||||
QString message() const;
|
||||
QString code() const;
|
||||
QString locator() const;
|
||||
QString version() const;
|
||||
|
||||
virtual QByteArray formatResponse( QString& responseFormat / Out / ) const;
|
||||
};
|
||||
|
@ -79,6 +79,21 @@ class QgsServerRequest
|
||||
*/
|
||||
QMap<QString, QString> parameters() const;
|
||||
|
||||
/**
|
||||
* Set a parameter
|
||||
*/
|
||||
void setParameter( const QString& key, const QString& value );
|
||||
|
||||
/**
|
||||
* Get a parameter value
|
||||
*/
|
||||
QString getParameter( const QString& key ) const;
|
||||
|
||||
/**
|
||||
* Remove a parameter
|
||||
*/
|
||||
void removeParameter( const QString& key );
|
||||
|
||||
/**
|
||||
* Return post/put data
|
||||
* Check for QByteArray::isNull() to check if data
|
||||
|
@ -24,8 +24,6 @@ SET ( qgis_mapserv_SRCS
|
||||
qgscapabilitiescache.cpp
|
||||
qgsconfigcache.cpp
|
||||
qgsrequesthandler.cpp
|
||||
qgsowsserver.cpp
|
||||
qgswcsserver.cpp
|
||||
qgsserversettings.cpp
|
||||
qgsserverexception.cpp
|
||||
qgsmslayercache.cpp
|
||||
|
@ -1,66 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsowsserver.cpp
|
||||
-------------------
|
||||
begin : February 27, 2012
|
||||
copyright : (C) 2012 by René-Luc D'Hont & Marco Hugentobler
|
||||
email : rldhont at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsowsserver.h"
|
||||
#include "qgsmessagelog.h"
|
||||
#include "qgsvectorlayer.h"
|
||||
#include "qgsvectordataprovider.h"
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
//! Apply filter from AccessControl
|
||||
void QgsOWSServer::applyAccessControlLayerFilters( QgsMapLayer* mapLayer, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const
|
||||
{
|
||||
if ( QgsVectorLayer* layer = qobject_cast<QgsVectorLayer*>( mapLayer ) )
|
||||
{
|
||||
QString sql = mAccessControl->extraSubsetString( layer );
|
||||
if ( !sql.isEmpty() )
|
||||
{
|
||||
if ( !originalLayerFilters.contains( layer ) )
|
||||
{
|
||||
originalLayerFilters.insert( layer, layer->subsetString() );
|
||||
}
|
||||
if ( !layer->subsetString().isEmpty() )
|
||||
{
|
||||
sql.prepend( " AND " );
|
||||
sql.prepend( layer->subsetString() );
|
||||
}
|
||||
if ( !layer->setSubsetString( sql ) )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Layer does not support Subset String" ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
//! Restore layer filter as original
|
||||
void QgsOWSServer::restoreLayerFilters( const QHash<QgsMapLayer*, QString>& filterMap )
|
||||
{
|
||||
QHash<QgsMapLayer*, QString>::const_iterator filterIt = filterMap.constBegin();
|
||||
for ( ; filterIt != filterMap.constEnd(); ++filterIt )
|
||||
{
|
||||
QgsVectorLayer* filteredLayer = qobject_cast<QgsVectorLayer*>( filterIt.key() );
|
||||
if ( filteredLayer )
|
||||
{
|
||||
QgsVectorDataProvider* dp = filteredLayer->dataProvider();
|
||||
if ( dp )
|
||||
{
|
||||
dp->setSubsetString( filterIt.value() );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,110 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgsowsserver.h
|
||||
--------------
|
||||
begin : March 24, 2014
|
||||
copyright : (C) 2006 by Marco Hugentobler
|
||||
email : marco dot hugentobler at sourcepole dot ch
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSOWSSERVER_H
|
||||
#define QGSOWSSERVER_H
|
||||
|
||||
#include "qgsconfig.h"
|
||||
#include "qgsrequesthandler.h"
|
||||
#include "qgsserversettings.h"
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
#include "qgsaccesscontrol.h"
|
||||
#else
|
||||
class QgsAccessControl;
|
||||
#endif
|
||||
|
||||
#include <QHash>
|
||||
|
||||
class QgsMapLayer;
|
||||
|
||||
class QgsOWSServer
|
||||
{
|
||||
public:
|
||||
QgsOWSServer(
|
||||
const QString& configFilePath
|
||||
, const QgsServerSettings& settings
|
||||
, const QMap<QString, QString>& parameters
|
||||
, QgsRequestHandler* rh
|
||||
, QgsAccessControl* ac
|
||||
)
|
||||
: mSettings( settings )
|
||||
, mParameters( parameters )
|
||||
, mRequestHandler( rh )
|
||||
, mConfigFilePath( configFilePath )
|
||||
, mAccessControl( ac )
|
||||
{}
|
||||
virtual ~QgsOWSServer() = default;
|
||||
|
||||
virtual void executeRequest() = 0;
|
||||
|
||||
/** Restores the original layer filters
|
||||
* @param filterMap the original layer filter
|
||||
*/
|
||||
static void restoreLayerFilters( const QHash < QgsMapLayer*, QString >& filterMap );
|
||||
|
||||
private:
|
||||
QgsOWSServer() {}
|
||||
|
||||
protected:
|
||||
QgsServerSettings mSettings;
|
||||
QMap<QString, QString> mParameters;
|
||||
QgsRequestHandler* mRequestHandler;
|
||||
QString mConfigFilePath;
|
||||
|
||||
//! The access control helper
|
||||
QgsAccessControl* mAccessControl;
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
|
||||
/** Apply filter strings from the access control to the layers.
|
||||
* @param layer the concerned layer
|
||||
* @param originalLayerFilters the original layer filter
|
||||
*
|
||||
*/
|
||||
void applyAccessControlLayerFilters( QgsMapLayer* layer, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/** RAII class to restore layer filters on destruction
|
||||
*/
|
||||
class QgsOWSServerFilterRestorer
|
||||
{
|
||||
public:
|
||||
|
||||
QgsOWSServerFilterRestorer() = default;
|
||||
|
||||
QgsOWSServerFilterRestorer( const QgsOWSServerFilterRestorer& rh ) = delete;
|
||||
QgsOWSServerFilterRestorer& operator=( const QgsOWSServerFilterRestorer& rh ) = delete;
|
||||
|
||||
//! Destructor. When object is destroyed all original layer filters will be restored.
|
||||
~QgsOWSServerFilterRestorer()
|
||||
{
|
||||
QgsOWSServer::restoreLayerFilters( mOriginalLayerFilters );
|
||||
}
|
||||
|
||||
/** Returns a reference to the object's hash of layers to original subsetString filters.
|
||||
* Original layer subsetString filters MUST be inserted into this hash before modifying them.
|
||||
*/
|
||||
QHash<QgsMapLayer*, QString>& originalFilters() { return mOriginalLayerFilters; }
|
||||
|
||||
private:
|
||||
QHash<QgsMapLayer*, QString> mOriginalLayerFilters;
|
||||
|
||||
};
|
||||
|
||||
#endif // QGSOWSSERVER_H
|
@ -53,20 +53,6 @@ QMap<QString, QString> QgsRequestHandler::parameterMap() const
|
||||
return mRequest.parameters();
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setHttpResponse( const QByteArray& ba, const QString &format )
|
||||
{
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Checking byte array is ok to set..." ) );
|
||||
|
||||
if ( ba.size() < 1 )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
QgsMessageLog::logMessage( QStringLiteral( "Byte array looks good, setting response..." ) );
|
||||
appendBody( ba );
|
||||
setInfoFormat( format );
|
||||
}
|
||||
|
||||
bool QgsRequestHandler::exceptionRaised() const
|
||||
{
|
||||
return mExceptionRaised;
|
||||
@ -107,55 +93,12 @@ void QgsRequestHandler::appendBody( const QByteArray &body )
|
||||
mResponse.write( body );
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setInfoFormat( const QString &format )
|
||||
{
|
||||
mInfoFormat = format;
|
||||
|
||||
// Update header
|
||||
QString fmt = mInfoFormat;
|
||||
if ( mInfoFormat.startsWith( QLatin1String( "text/" ) ) || mInfoFormat.startsWith( QLatin1String( "application/vnd.ogc.gml" ) ) )
|
||||
{
|
||||
fmt.append( "; charset=utf-8" );
|
||||
}
|
||||
setHeader( QStringLiteral( "Content-Type" ), fmt );
|
||||
|
||||
}
|
||||
|
||||
void QgsRequestHandler::sendResponse()
|
||||
{
|
||||
// Send data to output
|
||||
mResponse.flush();
|
||||
}
|
||||
|
||||
|
||||
|
||||
QString QgsRequestHandler::formatToMimeType( const QString& format ) const
|
||||
{
|
||||
if ( format.compare( QLatin1String( "png" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return QStringLiteral( "image/png" );
|
||||
}
|
||||
else if ( format.compare( QLatin1String( "jpg" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return QStringLiteral( "image/jpeg" );
|
||||
}
|
||||
else if ( format.compare( QLatin1String( "svg" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return QStringLiteral( "image/svg+xml" );
|
||||
}
|
||||
else if ( format.compare( QLatin1String( "pdf" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
return QStringLiteral( "application/pdf" );
|
||||
}
|
||||
return format;
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setGetCapabilitiesResponse( const QDomDocument& doc )
|
||||
{
|
||||
QByteArray ba = doc.toByteArray();
|
||||
setHttpResponse( ba, QStringLiteral( "text/xml" ) );
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setServiceException( const QgsServerException& ex )
|
||||
{
|
||||
// Safety measure to avoid potential leaks if called repeatedly
|
||||
@ -163,14 +106,6 @@ void QgsRequestHandler::setServiceException( const QgsServerException& ex )
|
||||
mResponse.write( ex );
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setGetCoverageResponse( QByteArray* ba )
|
||||
{
|
||||
if ( ba )
|
||||
{
|
||||
setHttpResponse( *ba, QStringLiteral( "image/tiff" ) );
|
||||
}
|
||||
}
|
||||
|
||||
void QgsRequestHandler::setupParameters()
|
||||
{
|
||||
const QgsServerRequest::Parameters parameters = mRequest.parameters();
|
||||
|
@ -54,15 +54,9 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
explicit QgsRequestHandler( QgsServerRequest& request, QgsServerResponse& response );
|
||||
~QgsRequestHandler();
|
||||
|
||||
//! @note not available in Python bindings
|
||||
void setGetCapabilitiesResponse( const QDomDocument& doc );
|
||||
|
||||
//! Allow plugins to return a QgsMapServiceException
|
||||
void setServiceException( const QgsServerException &ex );
|
||||
|
||||
//! @note not available in Python bindings
|
||||
void setGetCoverageResponse( QByteArray* ba );
|
||||
|
||||
/** Send out HTTP headers and flush output buffer
|
||||
*
|
||||
* This method is intended only for streaming
|
||||
@ -88,9 +82,6 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
//! Set the info format string such as "text/xml"
|
||||
void appendBody( const QByteArray &body );
|
||||
|
||||
//! Set the info format string such as "text/xml"
|
||||
void setInfoFormat( const QString &format );
|
||||
|
||||
//! Pointer to last raised exception
|
||||
bool exceptionRaised() const;
|
||||
|
||||
@ -117,19 +108,9 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
//! Return the requested format string
|
||||
QString format() const { return mFormat; }
|
||||
|
||||
//! Return the mime type for the response
|
||||
QString infoFormat() const { return mInfoFormat; }
|
||||
|
||||
//! Return true if the HTTP headers were already sent to the client
|
||||
bool headersSent() const;
|
||||
|
||||
private:
|
||||
void setHttpResponse( const QByteArray& ba, const QString &format );
|
||||
|
||||
/** Converts format to official mimetype (e.g. 'jpg' to 'image/jpeg')
|
||||
@return mime string (or the entered string if not found)*/
|
||||
QString formatToMimeType( const QString& format ) const;
|
||||
|
||||
private:
|
||||
|
||||
void setupParameters();
|
||||
@ -138,7 +119,6 @@ class SERVER_EXPORT QgsRequestHandler
|
||||
QString mFormat;
|
||||
QString mFormatString; //format string as it is passed in the request (with base)
|
||||
QString mService;
|
||||
QString mInfoFormat;
|
||||
bool mExceptionRaised;
|
||||
|
||||
QgsServerRequest& mRequest;
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include "qgsconfig.h"
|
||||
#include "qgsserver.h"
|
||||
#include "qgsmslayercache.h"
|
||||
|
||||
#include "qgsmapsettings.h"
|
||||
#include "qgsauthmanager.h"
|
||||
#include "qgscapabilitiescache.h"
|
||||
@ -31,7 +30,6 @@
|
||||
#include "qgsproject.h"
|
||||
#include "qgsproviderregistry.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgswcsserver.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgspallabeling.h"
|
||||
#include "qgsnetworkaccessmanager.h"
|
||||
@ -403,8 +401,6 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
||||
QMap<QString, QString> parameterMap = request.parameters();
|
||||
printRequestParameters( parameterMap, logLevel );
|
||||
|
||||
QgsAccessControl* accessControl = sServerInterface->accessControls();
|
||||
|
||||
//Config file path
|
||||
QString configFilePath = configPath( *sConfigFilePath, parameterMap );
|
||||
|
||||
@ -438,31 +434,6 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
||||
{
|
||||
service->executeRequest( request, theResponse );
|
||||
}
|
||||
else if ( serviceString == QLatin1String( "WCS" ) )
|
||||
{
|
||||
|
||||
QgsWCSProjectParser* p = QgsConfigCache::instance()->wcsConfiguration(
|
||||
configFilePath
|
||||
, accessControl
|
||||
);
|
||||
if ( !p )
|
||||
{
|
||||
theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ),
|
||||
QStringLiteral( "Error reading the project file" ) ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
QgsWCSServer wcsServer(
|
||||
configFilePath
|
||||
, sSettings
|
||||
, parameterMap
|
||||
, p
|
||||
, &theRequestHandler
|
||||
, accessControl
|
||||
);
|
||||
wcsServer.executeRequest();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
throw QgsOgcServiceException( QStringLiteral( "Service configuration error" ),
|
||||
|
@ -27,10 +27,13 @@
|
||||
/** \ingroup server
|
||||
* \class QgsServerException
|
||||
* \brief Exception base class for server exceptions.
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
class SERVER_EXPORT QgsServerException : public QgsException
|
||||
{
|
||||
public:
|
||||
//! Constructor
|
||||
QgsServerException( const QString& message, int responseCode = 500 );
|
||||
|
||||
/**
|
||||
@ -52,23 +55,34 @@ class SERVER_EXPORT QgsServerException : public QgsException
|
||||
};
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsOcgServiceException
|
||||
* \class QgsOgcServiceException
|
||||
* \brief Exception base class for service exceptions.
|
||||
*
|
||||
* Note that this exception is assaciated with a default return code 200 which may be
|
||||
* Note that this exception is associated with a default return code 200 which may be
|
||||
* not appropriate in some situations.
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
class SERVER_EXPORT QgsOgcServiceException : public QgsServerException
|
||||
{
|
||||
public:
|
||||
//! Construction
|
||||
QgsOgcServiceException( const QString& code, const QString& message, const QString& locator = QString(),
|
||||
int responseCode = 200, const QString& version = QStringLiteral( "1.3.0" ) );
|
||||
|
||||
//! @return message
|
||||
QString message() const { return mMessage; }
|
||||
|
||||
//! @return code
|
||||
QString code() const { return mCode; }
|
||||
|
||||
//! @return locator
|
||||
QString locator() const { return mLocator; }
|
||||
|
||||
//!return exception version
|
||||
QString version() const { return mVersion; }
|
||||
|
||||
//! Overrided from QgsServerException
|
||||
virtual QByteArray formatResponse( QString& responseFormat ) const override;
|
||||
|
||||
private:
|
||||
@ -76,8 +90,6 @@ class SERVER_EXPORT QgsOgcServiceException : public QgsServerException
|
||||
QString mMessage;
|
||||
QString mLocator;
|
||||
QString mVersion;
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
@ -27,6 +27,8 @@
|
||||
* \ingroup server
|
||||
* QgsServerRequest
|
||||
* Class defining request interface passed to services QgsService::executeRequest() method
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
|
||||
// Note about design: this interface must be passed along to python and thus signatures methods must be
|
||||
@ -38,6 +40,9 @@ class SERVER_EXPORT QgsServerRequest
|
||||
|
||||
typedef QMap<QString, QString> Parameters;
|
||||
|
||||
/**
|
||||
* HTTP Method (or equivalent) used for the request
|
||||
*/
|
||||
enum Method
|
||||
{
|
||||
HeadMethod, PutMethod, GetMethod, PostMethod, DeleteMethod
|
||||
|
@ -30,6 +30,8 @@ class QgsServerException;
|
||||
* \ingroup server
|
||||
* QgsServerResponse
|
||||
* Class defining response interface passed to services QgsService::executeRequest() method
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
|
||||
// Note:
|
||||
|
@ -35,6 +35,7 @@ class QgsProject;
|
||||
* This class provides methods for executing server requests
|
||||
* They are registered at runtime for a given service name.
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
class SERVER_EXPORT QgsService
|
||||
{
|
||||
|
@ -41,6 +41,7 @@ class QgsServerInterface;
|
||||
* IMPORTANT: The registry hold ownership of registered services and
|
||||
* will call 'delete' on cleanup
|
||||
*
|
||||
* @note added in QGIS 3.0
|
||||
*/
|
||||
class SERVER_EXPORT QgsServiceRegistry
|
||||
{
|
||||
|
@ -1,493 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgswcsserver.cpp
|
||||
-------------------
|
||||
begin : December 9, 2013
|
||||
copyright : (C) 2013 by René-Luc D'Hont
|
||||
email : rldhont at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgswcsserver.h"
|
||||
#include "qgswcsprojectparser.h"
|
||||
#include "qgsrasterdataprovider.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrasterpipe.h"
|
||||
#include "qgsrasterprojector.h"
|
||||
#include "qgsrasterfilewriter.h"
|
||||
#include "qgslogger.h"
|
||||
#include "qgsmapserviceexception.h"
|
||||
#include "qgsaccesscontrol.h"
|
||||
|
||||
#include <QTemporaryFile>
|
||||
#include <QUrl>
|
||||
|
||||
#ifndef Q_OS_WIN
|
||||
#include <netinet/in.h>
|
||||
#else
|
||||
#include <winsock.h>
|
||||
#endif
|
||||
|
||||
static const QString WCS_NAMESPACE = QStringLiteral( "http://www.opengis.net/wcs" );
|
||||
static const QString GML_NAMESPACE = QStringLiteral( "http://www.opengis.net/gml" );
|
||||
static const QString OGC_NAMESPACE = QStringLiteral( "http://www.opengis.net/ogc" );
|
||||
|
||||
QgsWCSServer::QgsWCSServer(
|
||||
const QString& configFilePath
|
||||
, const QgsServerSettings& settings
|
||||
, QMap<QString, QString> ¶meters
|
||||
, QgsWCSProjectParser* pp
|
||||
, QgsRequestHandler* rh
|
||||
, QgsAccessControl* accessControl
|
||||
)
|
||||
: QgsOWSServer(
|
||||
configFilePath
|
||||
, settings
|
||||
, parameters
|
||||
, rh
|
||||
, accessControl
|
||||
)
|
||||
, mConfigParser(
|
||||
pp
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
QgsWCSServer::QgsWCSServer()
|
||||
: QgsOWSServer(
|
||||
QString()
|
||||
, QgsServerSettings()
|
||||
, QMap<QString, QString>()
|
||||
, nullptr
|
||||
, nullptr
|
||||
)
|
||||
, mConfigParser( nullptr )
|
||||
{
|
||||
}
|
||||
|
||||
void QgsWCSServer::executeRequest()
|
||||
{
|
||||
//request type
|
||||
QString request = mParameters.value( QStringLiteral( "REQUEST" ) );
|
||||
if ( request.isEmpty() )
|
||||
{
|
||||
//do some error handling
|
||||
QgsDebugMsg( "unable to find 'REQUEST' parameter, exiting..." );
|
||||
mRequestHandler->setServiceException( QgsMapServiceException( QStringLiteral( "OperationNotSupported" ), QStringLiteral( "Please check the value of the REQUEST parameter" ) ) );
|
||||
return;
|
||||
}
|
||||
|
||||
if ( request.compare( QLatin1String( "GetCapabilities" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QDomDocument capabilitiesDocument;
|
||||
try
|
||||
{
|
||||
capabilitiesDocument = getCapabilities();
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
mRequestHandler->setServiceException( ex );
|
||||
return;
|
||||
}
|
||||
QgsDebugMsg( "seting GetCapabilities response" );
|
||||
mRequestHandler->setGetCapabilitiesResponse( capabilitiesDocument );
|
||||
return;
|
||||
}
|
||||
else if ( request.compare( QLatin1String( "DescribeCoverage" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QDomDocument describeDocument;
|
||||
try
|
||||
{
|
||||
describeDocument = describeCoverage();
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
mRequestHandler->setServiceException( ex );
|
||||
return;
|
||||
}
|
||||
QgsDebugMsg( "seting GetCapabilities response" );
|
||||
mRequestHandler->setGetCapabilitiesResponse( describeDocument );
|
||||
return;
|
||||
}
|
||||
else if ( request.compare( QLatin1String( "GetCoverage" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
QByteArray* coverageOutput;
|
||||
try
|
||||
{
|
||||
coverageOutput = getCoverage();
|
||||
}
|
||||
catch ( QgsMapServiceException& ex )
|
||||
{
|
||||
mRequestHandler->setServiceException( ex );
|
||||
return;
|
||||
}
|
||||
if ( coverageOutput )
|
||||
{
|
||||
mRequestHandler->setGetCoverageResponse( coverageOutput );
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
QDomDocument QgsWCSServer::getCapabilities()
|
||||
{
|
||||
QgsDebugMsg( "Entering." );
|
||||
QDomDocument doc;
|
||||
|
||||
//wcs:WCS_Capabilities element
|
||||
QDomElement wcsCapabilitiesElement = doc.createElement( QStringLiteral( "WCS_Capabilities" )/*wcs:WCS_Capabilities*/ );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
|
||||
doc.appendChild( wcsCapabilitiesElement );
|
||||
|
||||
if ( mConfigParser )
|
||||
{
|
||||
mConfigParser->serviceCapabilities( wcsCapabilitiesElement, doc );
|
||||
}
|
||||
|
||||
//INSERT Service
|
||||
|
||||
//wcs:Capability element
|
||||
QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wcs:Capability*/ );
|
||||
wcsCapabilitiesElement.appendChild( capabilityElement );
|
||||
|
||||
//wcs:Request element
|
||||
QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wcs:Request*/ );
|
||||
capabilityElement.appendChild( requestElement );
|
||||
|
||||
//wcs:GetCapabilities
|
||||
QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wcs:GetCapabilities*/ );
|
||||
requestElement.appendChild( getCapabilitiesElement );
|
||||
|
||||
QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wcs:DCPType*/ );
|
||||
getCapabilitiesElement.appendChild( dcpTypeElement );
|
||||
QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wcs:HTTP*/ );
|
||||
dcpTypeElement.appendChild( httpElement );
|
||||
|
||||
//Prepare url
|
||||
QString hrefString;
|
||||
if ( mConfigParser )
|
||||
{
|
||||
hrefString = mConfigParser->wcsServiceUrl();
|
||||
if ( hrefString.isEmpty() )
|
||||
{
|
||||
hrefString = mConfigParser->serviceUrl();
|
||||
}
|
||||
}
|
||||
if ( hrefString.isEmpty() )
|
||||
{
|
||||
hrefString = serviceUrl();
|
||||
}
|
||||
|
||||
QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wcs:Get*/ );
|
||||
httpElement.appendChild( getElement );
|
||||
QDomElement onlineResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wcs:OnlineResource*/ );
|
||||
onlineResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
|
||||
onlineResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
|
||||
getElement.appendChild( onlineResourceElement );
|
||||
|
||||
QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
|
||||
getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
|
||||
getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
|
||||
|
||||
QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
|
||||
describeCoverageElement.setTagName( QStringLiteral( "DescribeCoverage" ) );
|
||||
requestElement.appendChild( describeCoverageElement );
|
||||
|
||||
QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
|
||||
getCoverageElement.setTagName( QStringLiteral( "GetCoverage" ) );
|
||||
requestElement.appendChild( getCoverageElement );
|
||||
|
||||
/*
|
||||
* Adding layer list in ContentMetadata
|
||||
*/
|
||||
QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ );
|
||||
wcsCapabilitiesElement.appendChild( contentMetadataElement );
|
||||
/*
|
||||
* Adding layer list in contentMetadataElement
|
||||
*/
|
||||
if ( mConfigParser )
|
||||
{
|
||||
mConfigParser->wcsContentMetadata( contentMetadataElement, doc );
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
|
||||
QDomDocument QgsWCSServer::describeCoverage()
|
||||
{
|
||||
QgsDebugMsg( "Entering." );
|
||||
QDomDocument doc;
|
||||
|
||||
//wcs:WCS_Capabilities element
|
||||
QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
|
||||
doc.appendChild( coveDescElement );
|
||||
|
||||
//defining coverage name
|
||||
QString coveName = QLatin1String( "" );
|
||||
//read COVERAGE
|
||||
QMap<QString, QString>::const_iterator cove_name_it = mParameters.constFind( QStringLiteral( "COVERAGE" ) );
|
||||
if ( cove_name_it != mParameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
if ( coveName == QLatin1String( "" ) )
|
||||
{
|
||||
QMap<QString, QString>::const_iterator cove_name_it = mParameters.constFind( QStringLiteral( "IDENTIFIER" ) );
|
||||
if ( cove_name_it != mParameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
}
|
||||
mConfigParser->describeCoverage( coveName, coveDescElement, doc );
|
||||
return doc;
|
||||
}
|
||||
|
||||
QByteArray* QgsWCSServer::getCoverage()
|
||||
{
|
||||
QStringList wcsLayersId = mConfigParser->wcsLayers();
|
||||
|
||||
QList<QgsMapLayer*> layerList;
|
||||
|
||||
QStringList mErrors = QStringList();
|
||||
|
||||
//defining coverage name
|
||||
QString coveName = QLatin1String( "" );
|
||||
//read COVERAGE
|
||||
QMap<QString, QString>::const_iterator cove_name_it = mParameters.constFind( QStringLiteral( "COVERAGE" ) );
|
||||
if ( cove_name_it != mParameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
if ( coveName == QLatin1String( "" ) )
|
||||
{
|
||||
QMap<QString, QString>::const_iterator cove_name_it = mParameters.constFind( QStringLiteral( "IDENTIFIER" ) );
|
||||
if ( cove_name_it != mParameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
}
|
||||
|
||||
if ( coveName == QLatin1String( "" ) )
|
||||
{
|
||||
mErrors << QStringLiteral( "COVERAGE is mandatory" );
|
||||
}
|
||||
|
||||
layerList = mConfigParser->mapLayerFromCoverage( coveName );
|
||||
if ( layerList.size() < 1 )
|
||||
{
|
||||
mErrors << QStringLiteral( "The layer for the COVERAGE '%1' is not found" ).arg( coveName );
|
||||
}
|
||||
|
||||
bool conversionSuccess;
|
||||
// BBOX
|
||||
bool bboxOk = false;
|
||||
double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
|
||||
// WIDTh and HEIGHT
|
||||
int width = 0, height = 0;
|
||||
// CRS
|
||||
QString crs = QLatin1String( "" );
|
||||
|
||||
// read BBOX
|
||||
QMap<QString, QString>::const_iterator bbIt = mParameters.constFind( QStringLiteral( "BBOX" ) );
|
||||
if ( bbIt == mParameters.constEnd() )
|
||||
{
|
||||
minx = 0;
|
||||
miny = 0;
|
||||
maxx = 0;
|
||||
maxy = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
bboxOk = true;
|
||||
QString bbString = bbIt.value();
|
||||
minx = bbString.section( QStringLiteral( "," ), 0, 0 ).toDouble( &conversionSuccess );
|
||||
if ( !conversionSuccess ) {bboxOk = false;}
|
||||
miny = bbString.section( QStringLiteral( "," ), 1, 1 ).toDouble( &conversionSuccess );
|
||||
if ( !conversionSuccess ) {bboxOk = false;}
|
||||
maxx = bbString.section( QStringLiteral( "," ), 2, 2 ).toDouble( &conversionSuccess );
|
||||
if ( !conversionSuccess ) {bboxOk = false;}
|
||||
maxy = bbString.section( QStringLiteral( "," ), 3, 3 ).toDouble( &conversionSuccess );
|
||||
if ( !conversionSuccess ) {bboxOk = false;}
|
||||
}
|
||||
if ( !bboxOk )
|
||||
{
|
||||
mErrors << QStringLiteral( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" );
|
||||
}
|
||||
|
||||
// read WIDTH
|
||||
width = mParameters.value( QStringLiteral( "WIDTH" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
width = 0;
|
||||
// read HEIGHT
|
||||
height = mParameters.value( QStringLiteral( "HEIGHT" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
height = 0;
|
||||
}
|
||||
|
||||
if ( width < 0 || height < 0 )
|
||||
{
|
||||
mErrors << QStringLiteral( "The WIDTH and HEIGHT are mandatory and have to be integer" );
|
||||
}
|
||||
|
||||
crs = mParameters.value( QStringLiteral( "CRS" ), QLatin1String( "" ) );
|
||||
if ( crs == QLatin1String( "" ) )
|
||||
{
|
||||
mErrors << QStringLiteral( "The CRS is mandatory" );
|
||||
}
|
||||
|
||||
if ( mErrors.count() != 0 )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "RequestNotWellFormed" ), mErrors.join( QStringLiteral( ". " ) ) );
|
||||
}
|
||||
|
||||
QgsCoordinateReferenceSystem requestCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
|
||||
if ( !requestCRS.isValid() )
|
||||
{
|
||||
mErrors << QStringLiteral( "Could not create request CRS" );
|
||||
throw QgsMapServiceException( QStringLiteral( "RequestNotWellFormed" ), mErrors.join( QStringLiteral( ". " ) ) );
|
||||
}
|
||||
|
||||
QgsRectangle rect( minx, miny, maxx, maxy );
|
||||
|
||||
QgsMapLayer* layer = layerList.at( 0 );
|
||||
QgsRasterLayer* rLayer = qobject_cast<QgsRasterLayer*>( layer );
|
||||
if ( rLayer && wcsLayersId.contains( rLayer->id() ) )
|
||||
{
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !mAccessControl->layerReadPermission( rLayer ) )
|
||||
{
|
||||
throw QgsMapServiceException( QStringLiteral( "Security" ), QStringLiteral( "You are not allowed to access to this coverage" ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// RESPONSE_CRS
|
||||
QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
|
||||
crs = mParameters.value( QStringLiteral( "RESPONSE_CRS" ), QLatin1String( "" ) );
|
||||
if ( crs != QLatin1String( "" ) )
|
||||
{
|
||||
responseCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
|
||||
if ( !responseCRS.isValid() )
|
||||
{
|
||||
responseCRS = rLayer->crs();
|
||||
}
|
||||
}
|
||||
|
||||
// transform rect
|
||||
if ( requestCRS != rLayer->crs() )
|
||||
{
|
||||
QgsCoordinateTransform t( requestCRS, rLayer->crs() );
|
||||
rect = t.transformBoundingBox( rect );
|
||||
}
|
||||
|
||||
QTemporaryFile tempFile;
|
||||
tempFile.open();
|
||||
QgsRasterFileWriter fileWriter( tempFile.fileName() );
|
||||
|
||||
// clone pipe/provider
|
||||
QgsRasterPipe* pipe = new QgsRasterPipe();
|
||||
if ( !pipe->set( rLayer->dataProvider()->clone() ) )
|
||||
{
|
||||
mErrors << QStringLiteral( "Cannot set pipe provider" );
|
||||
throw QgsMapServiceException( QStringLiteral( "RequestNotWellFormed" ), mErrors.join( QStringLiteral( ". " ) ) );
|
||||
}
|
||||
|
||||
// add projector if necessary
|
||||
if ( responseCRS != rLayer->crs() )
|
||||
{
|
||||
QgsRasterProjector * projector = new QgsRasterProjector;
|
||||
projector->setCrs( rLayer->crs(), responseCRS );
|
||||
if ( !pipe->insert( 2, projector ) )
|
||||
{
|
||||
mErrors << QStringLiteral( "Cannot set pipe projector" );
|
||||
throw QgsMapServiceException( QStringLiteral( "RequestNotWellFormed" ), mErrors.join( QStringLiteral( ". " ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsRasterFileWriter::WriterError err = fileWriter.writeRaster( pipe, width, height, rect, responseCRS );
|
||||
if ( err != QgsRasterFileWriter::NoError )
|
||||
{
|
||||
mErrors << QStringLiteral( "Cannot write raster error code: %1" ).arg( err );
|
||||
throw QgsMapServiceException( QStringLiteral( "RequestNotWellFormed" ), mErrors.join( QStringLiteral( ". " ) ) );
|
||||
}
|
||||
delete pipe;
|
||||
QByteArray* ba = nullptr;
|
||||
ba = new QByteArray();
|
||||
*ba = tempFile.readAll();
|
||||
|
||||
return ba;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
QString QgsWCSServer::serviceUrl() const
|
||||
{
|
||||
QUrl mapUrl( getenv( "REQUEST_URI" ) );
|
||||
mapUrl.setHost( getenv( "SERVER_NAME" ) );
|
||||
|
||||
//Add non-default ports to url
|
||||
QString portString = getenv( "SERVER_PORT" );
|
||||
if ( !portString.isEmpty() )
|
||||
{
|
||||
bool portOk;
|
||||
int portNumber = portString.toInt( &portOk );
|
||||
if ( portOk )
|
||||
{
|
||||
if ( portNumber != 80 )
|
||||
{
|
||||
mapUrl.setPort( portNumber );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( QString( getenv( "HTTPS" ) ).compare( QLatin1String( "on" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mapUrl.setScheme( QStringLiteral( "https" ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
mapUrl.setScheme( QStringLiteral( "http" ) );
|
||||
}
|
||||
|
||||
QList<QPair<QString, QString> > queryItems = mapUrl.queryItems();
|
||||
QList<QPair<QString, QString> >::const_iterator queryIt = queryItems.constBegin();
|
||||
for ( ; queryIt != queryItems.constEnd(); ++queryIt )
|
||||
{
|
||||
if ( queryIt->first.compare( QLatin1String( "REQUEST" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mapUrl.removeQueryItem( queryIt->first );
|
||||
}
|
||||
else if ( queryIt->first.compare( QLatin1String( "VERSION" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mapUrl.removeQueryItem( queryIt->first );
|
||||
}
|
||||
else if ( queryIt->first.compare( QLatin1String( "SERVICE" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mapUrl.removeQueryItem( queryIt->first );
|
||||
}
|
||||
else if ( queryIt->first.compare( QLatin1String( "_DC" ), Qt::CaseInsensitive ) == 0 )
|
||||
{
|
||||
mapUrl.removeQueryItem( queryIt->first );
|
||||
}
|
||||
}
|
||||
return mapUrl.toString();
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgswcsserver.h
|
||||
-------------------
|
||||
begin : December 9, 2013
|
||||
copyright : (C) 2013 by René-Luc D'Hont
|
||||
email : rldhont at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSWCSSERVER_H
|
||||
#define QGSWCSSERVER_H
|
||||
|
||||
#include <QDomDocument>
|
||||
#include <QMap>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
#include "qgis.h"
|
||||
#include "qgsowsserver.h"
|
||||
|
||||
class QgsWCSProjectParser;
|
||||
class QgsRequestHandler;
|
||||
|
||||
/** This class handles all the wcs server requests. The parameters and values have to be passed in the form of
|
||||
a map<QString, QString>. This map is usually generated by a subclass of QgsWMSRequestHandler, which makes QgsWCSServer
|
||||
independent from any server side technology*/
|
||||
|
||||
class QgsWCSServer: public QgsOWSServer
|
||||
{
|
||||
public:
|
||||
//! Constructor. Takes parameter map and a pointer to a renderer object (does not take ownership)
|
||||
QgsWCSServer(
|
||||
const QString& configFilePath
|
||||
, const QgsServerSettings& settings
|
||||
, QMap<QString, QString>& parameters
|
||||
, QgsWCSProjectParser* pp
|
||||
, QgsRequestHandler* rh
|
||||
, QgsAccessControl* accessControl
|
||||
);
|
||||
|
||||
void executeRequest() override;
|
||||
|
||||
//! Returns an XML file with the capabilities description (as described in the WFS specs)
|
||||
QDomDocument getCapabilities();
|
||||
|
||||
//! Returns an XML file with the describe Coverage (as described in the WCS specs)
|
||||
QDomDocument describeCoverage();
|
||||
|
||||
//! Creates a file which is the result of the getCoverage request.
|
||||
QByteArray* getCoverage();
|
||||
|
||||
//! Sets configuration parser for administration settings. Does not take ownership
|
||||
void setAdminConfigParser( QgsWCSProjectParser* parser ) { mConfigParser = parser; }
|
||||
|
||||
private:
|
||||
//! Don't use the default constructor
|
||||
QgsWCSServer();
|
||||
|
||||
//! Get service address from REQUEST_URI if not specified in the configuration
|
||||
QString serviceUrl() const;
|
||||
|
||||
QgsWCSProjectParser* mConfigParser;
|
||||
|
||||
};
|
||||
|
||||
#endif
|
@ -9,4 +9,5 @@ SET (CMAKE_LIBRARY_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/${QGIS_SERVER_MODUL
|
||||
ADD_SUBDIRECTORY(DummyService)
|
||||
ADD_SUBDIRECTORY(wms)
|
||||
ADD_SUBDIRECTORY(wfs)
|
||||
ADD_SUBDIRECTORY(wcs)
|
||||
|
||||
|
59
src/server/services/wcs/CMakeLists.txt
Normal file
59
src/server/services/wcs/CMakeLists.txt
Normal file
@ -0,0 +1,59 @@
|
||||
|
||||
########################################################
|
||||
# Files
|
||||
|
||||
SET (wcs_SRCS
|
||||
qgswcs.cpp
|
||||
qgswcsutils.cpp
|
||||
qgswcsgetcapabilities.cpp
|
||||
qgswcsdescribecoverage.cpp
|
||||
qgswcsgetcoverage.cpp
|
||||
)
|
||||
|
||||
########################################################
|
||||
# Build
|
||||
|
||||
ADD_LIBRARY (wcs MODULE ${wcs_SRCS})
|
||||
|
||||
|
||||
INCLUDE_DIRECTORIES(SYSTEM
|
||||
${GDAL_INCLUDE_DIR}
|
||||
${GEOS_INCLUDE_DIR}
|
||||
${PROJ_INCLUDE_DIR}
|
||||
${POSTGRES_INCLUDE_DIR}
|
||||
)
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/python
|
||||
${CMAKE_BINARY_DIR}/src/analysis
|
||||
${CMAKE_BINARY_DIR}/src/server
|
||||
${CMAKE_CURRENT_BINARY_DIR}
|
||||
../../../core
|
||||
../../../core/dxf
|
||||
../../../core/geometry
|
||||
../../../core/raster
|
||||
../../../core/symbology-ng
|
||||
../../../core/composer
|
||||
../../../core/layertree
|
||||
../..
|
||||
..
|
||||
.
|
||||
)
|
||||
|
||||
|
||||
#endif
|
||||
TARGET_LINK_LIBRARIES(wcs
|
||||
qgis_core
|
||||
qgis_server
|
||||
)
|
||||
|
||||
|
||||
########################################################
|
||||
# Install
|
||||
|
||||
INSTALL(TARGETS wcs
|
||||
RUNTIME DESTINATION ${QGIS_SERVER_MODULE_DIR}
|
||||
LIBRARY DESTINATION ${QGIS_SERVER_MODULE_DIR}
|
||||
)
|
||||
|
124
src/server/services/wcs/qgswcs.cpp
Normal file
124
src/server/services/wcs/qgswcs.cpp
Normal file
@ -0,0 +1,124 @@
|
||||
/***************************************************************************
|
||||
qgswcs.cpp
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgsmodule.h"
|
||||
#include "qgswcsutils.h"
|
||||
#include "qgswcsgetcapabilities.h"
|
||||
#include "qgswcsdescribecoverage.h"
|
||||
#include "qgswcsgetcoverage.h"
|
||||
|
||||
#define QSTR_COMPARE( str, lit )\
|
||||
(str.compare( QStringLiteral( lit ), Qt::CaseInsensitive ) == 0)
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
class Service: public QgsService
|
||||
{
|
||||
public:
|
||||
// Constructor
|
||||
Service( QgsServerInterface* serverIface )
|
||||
: mServerIface( serverIface )
|
||||
{}
|
||||
|
||||
QString name() const { return QStringLiteral( "WCS" ); }
|
||||
QString version() const { return implementationVersion(); }
|
||||
|
||||
bool allowMethod( QgsServerRequest::Method method ) const
|
||||
{
|
||||
return method == QgsServerRequest::GetMethod || method == QgsServerRequest::PostMethod;
|
||||
}
|
||||
|
||||
void executeRequest( const QgsServerRequest& request, QgsServerResponse& response,
|
||||
QgsProject* project )
|
||||
{
|
||||
Q_UNUSED( project );
|
||||
|
||||
QgsServerRequest::Parameters params = request.parameters();
|
||||
QString versionString = params.value( "VERSION" );
|
||||
|
||||
// Set the default version
|
||||
if ( versionString.isEmpty() )
|
||||
{
|
||||
versionString = version();
|
||||
}
|
||||
|
||||
// Get the request
|
||||
QString req = params.value( QStringLiteral( "REQUEST" ) );
|
||||
if ( req.isEmpty() )
|
||||
{
|
||||
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
|
||||
QStringLiteral( "Please check the value of the REQUEST parameter" ) );
|
||||
}
|
||||
|
||||
if ( QSTR_COMPARE( req, "GetCapabilities" ) )
|
||||
{
|
||||
writeGetCapabilities( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if ( QSTR_COMPARE( req, "DescribeCoverage" ) )
|
||||
{
|
||||
writeDescribeCoverage( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if ( QSTR_COMPARE( req, "GetCoverage" ) )
|
||||
{
|
||||
writeGetCoverage( mServerIface, versionString, request, response );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Operation not supported
|
||||
throw QgsServiceException( QStringLiteral( "OperationNotSupported" ),
|
||||
QStringLiteral( "Request %1 is not supported" ).arg( req ) );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
QgsServerInterface* mServerIface;
|
||||
};
|
||||
|
||||
|
||||
} // namespace QgsWfs
|
||||
|
||||
|
||||
// Module
|
||||
class QgsWcsModule: public QgsServiceModule
|
||||
{
|
||||
public:
|
||||
void registerSelf( QgsServiceRegistry& registry, QgsServerInterface* serverIface )
|
||||
{
|
||||
QgsDebugMsg( "WCSModule::registerSelf called" );
|
||||
registry.registerService( new QgsWcs::Service( serverIface ) );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Entry points
|
||||
QGISEXTERN QgsServiceModule* QGS_ServiceModule_Init()
|
||||
{
|
||||
static QgsWcsModule module;
|
||||
return &module;
|
||||
}
|
||||
QGISEXTERN void QGS_ServiceModule_Exit( QgsServiceModule* )
|
||||
{
|
||||
// Nothing to do
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
83
src/server/services/wcs/qgswcsdescribecoverage.cpp
Normal file
83
src/server/services/wcs/qgswcsdescribecoverage.cpp
Normal file
@ -0,0 +1,83 @@
|
||||
/***************************************************************************
|
||||
qgswcsdescribecoverage.cpp
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgswcsutils.h"
|
||||
#include "qgswcsdescribecoverage.h"
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Output WCS DescribeCoverage response
|
||||
*/
|
||||
void writeDescribeCoverage( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response )
|
||||
{
|
||||
QDomDocument doc = createDescribeCoverageDocument( serverIface, version, request );
|
||||
|
||||
response.setHeader( "Content-Type", "text/xml; charset=utf-8" );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
QDomDocument createDescribeCoverageDocument( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request )
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
|
||||
QDomDocument doc;
|
||||
|
||||
QgsServerRequest::Parameters parameters = request.parameters();
|
||||
|
||||
QgsWCSProjectParser* configParser = getConfigParser( serverIface );
|
||||
|
||||
//wcs:WCS_Capabilities element
|
||||
QDomElement coveDescElement = doc.createElement( QStringLiteral( "CoverageDescription" )/*wcs:CoverageDescription*/ );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/describeCoverage.xsd" );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
|
||||
coveDescElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "version" ), QStringLiteral( "1.0.0" ) );
|
||||
coveDescElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
|
||||
doc.appendChild( coveDescElement );
|
||||
|
||||
//defining coverage name
|
||||
QString coveName;
|
||||
//read COVERAGE
|
||||
QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
|
||||
if ( cove_name_it != parameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
if ( coveName.isEmpty() )
|
||||
{
|
||||
QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
|
||||
if ( cove_name_it != parameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
}
|
||||
configParser->describeCoverage( coveName, coveDescElement, doc );
|
||||
return doc;
|
||||
}
|
||||
|
||||
} // namespace QgsWcs
|
||||
|
||||
|
||||
|
41
src/server/services/wcs/qgswcsdescribecoverage.h
Normal file
41
src/server/services/wcs/qgswcsdescribecoverage.h
Normal file
@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
qgswcsdescribecoverage.h
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSWCSDESCRIBECOVERAGE_H
|
||||
#define QGSWCSDESCRIBECOVERAGE_H
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Create describe coverage document
|
||||
*/
|
||||
QDomDocument createDescribeCoverageDocument( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request );
|
||||
|
||||
/** Output WCS DescribeCoverage response
|
||||
*/
|
||||
void writeDescribeCoverage( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response );
|
||||
|
||||
} // samespace QgsWcs
|
||||
|
||||
#endif
|
||||
|
121
src/server/services/wcs/qgswcsgetcapabilities.cpp
Normal file
121
src/server/services/wcs/qgswcsgetcapabilities.cpp
Normal file
@ -0,0 +1,121 @@
|
||||
/***************************************************************************
|
||||
qgswcsgecapabilities.cpp
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgswcsutils.h"
|
||||
#include "qgswcsgetcapabilities.h"
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Output WCS GetCapabilities response
|
||||
*/
|
||||
void writeGetCapabilities( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response )
|
||||
{
|
||||
QDomDocument doc = createGetCapabilitiesDocument( serverIface, version, request );
|
||||
|
||||
response.setHeader( "Content-Type", "text/xml; charset=utf-8" );
|
||||
response.write( doc.toByteArray() );
|
||||
}
|
||||
|
||||
|
||||
QDomDocument createGetCapabilitiesDocument( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request )
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
|
||||
QDomDocument doc;
|
||||
|
||||
QgsWCSProjectParser* configParser = getConfigParser( serverIface );
|
||||
|
||||
//wcs:WCS_Capabilities element
|
||||
QDomElement wcsCapabilitiesElement = doc.createElement( QStringLiteral( "WCS_Capabilities" )/*wcs:WCS_Capabilities*/ );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns" ), WCS_NAMESPACE );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xsi" ), QStringLiteral( "http://www.w3.org/2001/XMLSchema-instance" ) );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xsi:schemaLocation" ), WCS_NAMESPACE + " http://schemas.opengis.net/wcs/1.0.0/wcsCapabilities.xsd" );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:gml" ), GML_NAMESPACE );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "xmlns:xlink" ), QStringLiteral( "http://www.w3.org/1999/xlink" ) );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "version" ), implementationVersion() );
|
||||
wcsCapabilitiesElement.setAttribute( QStringLiteral( "updateSequence" ), QStringLiteral( "0" ) );
|
||||
doc.appendChild( wcsCapabilitiesElement );
|
||||
|
||||
configParser->serviceCapabilities( wcsCapabilitiesElement, doc );
|
||||
|
||||
//INSERT Service
|
||||
|
||||
//wcs:Capability element
|
||||
QDomElement capabilityElement = doc.createElement( QStringLiteral( "Capability" )/*wcs:Capability*/ );
|
||||
wcsCapabilitiesElement.appendChild( capabilityElement );
|
||||
|
||||
//wcs:Request element
|
||||
QDomElement requestElement = doc.createElement( QStringLiteral( "Request" )/*wcs:Request*/ );
|
||||
capabilityElement.appendChild( requestElement );
|
||||
|
||||
//wcs:GetCapabilities
|
||||
QDomElement getCapabilitiesElement = doc.createElement( QStringLiteral( "GetCapabilities" )/*wcs:GetCapabilities*/ );
|
||||
requestElement.appendChild( getCapabilitiesElement );
|
||||
|
||||
QDomElement dcpTypeElement = doc.createElement( QStringLiteral( "DCPType" )/*wcs:DCPType*/ );
|
||||
getCapabilitiesElement.appendChild( dcpTypeElement );
|
||||
QDomElement httpElement = doc.createElement( QStringLiteral( "HTTP" )/*wcs:HTTP*/ );
|
||||
dcpTypeElement.appendChild( httpElement );
|
||||
|
||||
//Prepare url
|
||||
QString hrefString = serviceUrl( request, configParser );
|
||||
|
||||
QDomElement getElement = doc.createElement( QStringLiteral( "Get" )/*wcs:Get*/ );
|
||||
httpElement.appendChild( getElement );
|
||||
QDomElement onlineResourceElement = doc.createElement( QStringLiteral( "OnlineResource" )/*wcs:OnlineResource*/ );
|
||||
onlineResourceElement.setAttribute( QStringLiteral( "xlink:type" ), QStringLiteral( "simple" ) );
|
||||
onlineResourceElement.setAttribute( QStringLiteral( "xlink:href" ), hrefString );
|
||||
getElement.appendChild( onlineResourceElement );
|
||||
|
||||
QDomElement getCapabilitiesDhcTypePostElement = dcpTypeElement.cloneNode().toElement();//this is the same as for 'GetCapabilities'
|
||||
getCapabilitiesDhcTypePostElement.firstChild().firstChild().toElement().setTagName( QStringLiteral( "Post" ) );
|
||||
getCapabilitiesElement.appendChild( getCapabilitiesDhcTypePostElement );
|
||||
|
||||
QDomElement describeCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
|
||||
describeCoverageElement.setTagName( QStringLiteral( "DescribeCoverage" ) );
|
||||
requestElement.appendChild( describeCoverageElement );
|
||||
|
||||
QDomElement getCoverageElement = getCapabilitiesElement.cloneNode().toElement();//this is the same as 'GetCapabilities'
|
||||
getCoverageElement.setTagName( QStringLiteral( "GetCoverage" ) );
|
||||
requestElement.appendChild( getCoverageElement );
|
||||
|
||||
/*
|
||||
* Adding layer list in ContentMetadata
|
||||
*/
|
||||
QDomElement contentMetadataElement = doc.createElement( QStringLiteral( "ContentMetadata" )/*wcs:ContentMetadata*/ );
|
||||
wcsCapabilitiesElement.appendChild( contentMetadataElement );
|
||||
/*
|
||||
* Adding layer list in contentMetadataElement
|
||||
*/
|
||||
if ( configParser )
|
||||
{
|
||||
configParser->wcsContentMetadata( contentMetadataElement, doc );
|
||||
}
|
||||
|
||||
return doc;
|
||||
|
||||
}
|
||||
|
||||
} // namespace QgsWcs
|
||||
|
||||
|
||||
|
41
src/server/services/wcs/qgswcsgetcapabilities.h
Normal file
41
src/server/services/wcs/qgswcsgetcapabilities.h
Normal file
@ -0,0 +1,41 @@
|
||||
/***************************************************************************
|
||||
qgswcsgecapabilities.h
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSWCSGETCAPABILITIES_H
|
||||
#define QGSWCSGETCAPABILITIES_H
|
||||
|
||||
#include <QDomDocument>
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Create get capabilities document
|
||||
*/
|
||||
QDomDocument createGetCapabilitiesDocument( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request );
|
||||
|
||||
/** Output WCS GetCapabilities response
|
||||
*/
|
||||
void writeGetCapabilities( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response );
|
||||
|
||||
} // samespace QgsWcs
|
||||
|
||||
#endif
|
||||
|
205
src/server/services/wcs/qgswcsgetcoverage.cpp
Normal file
205
src/server/services/wcs/qgswcsgetcoverage.cpp
Normal file
@ -0,0 +1,205 @@
|
||||
/***************************************************************************
|
||||
qgswcsgetcoverage.cpp
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#include "qgswcsutils.h"
|
||||
#include "qgsrasterlayer.h"
|
||||
#include "qgsrasterdataprovider.h"
|
||||
#include "qgsrasterpipe.h"
|
||||
#include "qgsrasterprojector.h"
|
||||
#include "qgsrasterfilewriter.h"
|
||||
#include "qgswcsgetcoverage.h"
|
||||
|
||||
#include <QTemporaryFile>
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Output WCS DescribeCoverage response
|
||||
*/
|
||||
void writeGetCoverage( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response )
|
||||
{
|
||||
Q_UNUSED( version );
|
||||
|
||||
response.write( getCoverageData( serverIface, request ) );
|
||||
response.setHeader( "Content-Type", "image/tiff" );
|
||||
}
|
||||
|
||||
QByteArray getCoverageData( QgsServerInterface* serverIface, const QgsServerRequest& request )
|
||||
{
|
||||
QgsWCSProjectParser* configParser = getConfigParser( serverIface );
|
||||
|
||||
QgsAccessControl* accessControl = serverIface->accessControls();
|
||||
|
||||
QStringList wcsLayersId = configParser->wcsLayers();
|
||||
|
||||
QList<QgsMapLayer*> layerList;
|
||||
|
||||
QgsServerRequest::Parameters parameters = request.parameters();
|
||||
|
||||
//defining coverage name
|
||||
QString coveName;
|
||||
//read COVERAGE
|
||||
QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "COVERAGE" ) );
|
||||
if ( cove_name_it != parameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
if ( coveName.isEmpty() )
|
||||
{
|
||||
QMap<QString, QString>::const_iterator cove_name_it = parameters.constFind( QStringLiteral( "IDENTIFIER" ) );
|
||||
if ( cove_name_it != parameters.constEnd() )
|
||||
{
|
||||
coveName = cove_name_it.value();
|
||||
}
|
||||
}
|
||||
|
||||
if ( coveName.isEmpty() )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "COVERAGE is mandatory" ) );
|
||||
}
|
||||
|
||||
layerList = configParser->mapLayerFromCoverage( coveName );
|
||||
if ( layerList.size() < 1 )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "The layer for the COVERAGE '%1' is not found" ).arg( coveName ) );
|
||||
}
|
||||
|
||||
double minx = 0.0, miny = 0.0, maxx = 0.0, maxy = 0.0;
|
||||
// WIDTh and HEIGHT
|
||||
int width = 0, height = 0;
|
||||
// CRS
|
||||
QString crs;
|
||||
|
||||
// read BBOX
|
||||
QgsRectangle bbox = parseBbox( parameters.value( QStringLiteral( "BBOX" ) ) );
|
||||
if ( !bbox.isEmpty() )
|
||||
{
|
||||
minx = bbox.xMinimum();
|
||||
miny = bbox.yMinimum();
|
||||
maxx = bbox.xMaximum();
|
||||
maxy = bbox.yMaximum();
|
||||
}
|
||||
else
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "The BBOX is mandatory and has to be xx.xxx,yy.yyy,xx.xxx,yy.yyy" ) );
|
||||
}
|
||||
|
||||
// read WIDTH
|
||||
bool conversionSuccess = false;
|
||||
width = parameters.value( QStringLiteral( "WIDTH" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
width = 0;
|
||||
}
|
||||
// read HEIGHT
|
||||
height = parameters.value( QStringLiteral( "HEIGHT" ), QStringLiteral( "0" ) ).toInt( &conversionSuccess );
|
||||
if ( !conversionSuccess )
|
||||
{
|
||||
height = 0;
|
||||
}
|
||||
|
||||
if ( width < 0 || height < 0 )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "The WIDTH and HEIGHT are mandatory and have to be integer" ) );
|
||||
}
|
||||
|
||||
crs = parameters.value( QStringLiteral( "CRS" ) );
|
||||
if ( crs.isEmpty() )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "The CRS is mandatory" ) );
|
||||
}
|
||||
|
||||
QgsCoordinateReferenceSystem requestCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
|
||||
if ( !requestCRS.isValid() )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "Invalid CRS" ) );
|
||||
}
|
||||
|
||||
QgsRectangle rect( minx, miny, maxx, maxy );
|
||||
|
||||
QgsMapLayer* layer = layerList.at( 0 );
|
||||
QgsRasterLayer* rLayer = qobject_cast<QgsRasterLayer*>( layer );
|
||||
if ( rLayer && wcsLayersId.contains( rLayer->id() ) )
|
||||
{
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
if ( !accessControl->layerReadPermission( rLayer ) )
|
||||
{
|
||||
throw QgsSecurityAccessException( QStringLiteral( "You are not allowed to access to this coverage" ) );
|
||||
}
|
||||
#endif
|
||||
|
||||
// RESPONSE_CRS
|
||||
QgsCoordinateReferenceSystem responseCRS = rLayer->crs();
|
||||
crs = parameters.value( QStringLiteral( "RESPONSE_CRS" ) );
|
||||
if ( crs.isEmpty() )
|
||||
{
|
||||
responseCRS = QgsCoordinateReferenceSystem::fromOgcWmsCrs( crs );
|
||||
if ( !responseCRS.isValid() )
|
||||
{
|
||||
responseCRS = rLayer->crs();
|
||||
}
|
||||
}
|
||||
|
||||
// transform rect
|
||||
if ( requestCRS != rLayer->crs() )
|
||||
{
|
||||
QgsCoordinateTransform t( requestCRS, rLayer->crs() );
|
||||
rect = t.transformBoundingBox( rect );
|
||||
}
|
||||
|
||||
QTemporaryFile tempFile;
|
||||
tempFile.open();
|
||||
QgsRasterFileWriter fileWriter( tempFile.fileName() );
|
||||
|
||||
// clone pipe/provider
|
||||
QgsRasterPipe pipe;
|
||||
if ( !pipe.set( rLayer->dataProvider()->clone() ) )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "Cannet set pipe provider" ) );
|
||||
}
|
||||
|
||||
// add projector if necessary
|
||||
if ( responseCRS != rLayer->crs() )
|
||||
{
|
||||
QgsRasterProjector * projector = new QgsRasterProjector;
|
||||
projector->setCrs( rLayer->crs(), responseCRS );
|
||||
if ( !pipe.insert( 2, projector ) )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "Cannot set pipe projector" ) );
|
||||
}
|
||||
}
|
||||
|
||||
QgsRasterFileWriter::WriterError err = fileWriter.writeRaster( &pipe, width, height, rect, responseCRS );
|
||||
if ( err != QgsRasterFileWriter::NoError )
|
||||
{
|
||||
throw QgsRequestNotWellFormedException( QStringLiteral( "Cannot write raster error code: %1" ).arg( err ) );
|
||||
}
|
||||
return tempFile.readAll();
|
||||
}
|
||||
else
|
||||
{
|
||||
return QByteArray();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace QgsWcs
|
||||
|
||||
|
||||
|
40
src/server/services/wcs/qgswcsgetcoverage.h
Normal file
40
src/server/services/wcs/qgswcsgetcoverage.h
Normal file
@ -0,0 +1,40 @@
|
||||
/***************************************************************************
|
||||
qgswcsgetcoverage.h
|
||||
-------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSWCSGETCOVERAGE_H
|
||||
#define QGSWCSGETCOVERAGE_H
|
||||
|
||||
#include <QByteArray>
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/** Output WCS GetCoverage response
|
||||
*/
|
||||
void writeGetCoverage( QgsServerInterface* serverIface, const QString& version,
|
||||
const QgsServerRequest& request, QgsServerResponse& response );
|
||||
|
||||
/**
|
||||
* Compute coverage data
|
||||
*/
|
||||
QByteArray getCoverageData( QgsServerInterface* serverIface, const QgsServerRequest& request );
|
||||
|
||||
} // samespace QgsWcs
|
||||
|
||||
#endif
|
||||
|
80
src/server/services/wcs/qgswcsserviceexception.h
Normal file
80
src/server/services/wcs/qgswcsserviceexception.h
Normal file
@ -0,0 +1,80 @@
|
||||
/***************************************************************************
|
||||
qgswcsserviceexception.h
|
||||
------------------------
|
||||
begin : January 17, 2017
|
||||
copyright : (C) 2017 by David Marteau
|
||||
email : david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef QGSWCSSERVICEEXCEPTION_H
|
||||
#define QGSWCSSERVICEEXCEPTION_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include "qgsserverexception.h"
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsserviceException
|
||||
* \brief Exception class for WFS service exceptions.
|
||||
*/
|
||||
class QgsServiceException : public QgsOgcServiceException
|
||||
{
|
||||
public:
|
||||
QgsServiceException( const QString& code, const QString& message,
|
||||
int responseCode = 200 )
|
||||
: QgsOgcServiceException( code, message, QString(), responseCode, QStringLiteral( "1.2.0" ) )
|
||||
{}
|
||||
|
||||
QgsServiceException( const QString& code, const QString& message, const QString& locator,
|
||||
int responseCode = 200 )
|
||||
: QgsOgcServiceException( code, message, locator, responseCode, QStringLiteral( "1.2.0" ) )
|
||||
{}
|
||||
|
||||
};
|
||||
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsSecurityAccessException
|
||||
* \brief Exception thrown when data access violates access controls
|
||||
*/
|
||||
class QgsSecurityAccessException: public QgsServiceException
|
||||
{
|
||||
public:
|
||||
QgsSecurityAccessException( const QString& message, const QString& locator = QString() )
|
||||
: QgsServiceException( QStringLiteral( "Security" ), message, locator, 403 )
|
||||
{}
|
||||
};
|
||||
|
||||
/** \ingroup server
|
||||
* \class QgsRequestNotWellFormedException
|
||||
* \brief Exception thrown in case of malformed request
|
||||
*/
|
||||
class QgsRequestNotWellFormedException: public QgsServiceException
|
||||
{
|
||||
public:
|
||||
QgsRequestNotWellFormedException( const QString& message, const QString& locator = QString() )
|
||||
: QgsServiceException( QStringLiteral( "RequestNotWellFormed" ), message, locator, 400 )
|
||||
{}
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
} // namespace QgsWcs
|
||||
|
||||
#endif
|
||||
|
94
src/server/services/wcs/qgswcsutils.cpp
Normal file
94
src/server/services/wcs/qgswcsutils.cpp
Normal file
@ -0,0 +1,94 @@
|
||||
/***************************************************************************
|
||||
qgswcsutils.cpp
|
||||
-------------------------
|
||||
begin : December 9, 2013
|
||||
copyright : (C) 2013 by René-Luc D'Hont
|
||||
email : rldhont at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
|
||||
#include "qgswcsutils.h"
|
||||
#include "qgsconfigcache.h"
|
||||
|
||||
namespace QgsWcs
|
||||
{
|
||||
QString implementationVersion()
|
||||
{
|
||||
return QStringLiteral( "1.0.0" );
|
||||
}
|
||||
|
||||
// Return the wms config parser (Transitional)
|
||||
QgsWCSProjectParser* getConfigParser( QgsServerInterface* serverIface )
|
||||
{
|
||||
QString configFilePath = serverIface->configFilePath();
|
||||
|
||||
QgsWCSProjectParser* parser = QgsConfigCache::instance()->wcsConfiguration( configFilePath, serverIface->accessControls() );
|
||||
if ( !parser )
|
||||
{
|
||||
throw QgsServiceException(
|
||||
QStringLiteral( "WFS configuration error" ),
|
||||
QStringLiteral( "There was an error reading the project file or the SLD configuration" ) );
|
||||
}
|
||||
return parser;
|
||||
}
|
||||
|
||||
QString serviceUrl( const QgsServerRequest& request, QgsWCSProjectParser* parser )
|
||||
{
|
||||
QString href;
|
||||
if ( parser )
|
||||
{
|
||||
href = parser->wcsServiceUrl();
|
||||
if ( href.isEmpty() )
|
||||
{
|
||||
href = parser->serviceUrl();
|
||||
}
|
||||
}
|
||||
|
||||
// Build default url
|
||||
if ( href.isEmpty() )
|
||||
{
|
||||
QUrl url = request.url();
|
||||
QUrlQuery q( url );
|
||||
|
||||
q.removeAllQueryItems( QStringLiteral( "REQUEST" ) );
|
||||
q.removeAllQueryItems( QStringLiteral( "VERSION" ) );
|
||||
q.removeAllQueryItems( QStringLiteral( "SERVICE" ) );
|
||||
q.removeAllQueryItems( QStringLiteral( "_DC" ) );
|
||||
|
||||
url.setQuery( q );
|
||||
href = url.toString( QUrl::FullyDecoded );
|
||||
|
||||
}
|
||||
|
||||
return href;
|
||||
}
|
||||
|
||||
QgsRectangle parseBbox( const QString& bboxStr )
|
||||
{
|
||||
QStringList lst = bboxStr.split( QStringLiteral( "," ) );
|
||||
if ( lst.count() != 4 )
|
||||
return QgsRectangle();
|
||||
|
||||
double d[4];
|
||||
bool ok;
|
||||
for ( int i = 0; i < 4; i++ )
|
||||
{
|
||||
lst[i].replace( QLatin1String( " " ), QLatin1String( "+" ) );
|
||||
d[i] = lst[i].toDouble( &ok );
|
||||
if ( !ok )
|
||||
return QgsRectangle();
|
||||
}
|
||||
return QgsRectangle( d[0], d[1], d[2], d[3] );
|
||||
}
|
||||
|
||||
} // namespace QgsWfs
|
||||
|
||||
|
70
src/server/services/wcs/qgswcsutils.h
Normal file
70
src/server/services/wcs/qgswcsutils.h
Normal file
@ -0,0 +1,70 @@
|
||||
/***************************************************************************
|
||||
qgswcsutils.h
|
||||
|
||||
Define WCS service utility functions
|
||||
------------------------------------
|
||||
begin : January 16 , 2017
|
||||
copyright : (C) 2013 by René-Luc D'Hont ( parts from qgswcsserver )
|
||||
(C) 2017 by David Marteau
|
||||
email : rldhont at 3liz dot com
|
||||
david dot marteau at 3liz dot com
|
||||
***************************************************************************/
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
#ifndef QGSWCSUTILS_H
|
||||
#define QGSWCSUTILS_H
|
||||
|
||||
#include "qgsmodule.h"
|
||||
#include "qgswcsprojectparser.h"
|
||||
#include "qgswcsserviceexception.h"
|
||||
|
||||
/**
|
||||
* \ingroup server
|
||||
* WCS implementation
|
||||
*/
|
||||
|
||||
//! WCS implementation
|
||||
namespace QgsWcs
|
||||
{
|
||||
|
||||
/**
|
||||
* Return the highest version supported by this implementation
|
||||
*/
|
||||
QString implementationVersion();
|
||||
|
||||
/**
|
||||
* Return the wms config parser (Transitional)
|
||||
*
|
||||
* XXX This is needed in the current implementation.
|
||||
* This should disappear as soon we get rid of singleton.
|
||||
*/
|
||||
QgsWCSProjectParser* getConfigParser( QgsServerInterface* serverIface );
|
||||
|
||||
/**
|
||||
* Service URL string
|
||||
*/
|
||||
QString serviceUrl( const QgsServerRequest& request, QgsWCSProjectParser* parser = nullptr );
|
||||
|
||||
/**
|
||||
* Parse bounding box
|
||||
*/
|
||||
//XXX At some point, should be moved to common library
|
||||
QgsRectangle parseBbox( const QString& bboxStr );
|
||||
|
||||
// Define namespaces used in WFS documents
|
||||
const QString WCS_NAMESPACE = QStringLiteral( "http://www.opengis.net/wcs" );
|
||||
const QString GML_NAMESPACE = QStringLiteral( "http://www.opengis.net/gml" );
|
||||
const QString OGC_NAMESPACE = QStringLiteral( "http://www.opengis.net/ogc" );
|
||||
|
||||
} // namespace QgsWcs
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -26,7 +26,6 @@ INCLUDE_DIRECTORIES(SYSTEM
|
||||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${CMAKE_BINARY_DIR}/src/core
|
||||
${CMAKE_BINARY_DIR}/src/gui
|
||||
${CMAKE_BINARY_DIR}/src/python
|
||||
${CMAKE_BINARY_DIR}/src/analysis
|
||||
${CMAKE_BINARY_DIR}/src/server
|
||||
@ -38,9 +37,6 @@ INCLUDE_DIRECTORIES(
|
||||
../../../core/symbology-ng
|
||||
../../../core/composer
|
||||
../../../core/layertree
|
||||
../../../gui
|
||||
../../../gui/editorwidgets
|
||||
../../../gui/editorwidgets/core
|
||||
../..
|
||||
..
|
||||
.
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
namespace QgsWfs
|
||||
{
|
||||
|
||||
/**
|
||||
* Create get capabilities document
|
||||
*/
|
||||
|
@ -25,6 +25,7 @@
|
||||
|
||||
namespace QgsWfs
|
||||
{
|
||||
|
||||
/**
|
||||
* Create get capabilities document
|
||||
*/
|
||||
|
@ -35,6 +35,7 @@
|
||||
//! WMS implementation
|
||||
namespace QgsWfs
|
||||
{
|
||||
|
||||
/** Return the highest version supported by this implementation
|
||||
*/
|
||||
QString implementationVersion();
|
||||
|
@ -88,13 +88,13 @@ namespace QgsWms
|
||||
{
|
||||
writeGetCapabilities( mServerIface, versionString, request, response, false );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetProjectSettings" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetProjectSettings" ) )
|
||||
{
|
||||
//getProjectSettings extends WMS 1.3.0 capabilities
|
||||
versionString = QStringLiteral( "1.3.0" );
|
||||
writeGetCapabilities( mServerIface, versionString, request, response, true );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetMap" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetMap" ) )
|
||||
{
|
||||
QString format = params.value( QStringLiteral( "FORMAT" ) );
|
||||
if QSTR_COMPARE( format, "application/dxf" )
|
||||
@ -106,35 +106,35 @@ namespace QgsWms
|
||||
writeGetMap( mServerIface, versionString, request, response );
|
||||
}
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetFeatureInfo" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetFeatureInfo" ) )
|
||||
{
|
||||
writeGetFeatureInfo( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetContext" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetContext" ) )
|
||||
{
|
||||
writeGetContext( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetSchemaExtension" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetSchemaExtension" ) )
|
||||
{
|
||||
writeGetSchemaExtension( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetStyle" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetStyle" ) )
|
||||
{
|
||||
writeGetStyle( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetStyles" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetStyles" ) )
|
||||
{
|
||||
writeGetStyles( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "DescribeLayer" ) )
|
||||
else if ( QSTR_COMPARE( req, "DescribeLayer" ) )
|
||||
{
|
||||
writeDescribeLayer( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetLegendGraphic" ) || QSTR_COMPARE( req, "GetLegendGraphics" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetLegendGraphic" ) || QSTR_COMPARE( req, "GetLegendGraphics" ) )
|
||||
{
|
||||
writeGetLegendGraphics( mServerIface, versionString, request, response );
|
||||
}
|
||||
else if( QSTR_COMPARE( req, "GetPrint" ) )
|
||||
else if ( QSTR_COMPARE( req, "GetPrint" ) )
|
||||
{
|
||||
writeGetPrint( mServerIface, versionString, request, response );
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user