Skip to content
Permalink
Browse files

[server] WIP clean project parsing by using QgsProject

  • Loading branch information
pblottiere committed Jan 30, 2017
1 parent 8ba609e commit 5c8360dba24edcc2c7e73951d75d98bfd7bc8c5d
Showing with 7,613 additions and 387 deletions.
  1. +0 −4 python/server/qgsserverprojectparser.sip
  2. +61 −0 python/server/qgsserverprojectutils.sip
  3. +1 −1 python/server/qgsservice.sip
  4. +0 −2 python/server/qgswcsprojectparser.sip
  5. +0 −2 python/server/qgswfsprojectparser.sip
  6. +2 −6 python/server/qgswmsconfigparser.sip
  7. +2 −6 python/server/qgswmsprojectparser.sip
  8. +1 −0 python/server/server.sip
  9. +15 −9 src/core/qgsmaplayer.cpp
  10. +8 −0 src/core/qgsmaplayer.h
  11. +1 −1 src/core/qgsproject.cpp
  12. +1 −0 src/server/CMakeLists.txt
  13. +20 −1 src/server/qgsserver.cpp
  14. +4 −0 src/server/qgsserver.h
  15. +0 −63 src/server/qgsserverprojectparser.cpp
  16. +0 −4 src/server/qgsserverprojectparser.h
  17. +43 −0 src/server/qgsserverprojectutils.cpp
  18. +64 −0 src/server/qgsserverprojectutils.h
  19. +3 −2 src/server/qgsservice.h
  20. +4 −30 src/server/qgssldconfigparser.cpp
  21. +2 −6 src/server/qgssldconfigparser.h
  22. +0 −26 src/server/qgswcsprojectparser.cpp
  23. +0 −2 src/server/qgswcsprojectparser.h
  24. +481 −0 src/server/qgswcsserver.cpp
  25. +0 −10 src/server/qgswfsprojectparser.cpp
  26. +0 −2 src/server/qgswfsprojectparser.h
  27. +2,158 −0 src/server/qgswfsserver.cpp
  28. +2 −6 src/server/qgswmsconfigparser.h
  29. +9 −54 src/server/qgswmsprojectparser.cpp
  30. +4 −7 src/server/qgswmsprojectparser.h
  31. +3,554 −0 src/server/qgswmsserver.cpp
  32. +300 −0 src/server/qgswmsserver.h
  33. +1 −1 src/server/services/DummyService/dummy.cpp
  34. +2 −2 src/server/services/wcs/qgswcs.cpp
  35. +4 −4 src/server/services/wcs/qgswcsgetcapabilities.cpp
  36. +7 −4 src/server/services/wcs/qgswcsgetcapabilities.h
  37. +4 −7 src/server/services/wcs/qgswcsutils.cpp
  38. +1 −1 src/server/services/wcs/qgswcsutils.h
  39. +3 −5 src/server/services/wfs/qgswfs.cpp
  40. +4 −4 src/server/services/wfs/qgswfsgetcapabilities.cpp
  41. +7 −4 src/server/services/wfs/qgswfsgetcapabilities.h
  42. +18 −17 src/server/services/wfs/qgswfsgetfeature.cpp
  43. +3 −2 src/server/services/wfs/qgswfsgetfeature.h
  44. +4 −8 src/server/services/wfs/qgswfsutils.cpp
  45. +1 −1 src/server/services/wfs/qgswfsutils.h
  46. +9 −11 src/server/services/wms/qgswms.cpp
  47. +24 −7 src/server/services/wms/qgswmsdescribelayer.cpp
  48. +5 −4 src/server/services/wms/qgswmsdescribelayer.h
  49. +13 −10 src/server/services/wms/qgswmsgetcapabilities.cpp
  50. +6 −5 src/server/services/wms/qgswmsgetcapabilities.h
  51. +7 −6 src/server/services/wms/qgswmsgetcontext.cpp
  52. +5 −4 src/server/services/wms/qgswmsgetcontext.h
  53. +4 −3 src/server/services/wms/qgswmsgetfeatureinfo.cpp
  54. +3 −2 src/server/services/wms/qgswmsgetfeatureinfo.h
  55. +4 −3 src/server/services/wms/qgswmsgetlegendgraphics.cpp
  56. +3 −2 src/server/services/wms/qgswmsgetlegendgraphics.h
  57. +3 −3 src/server/services/wms/qgswmsgetmap.cpp
  58. +2 −1 src/server/services/wms/qgswmsgetmap.h
  59. +4 −3 src/server/services/wms/qgswmsgetprint.cpp
  60. +3 −2 src/server/services/wms/qgswmsgetprint.h
  61. +1 −7 src/server/services/wms/qgswmsgetschemaextension.cpp
  62. +10 −4 src/server/services/wms/qgswmsrenderer.cpp
  63. +2 −0 src/server/services/wms/qgswmsrenderer.h
  64. +4 −3 src/server/services/wms/qgswmsutils.cpp
  65. +1 −1 src/server/services/wms/qgswmsutils.h
  66. +1 −0 tests/src/python/CMakeLists.txt
  67. +151 −2 tests/src/python/test_qgsserver.py
  68. +47 −0 tests/src/python/test_qgsserver_projectutils.py
  69. +124 −0 tests/testdata/qgis_server/test_project_with_size.qgs
  70. +122 −0 tests/testdata/qgis_server/test_project_with_urls.qgs
  71. +124 −0 tests/testdata/qgis_server/test_project_without_urls.qgs
  72. +132 −0 tests/testdata/qgis_server_project/project.qgs
