mirror of
https://github.com/qgis/QGIS.git
synced 2025-03-28 00:04:04 -04:00
clean-up
This commit is contained in:
parent
6a64a556f0
commit
a868f0b7b6
@ -366,7 +366,6 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
|
||||
else
|
||||
{
|
||||
throw QgsServerException( QStringLiteral( "Project file error" ) );
|
||||
// theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ), QStringLiteral( "Error reading the project file" ) ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,481 +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
|
||||
, QMap<QString, QString> ¶meters
|
||||
, QgsWCSProjectParser* pp
|
||||
, QgsRequestHandler* rh
|
||||
, const QgsProject* project
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
, const QgsAccessControl* accessControl
|
||||
#endif
|
||||
)
|
||||
: QgsOWSServer(
|
||||
configFilePath
|
||||
, parameters
|
||||
, rh
|
||||
, project
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
, accessControl
|
||||
#endif
|
||||
)
|
||||
, mConfigParser(
|
||||
pp
|
||||
)
|
||||
{
|
||||
}
|
||||
|
||||
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 = QgsServerProjectUtils::wcsServiceUrl( *mProject );
|
||||
if ( hrefString.isEmpty() )
|
||||
{
|
||||
hrefString = QgsServerProjectUtils::wmsServiceUrl( *mProject );
|
||||
}
|
||||
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();
|
||||
}
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,300 +0,0 @@
|
||||
/***************************************************************************
|
||||
qgswmsserver.h
|
||||
-------------------
|
||||
begin : May 14, 2006
|
||||
copyright : (C) 2006 by Marco Hugentobler
|
||||
email : marco dot hugentobler at karto dot baug dot ethz 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 QGSWMSSERVER_H
|
||||
#define QGSWMSSERVER_H
|
||||
|
||||
#include "qgsowsserver.h"
|
||||
#include "qgswmsconfigparser.h"
|
||||
#include <QDomDocument>
|
||||
#include <QMap>
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
#include <map>
|
||||
|
||||
class QgsCapabilitiesCache;
|
||||
class QgsCoordinateReferenceSystem;
|
||||
class QgsComposition;
|
||||
class QgsConfigParser;
|
||||
class QgsFeature;
|
||||
class QgsFeatureRenderer;
|
||||
class QgsMapLayer;
|
||||
class QgsMapSettings;
|
||||
class QgsPoint;
|
||||
class QgsRasterLayer;
|
||||
class QgsRasterRenderer;
|
||||
class QgsRectangle;
|
||||
class QgsRenderContext;
|
||||
class QgsVectorLayer;
|
||||
class QgsSymbol;
|
||||
class QgsSymbol;
|
||||
class QgsAccessControl;
|
||||
|
||||
class QColor;
|
||||
class QFile;
|
||||
class QFont;
|
||||
class QImage;
|
||||
class QPaintDevice;
|
||||
class QPainter;
|
||||
class QStandardItem;
|
||||
|
||||
/** This class handles all the wms 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 QgsWMSServer
|
||||
independent from any server side technology*/
|
||||
|
||||
class QgsWmsServer: public QgsOWSServer
|
||||
{
|
||||
public:
|
||||
|
||||
/** Constructor. Does _NOT_ take ownership of
|
||||
QgsConfigParser and QgsCapabilitiesCache*/
|
||||
QgsWmsServer(
|
||||
const QString& configFilePath
|
||||
, QMap<QString, QString> ¶meters
|
||||
, QgsWmsConfigParser* cp
|
||||
, QgsRequestHandler* rh
|
||||
, QgsCapabilitiesCache* capCache
|
||||
, const QgsProject* project
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
, const QgsAccessControl* accessControl
|
||||
#endif
|
||||
);
|
||||
|
||||
void executeRequest() override;
|
||||
|
||||
/** Returns an XML file with the capabilities description (as described in the WMS specs)
|
||||
@param version WMS version (1.1.1 or 1.3.0)
|
||||
@param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
|
||||
QDomDocument getCapabilities( const QString &version = "1.3.0", bool fullProjectInformation = false );
|
||||
|
||||
QDomDocument getContext();
|
||||
|
||||
/** Returns the map legend as an image (or a null pointer in case of error). The caller takes ownership
|
||||
of the image object*/
|
||||
QImage* getLegendGraphics();
|
||||
|
||||
typedef QSet<QgsSymbol*> SymbolSet;
|
||||
typedef QHash<QgsVectorLayer*, SymbolSet> HitTest;
|
||||
|
||||
/** Returns the map as an image (or a null pointer in case of error). The caller takes ownership
|
||||
of the image object). If an instance to existing hit test structure is passed, instead of rendering
|
||||
it will fill the structure with symbols that would be used for rendering */
|
||||
QImage* getMap( HitTest* hitTest = nullptr );
|
||||
|
||||
/** Identical to getMap( HitTest* hitTest ) and updates the map settings actually used.
|
||||
@note added in QGIS 3.0 */
|
||||
QImage* getMap( QgsMapSettings &mapSettings, HitTest* hitTest = nullptr );
|
||||
//! GetMap request with vector format output. This output is usually symbolized (difference to WFS GetFeature)
|
||||
void getMapAsDxf();
|
||||
//! Returns an SLD file with the style of the requested layer. Exception is raised in case of troubles :-)
|
||||
QDomDocument getStyle();
|
||||
//! Returns an SLD file with the styles of the requested layers. Exception is raised in case of troubles :-)
|
||||
QDomDocument getStyles();
|
||||
//! Returns a describeLayer file with the onlineResource of the requested layers. Exception is raised in case of troubles :-)
|
||||
QDomDocument describeLayer();
|
||||
|
||||
/** Returns printed page as binary
|
||||
@param formatString out: format of the print output (e.g. pdf, svg, png, ...)
|
||||
@return printed page as binary or 0 in case of error*/
|
||||
QByteArray* getPrint( const QString& formatString );
|
||||
|
||||
/** Creates an xml document that describes the result of the getFeatureInfo request.
|
||||
* May throw an exception
|
||||
*/
|
||||
QDomDocument getFeatureInfo( const QString& version = "1.3.0" );
|
||||
|
||||
//! Sets configuration parser for administration settings. Does not take ownership
|
||||
void setAdminConfigParser( QgsWmsConfigParser* parser ) { mConfigParser = parser; }
|
||||
|
||||
//! Returns the schemaExtension for WMS 1.3.0 capabilities
|
||||
QDomDocument getSchemaExtension();
|
||||
|
||||
private:
|
||||
|
||||
/** Initializes WMS layers and configures rendering.
|
||||
* @param layersList out: list with WMS layer names
|
||||
* @param stylesList out: list with WMS style names
|
||||
* @param layerIdList out: list with QGIS layer ids
|
||||
* @return image configured. The calling function takes ownership of the image
|
||||
* may throw an exception
|
||||
*/
|
||||
QImage* initializeRendering( QStringList& layersList, QStringList& stylesList, QStringList& layerIdList, QgsMapSettings& mapSettings );
|
||||
|
||||
/** Creates a QImage from the HEIGHT and WIDTH parameters
|
||||
* @param width image width (or -1 if width should be taken from WIDTH wms parameter)
|
||||
* @param height image height (or -1 if height should be taken from HEIGHT wms parameter)
|
||||
* @param useBbox flag to indicate if the BBOX has to be used to adapt aspect ratio
|
||||
* @return a non null pointer
|
||||
* may throw an exception
|
||||
*/
|
||||
QImage* createImage( int width = -1, int height = -1, bool useBbox = true ) const;
|
||||
|
||||
/** Configures mapSettings to the parameters
|
||||
* HEIGHT, WIDTH, BBOX, CRS.
|
||||
* @param paintDevice the device that is used for painting (for dpi)
|
||||
* may throw an exception
|
||||
*/
|
||||
void configureMapSettings( const QPaintDevice* paintDevice, QgsMapSettings& mapSettings ) const;
|
||||
|
||||
/** Reads the layers and style lists from the parameters LAYERS and STYLES
|
||||
* may throw an exception
|
||||
*/
|
||||
void readLayersAndStyles( QStringList& layersList, QStringList& stylesList ) const;
|
||||
|
||||
/**
|
||||
* If the parameter SLD exists, mSLDParser is configured appropriately. The lists are
|
||||
* set to the layer and style names according to the SLD
|
||||
* may throw an exception
|
||||
*/
|
||||
void initializeSLDParser( QStringList& layersList, QStringList& stylesList );
|
||||
|
||||
/** Appends feature info xml for the layer to the layer element of the feature info dom document
|
||||
@param featureBBox the bounding box of the selected features in output CRS
|
||||
@return true in case of success*/
|
||||
bool featureInfoFromVectorLayer( QgsVectorLayer* layer,
|
||||
const QgsPoint* infoPoint,
|
||||
int nFeatures,
|
||||
QDomDocument& infoDocument,
|
||||
QDomElement& layerElement,
|
||||
const QgsMapSettings& mapSettings,
|
||||
QgsRenderContext& renderContext,
|
||||
const QString& version,
|
||||
const QString& infoFormat,
|
||||
QgsRectangle* featureBBox = nullptr ) const;
|
||||
//! Appends feature info xml for the layer to the layer element of the dom document
|
||||
bool featureInfoFromRasterLayer( QgsRasterLayer* layer,
|
||||
const QgsMapSettings& mapSettings,
|
||||
const QgsPoint* infoPoint,
|
||||
QDomDocument& infoDocument,
|
||||
QDomElement& layerElement,
|
||||
const QString& version,
|
||||
const QString& infoFormat ) const;
|
||||
|
||||
/** Creates a layer set and returns a stringlist with layer ids that can be passed to a renderer. Usually used in conjunction with readLayersAndStyles
|
||||
@param scaleDenominator Filter out layer if scale based visibility does not match (or use -1 if no scale restriction)*/
|
||||
QStringList layerSet( const QStringList& layersList, const QStringList& stylesList, const QgsCoordinateReferenceSystem& destCRS, double scaleDenominator = -1 ) const;
|
||||
|
||||
//! Record which symbols would be used if the map was in the current configuration of renderer. This is useful for content-based legend
|
||||
void runHitTest( const QgsMapSettings& mapSettings, QPainter* painter, HitTest& hitTest );
|
||||
//! Record which symbols within one layer would be rendered with the given renderer context
|
||||
void runHitTestLayer( QgsVectorLayer* vl, SymbolSet& usedSymbols, QgsRenderContext& context );
|
||||
|
||||
//! Read legend parameter from the request or from the first print composer in the project
|
||||
void legendParameters( double& boxSpace, double& layerSpace, double& layerTitleSpace,
|
||||
double& symbolSpace, double& iconLabelSpace, double& symbolWidth, double& symbolHeight, QFont& layerFont, QFont& itemFont, QColor& layerFontColor, QColor& itemFontColor );
|
||||
|
||||
/** Apply filter (subset) strings from the request to the layers. Example: '&FILTER=<layer1>:"AND property > 100",<layer2>:"AND bla = 'hallo!'" '
|
||||
* @param layerList list of layer IDs to filter
|
||||
* @param originalFilters hash of layer ID to original filter string
|
||||
* @note It is strongly recommended that this method be called alongside use of QgsOWSServerFilterRestorer
|
||||
* to ensure that the original filters are always correctly restored, regardless of whether exceptions
|
||||
* are thrown or functions are terminated early.
|
||||
*/
|
||||
void applyRequestedLayerFilters( const QStringList& layerList, QgsMapSettings& mapSettings, QHash<QgsMapLayer*, QString>& originalFilters ) const;
|
||||
|
||||
#ifdef HAVE_SERVER_PYTHON_PLUGINS
|
||||
|
||||
/** Apply filter strings from the access control to the layers.
|
||||
* @param layerList layers to filter
|
||||
* @param originalLayerFilters the original layers filter dictionary
|
||||
*/
|
||||
void applyAccessControlLayersFilters( const QStringList& layerList, QHash<QgsMapLayer*, QString>& originalLayerFilters ) const;
|
||||
#endif
|
||||
|
||||
/** Tests if a filter sql string is allowed (safe)
|
||||
@return true in case of success, false if string seems unsafe*/
|
||||
bool testFilterStringSafety( const QString& filter ) const;
|
||||
//! Helper function for filter safety test. Groups stringlist to merge entries starting/ending with quotes
|
||||
static void groupStringList( QStringList& list, const QString& groupString );
|
||||
|
||||
/** Select vector features with ids specified in parameter SELECTED, e.g. ...&SELECTED=layer1:1,2,9;layer2:3,5,10&...
|
||||
@return list with layer ids where selections have been created*/
|
||||
QStringList applyFeatureSelections( const QStringList& layerList ) const;
|
||||
//! Clear all feature selections in the given layers
|
||||
void clearFeatureSelections( const QStringList& layerIds ) const;
|
||||
|
||||
//! Applies opacity on layer/group level
|
||||
void applyOpacities( const QStringList& layerList, QList< QPair< QgsVectorLayer*, QgsFeatureRenderer*> >& vectorRenderers,
|
||||
QList< QPair< QgsRasterLayer*, QgsRasterRenderer* > >& rasterRenderers,
|
||||
QList< QPair< QgsVectorLayer*, double > >& labelTransparencies,
|
||||
QList< QPair< QgsVectorLayer*, double > >& labelBufferTransparencies
|
||||
);
|
||||
|
||||
//! Restore original opacities
|
||||
void restoreOpacities( QList< QPair <QgsVectorLayer*, QgsFeatureRenderer*> >& vectorRenderers,
|
||||
QList< QPair < QgsRasterLayer*, QgsRasterRenderer* > >& rasterRenderers,
|
||||
QList< QPair< QgsVectorLayer*, double > >& labelTransparencies,
|
||||
QList< QPair< QgsVectorLayer*, double > >& labelBufferTransparencies );
|
||||
|
||||
void appendFormats( QDomDocument &doc, QDomElement &elem, const QStringList &formats );
|
||||
|
||||
/** Checks WIDTH/HEIGHT values against MaxWidth and MaxHeight
|
||||
@return true if width/height values are okay*/
|
||||
bool checkMaximumWidthHeight() const;
|
||||
|
||||
//! Get service address from REQUEST_URI if not specified in the configuration
|
||||
QString serviceUrl() const;
|
||||
|
||||
//! Add '<?xml version="1.0" ?>'. Some clients need an xml declaration (though it is not strictly required)
|
||||
void addXmlDeclaration( QDomDocument& doc ) const;
|
||||
|
||||
//! Converts a feature info xml document to SIA2045 norm
|
||||
void convertFeatureInfoToSIA2045( QDomDocument& doc );
|
||||
|
||||
//! Cleanup temporary objects (e.g. SLD parser objects or temporary files) after request
|
||||
void cleanupAfterRequest();
|
||||
|
||||
//! Map containing the WMS parameters
|
||||
QgsCapabilitiesCache* mCapabilitiesCache;
|
||||
|
||||
QgsWmsConfigParser* mConfigParser;
|
||||
|
||||
bool mOwnsConfigParser; //delete config parser after request (e.g. sent SLD)
|
||||
|
||||
// specify if layer or rule item labels should be drawn in the legend graphic with GetLegendGraphics
|
||||
bool mDrawLegendLayerLabel;
|
||||
bool mDrawLegendItemLabel;
|
||||
|
||||
QDomElement createFeatureGML(
|
||||
QgsFeature* feat,
|
||||
QgsVectorLayer* layer,
|
||||
QDomDocument& doc,
|
||||
QgsCoordinateReferenceSystem& crs,
|
||||
const QgsMapSettings& mapSettings,
|
||||
const QString& typeName,
|
||||
bool withGeom,
|
||||
int version,
|
||||
QStringList* attributes = nullptr ) const;
|
||||
|
||||
//! Replaces attribute value with ValueRelation or ValueRelation if defined. Otherwise returns the original value
|
||||
static QString replaceValueMapAndRelation( QgsVectorLayer* vl, int idx, const QString& attributeVal );
|
||||
|
||||
//! Return the image quality to use for getMap request
|
||||
int getImageQuality() const;
|
||||
|
||||
//! Return precision to use for GetFeatureInfo request
|
||||
int getWMSPrecision( int defaultValue ) const;
|
||||
|
||||
//! Gets layer search rectangle (depending on request parameter, layer type, map and layer crs)
|
||||
QgsRectangle featureInfoSearchRect( QgsVectorLayer* ml, const QgsMapSettings& ms, const QgsRenderContext& rct, const QgsPoint& infoPoint ) const;
|
||||
|
||||
//! Reads and extracts the different options in the FORMAT_OPTIONS parameter
|
||||
void readFormatOptions( QMap<QString, QString>& formatOptions ) const;
|
||||
void readDxfLayerSettings( QList< QPair<QgsVectorLayer *, int > >& layers, const QMap<QString, QString>& formatOptionsMap ) const;
|
||||
};
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user