@@ -86,10 +86,6 @@ class QgsServerProjectParser
@return name or a null string in case of error*/
QString layerName( const QDomElement& layerElem ) const;

QString serviceUrl() const;
QString wfsServiceUrl() const;
QString wcsServiceUrl() const;

QStringList wfsLayers() const;
QStringList wcsLayers() const;

@@ -0,0 +1,61 @@
/***************************************************************************
qgsserverprojectutils.sip
-------------------------
begin : December 19, 2016
copyright : (C) 2016 by Paul Blottiere
email : paul dot blottiere at oslandia 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. *
* *
***************************************************************************/


/** \ingroup server
* The QgsServerProjectUtils class provides a way to retrieve specific entries
* a QgsProject.
* @note added in QGIS 3.0
*/
class QgsServerProjectUtils
{
%TypeHeaderCode
#include "qgsserverprojectutils.h"
%End

public:

/** Returns the maximum width for WMS images defined in a QGIS project.
* @param project the QGIS project
* @return width if defined in project, -1 otherwise.
*/
static int wmsMaxWidth( const QgsProject& project );

/** Returns the maximum height for WMS images defined in a QGIS project.
* @param project the QGIS project
* @return height if defined in project, -1 otherwise.
*/
static int wmsMaxHeight( const QgsProject& project );

/** Returns the WMS service url defined in a QGIS project.
* @param project the QGIS project
* @return url if defined in project, an empty string otherwise.
*/
static QString wmsServiceUrl( const QgsProject& project );

/** Returns the WFS service url defined in a QGIS project.
* @param project the QGIS project
* @return url if defined in project, an empty string otherwise.
*/
static QString wfsServiceUrl( const QgsProject& project );

/** Returns the WCS service url defined in a QGIS project.
* @param project the QGIS project
* @return url if defined in project, an empty string otherwise.
*/
static QString wcsServiceUrl( const QgsProject& project );
};
@@ -64,6 +64,6 @@ class QgsService
* Execute the requests and set result in QgsServerRequest
*/
virtual void executeRequest( const QgsServerRequest& request, QgsServerResponse& response,
QgsProject* project = nullptr ) = 0;
const QgsProject* project ) = 0;
};

@@ -27,8 +27,6 @@ class QgsWCSProjectParser
~QgsWCSProjectParser();

void serviceCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
QString wcsServiceUrl() const;
QString serviceUrl() const;
void wcsContentMetadata( QDomElement& parentElement, QDomDocument& doc ) const;
QStringList wcsLayers() const;
void describeCoverage( const QString& aCoveName, QDomElement& parentElement, QDomDocument& doc ) const;
@@ -28,8 +28,6 @@ class QgsWfsProjectParser
~QgsWfsProjectParser();

void serviceCapabilities( QDomElement& parentElement, QDomDocument& doc ) const;
QString serviceUrl() const;
QString wfsServiceUrl() const;
void featureTypeList( QDomElement& parentElement, QDomDocument& doc ) const;

void describeFeatureType( const QString& aTypeName, QDomElement& parentElement, QDomDocument& doc ) const;
@@ -27,7 +27,7 @@ class QgsWmsConfigParser

/** Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.
@param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings = false ) const = 0;
virtual void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, const QString& serviceUrl, bool fullProjectSettings = false ) const = 0;

/** Returns one or possibly several maplayers for a given layer name and style. If no layers/style are found, an empty list is returned*/
virtual QList<QgsMapLayer*> mapLayerFromStyle( const QString& lName, const QString& styleName, bool useCache = true ) const = 0;
@@ -42,7 +42,7 @@ class QgsWmsConfigParser
virtual QDomDocument getStyles( QStringList& layerList ) const = 0;

/** Returns the xml fragment of layers styles description*/
virtual QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const = 0;
virtual QDomDocument describeLayer( QStringList& layerList, const QString& wfsHrefString, const QString& wcsHrefString ) const = 0;

/** Returns if output are MM or PIXEL*/
virtual QgsUnitTypes::RenderUnit outputUnits() const = 0;
@@ -74,8 +74,6 @@ class QgsWmsConfigParser
/** Load PAL engine settings into global project instance*/
virtual void loadLabelSettings() const = 0;

virtual QString serviceUrl() const = 0;

virtual QStringList wfsLayerNames() const = 0;

virtual void owsGeneralAndResourceList( QDomElement& parentElement, QDomDocument& doc, const QString& strHref ) const = 0;
@@ -91,8 +89,6 @@ class QgsWmsConfigParser
virtual QFont legendLayerFont() const = 0;
virtual QFont legendItemFont() const = 0;

virtual double maxWidth() const = 0;
virtual double maxHeight() const = 0;
virtual double imageQuality() const = 0;

// WMS GetFeatureInfo precision (decimal places)
@@ -28,12 +28,10 @@ class QgsWmsProjectParser : public QgsWmsConfigParser

/** Adds layer and style specific capabilities elements to the parent node. This includes the individual layers and styles, their description, native CRS, bounding boxes, etc.
@param fullProjectInformation If true: add extended project information (does not validate against WMS schema)*/
void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, bool fullProjectSettings = false ) const /*override*/ ;
void layersAndStylesCapabilities( QDomElement& parentElement, QDomDocument& doc, const QString& version, const QString& serviceUrl, bool fullProjectSettings = false ) const /*override*/ ;

QList<QgsMapLayer*> mapLayerFromStyle( const QString& lName, const QString& styleName, bool useCache = true ) const /*override*/ ;

QString serviceUrl() const /*override*/ ;

QStringList wfsLayerNames() const /*override*/ ;

void owsGeneralAndResourceList( QDomElement& parentElement, QDomDocument& doc, const QString& strHref ) const /*override*/ ;
@@ -49,8 +47,6 @@ class QgsWmsProjectParser : public QgsWmsConfigParser
QFont legendLayerFont() const /*override*/ ;
QFont legendItemFont() const /*override*/ ;

double maxWidth() const /*override*/ ;
double maxHeight() const /*override*/ ;
double imageQuality() const /*override*/ ;
int wmsPrecision() const /*override*/ ;

@@ -75,7 +71,7 @@ class QgsWmsProjectParser : public QgsWmsConfigParser
QDomDocument getStyles( QStringList& layerList ) const /*override*/ ;

/** Returns the xml fragment of layers styles description*/
QDomDocument describeLayer( QStringList& layerList, const QString& hrefString ) const /*override*/ ;
QDomDocument describeLayer( QStringList& layerList, const QString& wfsHrefString, const QString& wcsHrefString ) const /*override*/ ;

/** Returns if output are MM or PIXEL*/
QgsUnitTypes::RenderUnit outputUnits() const /*override*/ ;
@@ -27,6 +27,7 @@
%Include qgswfsprojectparser.sip
%Include qgsconfigcache.sip
%Include qgsserversettings.sip
%Include qgsserverprojectutils.sip
%Include qgsserver.sip

%Include qgsserverrequest.sip
@@ -155,6 +155,12 @@ QPainter::CompositionMode QgsMapLayer::blendMode() const


bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
{
return readLayerXml( layerElement, QgsProject::instance() );
}


bool QgsMapLayer::readLayerXml( const QDomElement& layerElement, const QgsProject *project )
{
bool layerError;

@@ -185,19 +191,19 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
if ( provider == QLatin1String( "spatialite" ) )
{
QgsDataSourceUri uri( mDataSource );
uri.setDatabase( QgsProject::instance()->readPath( uri.database() ) );
uri.setDatabase( project->readPath( uri.database() ) );
mDataSource = uri.uri();
}
else if ( provider == QLatin1String( "ogr" ) )
{
QStringList theURIParts = mDataSource.split( '|' );
theURIParts[0] = QgsProject::instance()->readPath( theURIParts[0] );
theURIParts[0] = project->readPath( theURIParts[0] );
mDataSource = theURIParts.join( QStringLiteral( "|" ) );
}
else if ( provider == QLatin1String( "gpx" ) )
{
QStringList theURIParts = mDataSource.split( '?' );
theURIParts[0] = QgsProject::instance()->readPath( theURIParts[0] );
theURIParts[0] = project->readPath( theURIParts[0] );
mDataSource = theURIParts.join( QStringLiteral( "?" ) );
}
else if ( provider == QLatin1String( "delimitedtext" ) )
@@ -211,7 +217,7 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
urlSource.setPath( file.path() );
}

QUrl urlDest = QUrl::fromLocalFile( QgsProject::instance()->readPath( urlSource.toLocalFile() ) );
QUrl urlDest = QUrl::fromLocalFile( project->readPath( urlSource.toLocalFile() ) );
urlDest.setQueryItems( urlSource.queryItems() );
mDataSource = QString::fromAscii( urlDest.toEncoded() );
}
@@ -309,7 +315,7 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
QString filename = r.cap( 1 );
if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) )
filename = filename.mid( 1, filename.length() - 2 );
mDataSource = "NETCDF:\"" + QgsProject::instance()->readPath( filename ) + "\":" + r.cap( 2 );
mDataSource = "NETCDF:\"" + project->readPath( filename ) + "\":" + r.cap( 2 );
handled = true;
}
}
@@ -323,7 +329,7 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
QString filename = r.cap( 2 );
if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) )
filename = filename.mid( 1, filename.length() - 2 );
mDataSource = "HDF4_SDS:" + r.cap( 1 ) + ":\"" + QgsProject::instance()->readPath( filename ) + "\":" + r.cap( 3 );
mDataSource = "HDF4_SDS:" + r.cap( 1 ) + ":\"" + project->readPath( filename ) + "\":" + r.cap( 3 );
handled = true;
}
}
@@ -337,7 +343,7 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
QString filename = r.cap( 1 );
if ( filename.startsWith( '"' ) && filename.endsWith( '"' ) )
filename = filename.mid( 1, filename.length() - 2 );
mDataSource = "HDF5:\"" + QgsProject::instance()->readPath( filename ) + "\":" + r.cap( 2 );
mDataSource = "HDF5:\"" + project->readPath( filename ) + "\":" + r.cap( 2 );
handled = true;
}
}
@@ -348,14 +354,14 @@ bool QgsMapLayer::readLayerXml( const QDomElement& layerElement )
QRegExp r( "([^:]+):([^:]+):(.+)" );
if ( r.exactMatch( mDataSource ) )
{
mDataSource = r.cap( 1 ) + ':' + r.cap( 2 ) + ':' + QgsProject::instance()->readPath( r.cap( 3 ) );
mDataSource = r.cap( 1 ) + ':' + r.cap( 2 ) + ':' + project->readPath( r.cap( 3 ) );
handled = true;
}
}
}

if ( !handled )
mDataSource = QgsProject::instance()->readPath( mDataSource );
mDataSource = project->readPath( mDataSource );
}

// Set the CRS from project file, asking the user if necessary.
@@ -38,6 +38,7 @@
class QgsMapLayerLegend;
class QgsMapLayerRenderer;
class QgsMapLayerStyleManager;
class QgsProject;

class QDomDocument;
class QKeyEvent;
@@ -364,6 +365,13 @@ class CORE_EXPORT QgsMapLayer : public QObject
*/
bool readLayerXml( const QDomElement& layerElement );

/** Sets state from Dom document for a specific project.
* @param layerElement The Dom element corresponding to ``maplayer'' tag
* @param project
* @returns true if successful
*/
bool readLayerXml( const QDomElement& layerElement, const QgsProject *project );


/** Stores state in Dom node
* @param layerElement is a Dom element corresponding to ``maplayer'' tag
@@ -733,7 +733,7 @@ bool QgsProject::addLayer( const QDomElement &layerElem, QList<QDomNode> &broken
Q_CHECK_PTR( mapLayer );

// have the layer restore state that is stored in Dom node
if ( mapLayer->readLayerXml( layerElem ) && mapLayer->isValid() )
if ( mapLayer->readLayerXml( layerElem, this ) && mapLayer->isValid() )
{
// postpone readMapLayer signal for vector layers with joins
QgsVectorLayer *vLayer = qobject_cast<QgsVectorLayer*>( mapLayer );
@@ -39,6 +39,7 @@ SET(qgis_mapserv_SRCS
qgswmsconfigparser.cpp
qgswmsprojectparser.cpp
qgsserverprojectparser.cpp
qgsserverprojectutils.cpp
qgssldconfigparser.cpp
qgsconfigparserutils.cpp
qgsserver.cpp
@@ -39,6 +39,7 @@
#include "qgsbufferserverresponse.h"
#include "qgsfilterresponsedecorator.h"
#include "qgsservice.h"
#include "qgsserverprojectutils.h"

#include <QDomDocument>
#include <QNetworkDiskCache>
@@ -351,6 +352,24 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
//Config file path
QString configFilePath = configPath( *sConfigFilePath, parameterMap );

// load the project if needed and not empty
auto projectIt = mProjectStore.find( configFilePath );
if ( projectIt == mProjectStore.constEnd() )
{
// load the project
QgsProject* project = new QgsProject();
project->setFileName( configFilePath );
if ( project->read() )
{
projectIt = mProjectStore.insert( configFilePath, project );
}
else
{
throw QgsServerException( QStringLiteral( "Project file error" ) );
// theRequestHandler.setServiceException( QgsMapServiceException( QStringLiteral( "Project file error" ), QStringLiteral( "Error reading the project file" ) ) );
}
}

sServerInterface->setConfigFilePath( configFilePath );

//Service parameter
@@ -379,7 +398,7 @@ void QgsServer::handleRequest( QgsServerRequest& request, QgsServerResponse& res
QgsService* service = sServiceRegistry.getService( serviceString, versionString );
if ( service )
{
service->executeRequest( request, theResponse );
service->executeRequest( request, theResponse, projectIt.value() );
}
else
{
@@ -43,6 +43,7 @@

class QgsServerRequest;
class QgsServerResponse;
class QgsProject;

/** \ingroup server
* The QgsServer class provides OGC web services.
@@ -130,6 +131,9 @@ class SERVER_EXPORT QgsServer
static QgsServiceRegistry sServiceRegistry;

static QgsServerSettings sSettings;

// map of QgsProject
QMap<QString, const QgsProject*> mProjectStore;
};
#endif // QGSSERVER_H

0 comments on commit 5c8360d

Please sign in to comment.
You can’t perform that action at this time.