[qgis] 03/08: Imported Upstream version 2.14.10+dfsg
Bas Couwenberg
sebastic at debian.org
Fri Dec 16 15:08:02 UTC 2016
This is an automated email from the git hooks/post-receive script.
sebastic pushed a commit to branch experimental
in repository qgis.
commit 859d1f99ed6e44bd657dfa569b9400bce4e0bb6d
Author: Bas Couwenberg <sebastic at xs4all.nl>
Date: Fri Dec 16 13:57:41 2016 +0100
Imported Upstream version 2.14.10+dfsg
---
CMakeLists.txt | 2 +-
ChangeLog | 157 +++++++++++++++++++++
debian/changelog | 10 +-
.../plugins/processing/algs/taudem/TauDEMUtils.py | 13 ++
.../plugins/processing/modeler/ModelerAlgorithm.py | 5 +-
python/plugins/processing/tools/dataobjects.py | 3 +-
src/app/qgscustomization.cpp | 2 +-
.../symbology-ng/qgspointdisplacementrenderer.cpp | 7 +
.../symbology-ng/qgspointdisplacementrenderer.h | 4 +
src/gui/qgsfiledownloader.cpp | 14 +-
src/gui/qgsfiledownloader.h | 2 -
.../checks/qgsgeometrygapcheck.cpp | 4 +-
.../geometry_checker/utils/qgsfeaturepool.cpp | 9 +-
.../virtual/qgsvirtuallayersqlitemodule.cpp | 10 +-
src/server/qgsconfigparserutils.cpp | 12 +-
src/server/qgsserverprojectparser.cpp | 2 +-
src/server/qgswmsserver.cpp | 130 +++++++++++++++--
src/server/qgswmsserver.h | 6 +-
tests/src/gui/testqgsfiledownloader.cpp | 12 +-
tests/src/python/test_qgsfiledownloader.py | 14 +-
tests/src/python/test_qgsserver.py | 130 +++++++++++++++++
tests/src/python/test_qgsserver_accesscontrol.py | 32 ++---
.../WMS_GetLegendGraphic_BBox.png | Bin 0 -> 839 bytes
.../WMS_GetLegendGraphic_BBox2.png | Bin 0 -> 601 bytes
.../WMS_GetLegendGraphic_Basic.png | Bin 0 -> 601 bytes
.../WMS_GetLegendGraphic_BoxSpace.png | Bin 0 -> 3938 bytes
.../WMS_GetLegendGraphic_IconLabelSpace.png | Bin 0 -> 783 bytes
.../WMS_GetLegendGraphic_SymbolSize.png | Bin 0 -> 1248 bytes
.../WMS_GetLegendGraphic_SymbolSpace.png | Bin 0 -> 968 bytes
tests/testdata/qgis_server/getcapabilities.txt | 4 +-
.../qgis_server/getcapabilities_inspire.txt | 4 +-
tests/testdata/qgis_server/getprojectsettings.txt | 4 +-
tests/testdata/qgis_server/wfs_getcapabilities.txt | 2 +-
33 files changed, 520 insertions(+), 74 deletions(-)
diff --git a/CMakeLists.txt b/CMakeLists.txt
index d6db4b1..4398ee7 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,6 +1,6 @@
SET(CPACK_PACKAGE_VERSION_MAJOR "2")
SET(CPACK_PACKAGE_VERSION_MINOR "14")
-SET(CPACK_PACKAGE_VERSION_PATCH "9")
+SET(CPACK_PACKAGE_VERSION_PATCH "10")
SET(COMPLETE_VERSION ${CPACK_PACKAGE_VERSION_MAJOR}.${CPACK_PACKAGE_VERSION_MINOR}.${CPACK_PACKAGE_VERSION_PATCH})
SET(RELEASE_NAME "Essen")
IF (POLICY CMP0048) # in CMake 3.0.0+
diff --git a/ChangeLog b/ChangeLog
index e5b78ef..3a7cd94 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,160 @@
+Alexander Bruy <alexander.bruy at gmail.com> 2016-12-15
+
+ [processing] quote file paths in TauDEM provider
+
+Alessandro Pasotti <apasotti at boundlessgeo.com> 2016-12-14
+
+ [BACKPORT][BUGFIX] Fixed a crash on bad network protocol
+
+ ( from f48f90ead )
+
+rldhont <rldhont at gmail.com> 2016-12-13
+
+ Fix WMS 1.3. compliance: distort image if width/height ratio of bbox is different to WIDTH/HEIGHT of requested image
+
+ Not decrease but increase image
+
+Merge: 02d70fa a1a4ad9
+rldhont <rldhont at gmail.com> 2016-12-13
+
+ Merge pull request #3862 from rldhont/release-2_14-wms-130-compliance
+
+ Backport 214 wms 130 compliance
+
+Blottiere Paul <blottiere.paul at gmail.com> 2016-12-09
+
+ fix getLegendGraphics when BBox parameter is used
+
+rldhont <rldhont at gmail.com> 2016-12-12
+
+ Adapt WFS capabilties in server test for WMS 1.3.0 compliance
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-12-01
+
+ Fix access control tests such that bbox width/height ration matches image width/height
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-12-01
+
+ Adapt expected capabilities / project settings response in server test for WMS 1.3.0 compliance
+
+rldhont <rldhont at gmail.com> 2016-12-12
+
+ Fix typo
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-12-09
+
+ Backward support for parameters 'MTVER' and 'capabilities' from WMS 1.0.0 is required for WMS 1.1.1
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-12-01
+
+ Indentation
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-12-01
+
+ WMS server: parse bounding box only if the BBOX parameter is really there
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3 compliance: Each OnlineResource URL intended for HTTP Get requests in the capabilities document is a URL prefix
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ Exception format is XML, not capabilities format
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3. compliance: distort image if width/height ratio of bbox is different to WIDTH/HEIGHT of requested image
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: If a layer bounding box is there, it is not allowed to be empty (also if a layer has only one point)
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: throw exception if bbox is empty
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ Fix typo
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: exception format must be advertized as 'XML', not 'text/xml'
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: CRS:84 needs to be supported
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: support BGCOLOR parameter
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: throw exception if feature info point is not within the WIDTH/HEIGHT parameters
+
+Marco Hugentobler <marco.hugentobler at sourcepole.ch> 2016-11-29
+
+ WMS 1.3.0 compliance: use the reserved word 'None' if no fees
+
+nirvn <nirvn.asia at gmail.com> 2016-12-08
+
+ Revert "[style dock] emit widgetChanged() when raster palette labels updated"
+
+ This reverts commit f92928d4da7ece907b94713e8706e550e6ab4c5e.
+
+nirvn <nirvn.asia at gmail.com> 2016-12-08
+
+ [style dock] emit widgetChanged() when raster palette labels updated
+
+Sandro Mani <manisandro at gmail.com> 2016-12-06
+
+ [Geometry Checker] Don't add geometry-less features to feature-pool
+
+Hugo Mercier <hugo.mercier at oslandia.com> 2016-12-05
+
+ [virtual layer] Fix xFilter for null value comparisons
+
+Merge: b3742fe 8dc7799
+volaya <volayaf at gmail.com> 2016-12-02
+
+ Merge pull request #3826 from alexbruy/processing-models
+
+ fix loading of models containing user-defined scripts
+
+Alexander Bruy <alexander.bruy at gmail.com> 2016-12-02
+
+ fix loading of models containing user-defined scripts
+
+Sandro Mani <manisandro at gmail.com> 2016-12-01
+
+ [Geometry checker] Fix possible use of deleted geometry
+
+rldhont <rldhont at gmail.com> 2016-11-30
+
+ Update QgsPointDisplacementRenderer::legendKeysForFeature note
+
+rldhont <rldhont at gmail.com> 2016-11-30
+
+ [BUGFIX] Filter Legend By Map Content doesn't maintain point displacement legend
+
+ Fixed #11572
+ Manually cherry-picked 4d71cf968c4608359514637ceabcf4f3dcfb09ce
+
+borys <info at borysjurgiel.pl> 2016-11-29
+
+ [bugfix] Fix broken docks customization. Fixes #8055
+
+volaya <volayaf at gmail.com> 2016-11-27
+
+ [processing] fixed file extension when exporting layer
+
+ fixes #15898
+
+Juergen E. Fischer <jef at norbit.de> 2016-11-25
+
+ Release of 2.14.9
+
Matthias Kuhn <matthias at opengis.ch> 2016-10-17
Don't rely on RTTI to convert symbol layer to sip objects
diff --git a/debian/changelog b/debian/changelog
index e11ca65..d17c0b5 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,8 +1,14 @@
-qgis (2.14.9) UNRELEASED; urgency=medium
+qgis (2.14.10) UNRELEASED; urgency=medium
+
+ * Release of 2.14.10
+
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 16 Dec 2016 13:00:16 +0100
+
+qgis (2.14.9) unstable; urgency=medium
* Release of 2.14.9
- -- Jürgen E. Fischer <jef at norbit.de> Fri, 25 Nov 2016 14:11:24 +0100
+ -- Jürgen E. Fischer <jef at norbit.de> Fri, 16 Dec 2016 13:00:16 +0100
qgis (2.14.8) unstable; urgency=medium
diff --git a/python/plugins/processing/algs/taudem/TauDEMUtils.py b/python/plugins/processing/algs/taudem/TauDEMUtils.py
index 48150ce..6c57657 100644
--- a/python/plugins/processing/algs/taudem/TauDEMUtils.py
+++ b/python/plugins/processing/algs/taudem/TauDEMUtils.py
@@ -102,6 +102,7 @@ class TauDEMUtils:
def executeTauDEM(command, progress):
loglines = []
loglines.append(TauDEMUtils.tr('TauDEM execution console output'))
+ command = TauDEMUtils.escapeAndJoin(command)
fused_command = ''.join(['"%s" ' % c for c in command])
progress.setInfo(TauDEMUtils.tr('TauDEM command:'))
progress.setCommand(fused_command.replace('" "', ' ').strip('"'))
@@ -119,6 +120,18 @@ class TauDEMUtils:
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
@staticmethod
+ def escapeAndJoin(strList):
+ joined = ''
+ for s in strList:
+ if s[0] != '-' and ' ' in s:
+ escaped = '"' + s.replace('\\', '\\\\').replace('"', '\\"') \
+ + '"'
+ else:
+ escaped = s
+ joined += escaped + ' '
+ return joined.strip()
+
+ @staticmethod
def tr(string, context=''):
if context == '':
context = 'TauDEMUtils'
diff --git a/python/plugins/processing/modeler/ModelerAlgorithm.py b/python/plugins/processing/modeler/ModelerAlgorithm.py
index 0872485..91b0f7d 100644
--- a/python/plugins/processing/modeler/ModelerAlgorithm.py
+++ b/python/plugins/processing/modeler/ModelerAlgorithm.py
@@ -566,7 +566,10 @@ class ModelerAlgorithm(GeoAlgorithm):
def fromdict(d):
try:
fullClassName = d["class"]
- tokens = fullClassName.split(".")
+ if isinstance(fullClassName, basestring):
+ tokens = fullClassName.split(".")
+ else:
+ tokens = fullClassName.__class__.__name__.split(".")
className = tokens[-1]
moduleName = ".".join(tokens[:-1])
values = d["values"]
diff --git a/python/plugins/processing/tools/dataobjects.py b/python/plugins/processing/tools/dataobjects.py
index a23ed78..7e014ce 100644
--- a/python/plugins/processing/tools/dataobjects.py
+++ b/python/plugins/processing/tools/dataobjects.py
@@ -308,7 +308,8 @@ def exportVectorLayer(layer, supported=None):
unicode(layer.source()).decode('ascii')
except UnicodeEncodeError:
isASCII = False
- if not os.path.splitext(layer.source())[1].lower() in supported or not isASCII:
+ ext = os.path.splitext(layer.source())[-1].lower()[1:]
+ if ext not in supported or not isASCII:
writer = QgsVectorFileWriter(
output, systemEncoding,
layer.pendingFields(), provider.geometryType(),
diff --git a/src/app/qgscustomization.cpp b/src/app/qgscustomization.cpp
index 0f9c5c7..a30a214 100644
--- a/src/app/qgscustomization.cpp
+++ b/src/app/qgscustomization.cpp
@@ -576,7 +576,7 @@ void QgsCustomization::createTreeItemToolbars()
void QgsCustomization::createTreeItemDocks()
{
QStringList data;
- data << "Panels";
+ data << "Docks";
QTreeWidgetItem *topItem = new QTreeWidgetItem( data );
diff --git a/src/core/symbology-ng/qgspointdisplacementrenderer.cpp b/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
index 15c79af..a2bedf9 100644
--- a/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
+++ b/src/core/symbology-ng/qgspointdisplacementrenderer.cpp
@@ -329,6 +329,13 @@ QgsSymbolV2List QgsPointDisplacementRenderer::originalSymbolsForFeature( QgsFeat
return mRenderer->originalSymbolsForFeature( feat, context );
}
+QSet< QString > QgsPointDisplacementRenderer::legendKeysForFeature( QgsFeature& feat, QgsRenderContext& context )
+{
+ if ( !mRenderer )
+ return QSet< QString >() << QString();
+ return mRenderer->legendKeysForFeature( feat, context );
+}
+
bool QgsPointDisplacementRenderer::willRenderFeature( QgsFeature& feat, QgsRenderContext& context )
{
if ( !mRenderer )
diff --git a/src/core/symbology-ng/qgspointdisplacementrenderer.h b/src/core/symbology-ng/qgspointdisplacementrenderer.h
index 10dd03e..848e968 100644
--- a/src/core/symbology-ng/qgspointdisplacementrenderer.h
+++ b/src/core/symbology-ng/qgspointdisplacementrenderer.h
@@ -77,6 +77,10 @@ class CORE_EXPORT QgsPointDisplacementRenderer: public QgsFeatureRendererV2
@note available in python as originalSymbolsForFeature2
*/
virtual QgsSymbolV2List originalSymbolsForFeature( QgsFeature& feat, QgsRenderContext& context ) override;
+ /** Returns which legend keys match the feature
+ * @note added in QGIS 2.14.10
+ */
+ virtual QSet< QString > legendKeysForFeature( QgsFeature& feature, QgsRenderContext& context ) override;
/** Proxy that will call this method on the embedded renderer.
@note available in python as willRenderFeature2
*/
diff --git a/src/gui/qgsfiledownloader.cpp b/src/gui/qgsfiledownloader.cpp
index 36cde63..83520d2 100644
--- a/src/gui/qgsfiledownloader.cpp
+++ b/src/gui/qgsfiledownloader.cpp
@@ -60,7 +60,6 @@ void QgsFileDownloader::startDownload()
mReply = nam->get( request );
connect( mReply, SIGNAL( readyRead() ), this, SLOT( onReadyRead() ) );
- connect( mReply, SIGNAL( error( QNetworkReply::NetworkError ) ), this, SLOT( onNetworkError( QNetworkReply::NetworkError ) ) );
connect( mReply, SIGNAL( finished() ), this, SLOT( onFinished() ) );
connect( mReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( onDownloadProgress( qint64, qint64 ) ) );
connect( nam, SIGNAL( requestTimedOut( QNetworkReply* ) ), this, SLOT( onRequestTimedOut() ) );
@@ -161,7 +160,7 @@ void QgsFileDownloader::onFinished()
if ( mReply->error() )
{
mFile.remove();
- error( tr( "Download failed: %1." ).arg( mReply->errorString() ) );
+ error( tr( "Download failed: %1" ).arg( mReply->errorString() ) );
}
else if ( !redirectionTarget.isNull() )
{
@@ -174,18 +173,15 @@ void QgsFileDownloader::onFinished()
startDownload();
return;
}
- // All done
- emit downloadCompleted();
+ else
+ {
+ emit downloadCompleted();
+ }
}
emit downloadExited();
this->deleteLater();
}
-void QgsFileDownloader::onNetworkError( QNetworkReply::NetworkError err )
-{
- Q_ASSERT( mReply );
- error( QString( "Network error %1: %2" ).arg( err ).arg( mReply->errorString() ) );
-}
void QgsFileDownloader::onDownloadProgress( qint64 bytesReceived, qint64 bytesTotal )
{
diff --git a/src/gui/qgsfiledownloader.h b/src/gui/qgsfiledownloader.h
index 62e6d29..c9276f7 100644
--- a/src/gui/qgsfiledownloader.h
+++ b/src/gui/qgsfiledownloader.h
@@ -75,8 +75,6 @@ class GUI_EXPORT QgsFileDownloader : public QObject
void onReadyRead();
/** Called when the network reply has finished */
void onFinished();
- /** Called on Network Error */
- void onNetworkError( QNetworkReply::NetworkError err );
/** Called on data ready to be processed */
void onDownloadProgress( qint64 bytesReceived, qint64 bytesTotal );
/** Called when a network request times out */
diff --git a/src/plugins/geometry_checker/checks/qgsgeometrygapcheck.cpp b/src/plugins/geometry_checker/checks/qgsgeometrygapcheck.cpp
index 85c3564..c86c2da 100644
--- a/src/plugins/geometry_checker/checks/qgsgeometrygapcheck.cpp
+++ b/src/plugins/geometry_checker/checks/qgsgeometrygapcheck.cpp
@@ -79,7 +79,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError*>& errors,
// For each gap polygon which does not lie on the boundary, get neighboring polygons and add error
for ( int iPart = 0, nParts = diffGeom->partCount(); iPart < nParts; ++iPart )
{
- QgsAbstractGeometryV2* geom = QgsGeomUtils::getGeomPart( diffGeom, iPart );
+ QgsAbstractGeometryV2* geom = QgsGeomUtils::getGeomPart( diffGeom, iPart )->clone();
// Skip the gap between features and boundingbox
if ( geom->boundingBox() == envelope->boundingBox() )
{
@@ -118,7 +118,7 @@ void QgsGeometryGapCheck::collectErrors( QList<QgsGeometryCheckError*>& errors,
}
// Add error
- errors.append( new QgsGeometryGapCheckError( this, geom->clone(), neighboringIds, geom->area(), gapAreaBBox ) );
+ errors.append( new QgsGeometryGapCheckError( this, geom, neighboringIds, geom->area(), gapAreaBBox ) );
}
delete unionGeom;
diff --git a/src/plugins/geometry_checker/utils/qgsfeaturepool.cpp b/src/plugins/geometry_checker/utils/qgsfeaturepool.cpp
index 86e1d7d..c8f49cd 100644
--- a/src/plugins/geometry_checker/utils/qgsfeaturepool.cpp
+++ b/src/plugins/geometry_checker/utils/qgsfeaturepool.cpp
@@ -44,7 +44,14 @@ QgsFeaturePool::QgsFeaturePool( QgsVectorLayer *layer, bool selectedOnly )
QgsFeatureIterator it = layer->getFeatures( req );
while ( it.nextFeature( feature ) )
{
- mIndex.insertFeature( feature );
+ if ( feature.geometry() )
+ {
+ mIndex.insertFeature( feature );
+ }
+ else
+ {
+ mFeatureIds.remove( feature.id() );
+ }
}
}
diff --git a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
index 478a2ad..7d17fd9 100644
--- a/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
+++ b/src/providers/virtual/qgsvirtuallayersqlitemodule.cpp
@@ -616,13 +616,13 @@ int vtableFilter( sqlite3_vtab_cursor * cursor, int idxNum, const char *idxStr,
expr += "'" + str.replace( "'", "''" ) + "'";
break;
}
+ case SQLITE_NULL:
+ case SQLITE_BLOB: // comparison to blob ignored
default:
- expr = "";
- }
- if ( !expr.isEmpty() )
- {
- request.setFilterExpression( expr );
+ expr += " is null";
+ break;
}
+ request.setFilterExpression( expr );
}
VTableCursor *c = reinterpret_cast<VTableCursor*>( cursor );
c->filter( request );
diff --git a/src/server/qgsconfigparserutils.cpp b/src/server/qgsconfigparserutils.cpp
index b73d5b7..f89c41e 100644
--- a/src/server/qgsconfigparserutils.cpp
+++ b/src/server/qgsconfigparserutils.cpp
@@ -65,6 +65,9 @@ void QgsConfigParserUtils::appendCRSElementsToLayer( QDomElement& layerElement,
appendCRSElementToLayer( layerElement, CRSPrecedingElement, crs, doc );
}
}
+
+ //Support for CRS:84 is mandatory (equals EPSG:4326 with reversed axis)
+ appendCRSElementToLayer( layerElement, CRSPrecedingElement, QString( "CRS:84" ), doc );
}
void QgsConfigParserUtils::appendCRSElementToLayer( QDomElement& layerElement, const QDomElement& precedingElement,
@@ -77,7 +80,7 @@ void QgsConfigParserUtils::appendCRSElementToLayer( QDomElement& layerElement, c
layerElement.insertAfter( crsElement, precedingElement );
}
-void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& layerExtent,
+void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDomDocument& doc, const QgsRectangle& lExtent,
const QgsCoordinateReferenceSystem& layerCRS, const QStringList &crsList, const QStringList& constrainedCrsList )
{
if ( layerElem.isNull() )
@@ -85,6 +88,13 @@ void QgsConfigParserUtils::appendLayerBoundingBoxes( QDomElement& layerElem, QDo
return;
}
+ QgsRectangle layerExtent = lExtent;
+ if ( qgsDoubleNear( layerExtent.xMinimum(), layerExtent.xMaximum() ) || qgsDoubleNear( layerExtent.yMinimum(), layerExtent.yMaximum() ) )
+ {
+ //layer bbox cannot be empty
+ layerExtent.grow( 0.000001 );
+ }
+
const QgsCoordinateReferenceSystem& wgs84 = QgsCRSCache::instance()->crsByAuthId( GEO_EPSG_CRS_AUTHID );
QString version = doc.documentElement().attribute( "version" );
diff --git a/src/server/qgsserverprojectparser.cpp b/src/server/qgsserverprojectparser.cpp
index 860bec2..a2d7729 100644
--- a/src/server/qgsserverprojectparser.cpp
+++ b/src/server/qgsserverprojectparser.cpp
@@ -595,7 +595,7 @@ void QgsServerProjectParser::serviceCapabilities( QDomElement& parentElement, QD
//Fees
QDomElement feesElem = propertiesElement.firstChildElement( "WMSFees" );
QDomElement wmsFeesElem = doc.createElement( "Fees" );
- QDomText wmsFeesText = doc.createTextNode( "conditions unknown" ); // default value if access conditions are unknown
+ QDomText wmsFeesText = doc.createTextNode( "None" ); // default value if access conditions are unknown
if ( !feesElem.isNull() && !feesElem.text().isEmpty() )
{
wmsFeesText = doc.createTextNode( feesElem.text() );
diff --git a/src/server/qgswmsserver.cpp b/src/server/qgswmsserver.cpp
index ffa24f5..807384e 100644
--- a/src/server/qgswmsserver.cpp
+++ b/src/server/qgswmsserver.cpp
@@ -147,13 +147,30 @@ void QgsWMSServer::executeRequest()
}
//version
- QString version = mParameters.value( "VERSION", "1.3.0" );
+ QString version = "1.3.0";
+ if ( mParameters.contains( "VERSION" ) )
+ {
+ version = mParameters.value( "VERSION" );
+ }
+ else if ( mParameters.contains( "WMTVER" ) ) //WMTVER needs to be supported by WMS 1.1.1 for backwards compatibility with WMS 1.0.0
+ {
+ version = mParameters.value( "WMTVER" );
+ }
+
bool getProjectSettings = ( request.compare( "GetProjectSettings", Qt::CaseInsensitive ) == 0 );
if ( getProjectSettings )
{
version = "1.3.0"; //getProjectSettings extends WMS 1.3.0 capabilities
}
+ if ( version == "1.1.1" )
+ {
+ if ( request.compare( "capabilities", Qt::CaseInsensitive ) == 0 )
+ {
+ request = QString( "GetCapabilities" );
+ }
+ }
+
//GetCapabilities
if ( request.compare( "GetCapabilities", Qt::CaseInsensitive ) == 0 || getProjectSettings )
{
@@ -423,6 +440,12 @@ QDomDocument QgsWMSServer::getCapabilities( QString version, bool fullProjectInf
hrefString = serviceUrl();
}
+ //href needs to be a prefix
+ if ( !hrefString.endsWith( "?" ) && !hrefString.endsWith( "&" ) )
+ {
+ hrefString.append( hrefString.contains( "?" ) ? "&" : "?" );
+ }
+
if ( version == "1.1.1" )
{
doc = QDomDocument( "WMT_MS_Capabilities SYSTEM 'http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd'" ); //WMS 1.1.1 needs DOCTYPE "SYSTEM http://schemas.opengis.net/wms/1.1.1/WMS_MS_Capabilities.dtd"
@@ -556,7 +579,7 @@ QDomDocument QgsWMSServer::getCapabilities( QString version, bool fullProjectInf
//Exception element is mandatory
elem = doc.createElement( "Exception" );
- appendFormats( doc, elem, QStringList() << ( version == "1.1.1" ? "application/vnd.ogc.se_xml" : "text/xml" ) );
+ appendFormats( doc, elem, QStringList() << ( version == "1.1.1" ? "application/vnd.ogc.se_xml" : "XML" ) );
capabilityElement.appendChild( elem );
//UserDefinedSymbolization element
@@ -690,6 +713,10 @@ static QgsRectangle _parseBBOX( const QString &bboxStr, bool &ok )
}
ok = true;
+ if ( d[2] <= d[0] || d[3] <= d[1] )
+ {
+ throw QgsMapServiceException( "InvalidParameterValue", "BBOX is empty" );
+ }
return QgsRectangle( d[0], d[1], d[2], d[3] );
}
@@ -822,8 +849,6 @@ QImage* QgsWMSServer::getLegendGraphics()
}
QgsLayerTreeModel legendModel( &rootGroup );
- QList<QgsLayerTreeNode*> rootChildren = rootGroup.children();
-
if ( scaleDenominator > 0 )
legendModel.setLegendFilterByScale( scaleDenominator );
@@ -863,7 +888,7 @@ QImage* QgsWMSServer::getLegendGraphics()
}
// find out DPI
- QImage* tmpImage = createImage( 1, 1 );
+ QImage* tmpImage = createImage( 1, 1, false );
if ( !tmpImage )
return nullptr;
qreal dpmm = tmpImage->dotsPerMeterX() / 1000.0;
@@ -893,7 +918,7 @@ QImage* QgsWMSServer::getLegendGraphics()
if ( !rule.isEmpty() )
{
//create second image with the right dimensions
- QImage* paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight );
+ QImage* paintImage = createImage( ruleSymbolWidth, ruleSymbolHeight, false );
//go through the items a second time for painting
QPainter p( paintImage );
@@ -915,6 +940,7 @@ QImage* QgsWMSServer::getLegendGraphics()
return paintImage;
}
+ QList<QgsLayerTreeNode*> rootChildren = rootGroup.children();
Q_FOREACH ( QgsLayerTreeNode* node, rootChildren )
{
if ( QgsLayerTree::isLayer( node ) )
@@ -954,7 +980,7 @@ QImage* QgsWMSServer::getLegendGraphics()
QSizeF minSize = legendRenderer.minimumSize();
QSize s( minSize.width() * dpmm, minSize.height() * dpmm );
- QImage* paintImage = createImage( s.width(), s.height() );
+ QImage* paintImage = createImage( s.width(), s.height(), false );
QPainter p( paintImage );
p.setRenderHint( QPainter::Antialiasing, true );
@@ -1449,6 +1475,17 @@ QImage* QgsWMSServer::getMap( HitTest* hitTest )
// theImage->save( QDir::tempPath() + QDir::separator() + "lastrender.png" );
//#endif
+ thePainter.end();
+
+ //test if width / height ratio of image is the same as the ratio of WIDTH / HEIGHT parameters. If not, the image has to be scaled (required by WMS spec)
+ int widthParam = mParameters.value( "WIDTH", "0" ).toInt();
+ int heightParam = mParameters.value( "HEIGHT", "0" ).toInt();
+ if ( widthParam != theImage->width() || heightParam != theImage->height() )
+ {
+ //scale image
+ *theImage = theImage->scaled( widthParam, heightParam, Qt::IgnoreAspectRatio, Qt::SmoothTransformation );
+ }
+
return theImage;
}
@@ -1570,7 +1607,6 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, const QString& version )
QgsRectangle mapExtent = mMapRenderer->extent();
double scaleDenominator = scaleCalc.calculate( mapExtent, outputImage->width() );
mConfigParser->setScaleDenominator( scaleDenominator );
- delete outputImage; //no longer needed for feature info
//read FEATURE_COUNT
int featureCount = 1;
@@ -1610,6 +1646,16 @@ int QgsWMSServer::getFeatureInfo( QDomDocument& result, const QString& version )
j = -1;
}
+ //In case the output image is distorted (WIDTH/HEIGHT ratio not equal to BBOX width/height), I and J need to be adapted as well
+ int widthParam = mParameters.value( "WIDTH", "-1" ).toInt();
+ int heightParam = mParameters.value( "HEIGHT", "-1" ).toInt();
+ if (( i != -1 && j != -1 && widthParam != -1 && heightParam != -1 ) && ( widthParam != outputImage->width() || heightParam != outputImage->height() ) )
+ {
+ i *= ( outputImage->width() / ( double )widthParam );
+ j *= ( outputImage->height() / ( double )heightParam );
+ }
+ delete outputImage; //no longer needed for feature info
+
//Normally, I/J or X/Y are mandatory parameters.
//However, in order to make attribute only queries via the FILTER parameter, it is allowed to skip them if the FILTER parameter is there
@@ -1926,7 +1972,7 @@ QImage* QgsWMSServer::initializeRendering( QStringList& layersList, QStringList&
return theImage;
}
-QImage* QgsWMSServer::createImage( int width, int height ) const
+QImage* QgsWMSServer::createImage( int width, int height, bool useBbox ) const
{
bool conversionSuccess;
@@ -1946,6 +1992,32 @@ QImage* QgsWMSServer::createImage( int width, int height ) const
}
}
+ //Adapt width / height if the aspect ratio does not correspond with the BBOX.
+ //Required by WMS spec. 1.3.
+ if ( useBbox )
+ {
+ bool bboxOk;
+ QgsRectangle mapExtent = _parseBBOX( mParameters.value( "BBOX" ), bboxOk );
+ if ( bboxOk )
+ {
+ double mapWidthHeightRatio = mapExtent.width() / mapExtent.height();
+ double imageWidthHeightRatio = ( double )width / ( double )height;
+ if ( !qgsDoubleNear( mapWidthHeightRatio, imageWidthHeightRatio, 0.0001 ) )
+ {
+ if ( mapWidthHeightRatio >= imageWidthHeightRatio )
+ {
+ //increase image height
+ height = width * mapWidthHeightRatio;
+ }
+ else
+ {
+ //increase image width
+ width = height / mapWidthHeightRatio;
+ }
+ }
+ }
+ }
+
if ( width < 0 || height < 0 )
{
return nullptr;
@@ -1962,6 +2034,19 @@ QImage* QgsWMSServer::createImage( int width, int height ) const
//transparent parameter
bool transparent = mParameters.value( "TRANSPARENT" ).compare( "true", Qt::CaseInsensitive ) == 0;
+ //background color
+ QString bgColorString = mParameters.value( "BGCOLOR" );
+ if ( bgColorString.startsWith( "0x", Qt::CaseInsensitive ) )
+ {
+ bgColorString.replace( 0, 2, "#" );
+ }
+ QColor backgroundColor;
+ backgroundColor.setNamedColor( bgColorString );
+ if ( !backgroundColor.isValid() )
+ {
+ backgroundColor = QColor( Qt::white );
+ }
+
//use alpha channel only if necessary because it slows down performance
if ( transparent && !jpeg )
{
@@ -1971,7 +2056,7 @@ QImage* QgsWMSServer::createImage( int width, int height ) const
else
{
theImage = new QImage( width, height, QImage::Format_RGB32 );
- theImage->fill( qRgb( 255, 255, 255 ) );
+ theImage->fill( backgroundColor );
}
if ( !theImage )
@@ -2007,17 +2092,32 @@ int QgsWMSServer::configureMapRender( const QPaintDevice* paintDevice ) const
mMapRenderer->setOutputSize( QSize( paintDevice->width(), paintDevice->height() ), paintDevice->logicalDpiX() );
//map extent
- bool bboxOk;
- QgsRectangle mapExtent = _parseBBOX( mParameters.value( "BBOX", "0,0,0,0" ), bboxOk );
+ bool bboxOk = true;
+ QgsRectangle mapExtent;
+ if ( mParameters.contains( "BBOX" ) )
+ {
+ mapExtent = _parseBBOX( mParameters.value( "BBOX", "0,0,0,0" ), bboxOk );
+ }
+
if ( !bboxOk )
{
//throw a service exception
throw QgsMapServiceException( "InvalidParameterValue", "Invalid BBOX parameter" );
}
+ if ( mParameters.contains( "BBOX" ) && mapExtent.isEmpty() )
+ {
+ throw QgsMapServiceException( "InvalidParameterValue", "BBOX is empty" );
+ }
+
QGis::UnitType mapUnits = QGis::Degrees;
QString crs = mParameters.value( "CRS", mParameters.value( "SRS" ) );
+ if ( crs.compare( "CRS:84", Qt::CaseInsensitive ) == 0 )
+ {
+ crs = QString( "EPSG:4326" );
+ mapExtent.invert();
+ }
QgsCoordinateReferenceSystem outputCRS;
@@ -2154,6 +2254,12 @@ bool QgsWMSServer::infoPointToMapCoordinates( int i, int j, QgsPoint* infoPoint,
return false;
}
+ //check if i, j are in the pixel range of the image
+ if ( i < 0 || i > mapRenderer->width() || j < 0 || j > mapRenderer->height() )
+ {
+ throw QgsMapServiceException( "InvalidPoint", "I/J parameters not within the pixel range" );
+ }
+
double xRes = mapRenderer->extent().width() / mapRenderer->width();
double yRes = mapRenderer->extent().height() / mapRenderer->height();
infoPoint->setX( mapRenderer->extent().xMinimum() + i * xRes + xRes / 2.0 );
diff --git a/src/server/qgswmsserver.h b/src/server/qgswmsserver.h
index 26f2c37..edc580b 100644
--- a/src/server/qgswmsserver.h
+++ b/src/server/qgswmsserver.h
@@ -133,9 +133,11 @@ class QgsWMSServer: public QgsOWSServer
/** 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 0 in case of error*/
- QImage* createImage( int width = -1, int height = -1 ) const;
- /** Configures mMapRenderer to the parameters
+ 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)
@return 0 in case of success*/
diff --git a/tests/src/gui/testqgsfiledownloader.cpp b/tests/src/gui/testqgsfiledownloader.cpp
index fa9a7dc..9ab5bd0 100644
--- a/tests/src/gui/testqgsfiledownloader.cpp
+++ b/tests/src/gui/testqgsfiledownloader.cpp
@@ -172,7 +172,7 @@ void TestQgsFileDownloader::testInValidDownload()
QVERIFY( mError );
QVERIFY( !mCanceled );
QVERIFY( mTempFile->size() == 0 );
- QCOMPARE( mErrorMessage, QString( "Network error 3: Host www.doesnotexistofthatimsure.qgis not found" ) );
+ QCOMPARE( mErrorMessage, QString( "Download failed: Host www.doesnotexistofthatimsure.qgis not found" ) );
}
void TestQgsFileDownloader::testCanceledDownload()
@@ -205,7 +205,7 @@ void TestQgsFileDownloader::testInvalidUrl()
QVERIFY( !mCompleted );
QVERIFY( mError );
QVERIFY( !mCanceled );
- QCOMPARE( mErrorMessage, QString( "Network error 301: Protocol \"xyz\" is unknown" ) );
+ QCOMPARE( mErrorMessage, QString( "Download failed: Protocol \"xyz\" is unknown" ) );
}
void TestQgsFileDownloader::testBlankUrl()
@@ -216,7 +216,7 @@ void TestQgsFileDownloader::testBlankUrl()
QVERIFY( !mCompleted );
QVERIFY( mError );
QVERIFY( !mCanceled );
- QCOMPARE( mErrorMessage, QString( "Network error 301: Protocol \"\" is unknown" ) );
+ QCOMPARE( mErrorMessage, QString( "Download failed: Protocol \"\" is unknown" ) );
}
#ifndef QT_NO_OPENSSL
@@ -225,9 +225,9 @@ void TestQgsFileDownloader::testSslError_data()
QTest::addColumn<QString>( "url" );
QTest::addColumn<QString>( "result" );
- QTest::newRow( "expired" ) << "https://expired.badssl.com/" << "Network error 6: SSL handshake failed;SSL Errors: ;The certificate has expired";
- QTest::newRow( "self-signed" ) << "https://self-signed.badssl.com/" << "Network error 6: SSL handshake failed;SSL Errors: ;The certificate is self-signed, and untrusted";
- QTest::newRow( "untrusted-root" ) << "https://untrusted-root.badssl.com/" << "Network error 6: SSL handshake failed;No certificates could be verified;SSL Errors: ;The issuer certificate of a locally looked up certificate could not be found;The root CA certificate is not trusted for this purpose";
+ QTest::newRow( "expired" ) << "https://expired.badssl.com/" << "SSL Errors: ;The certificate has expired";
+ QTest::newRow( "self-signed" ) << "https://self-signed.badssl.com/" << "SSL Errors: ;The certificate is self-signed, and untrusted";
+ QTest::newRow( "untrusted-root" ) << "https://untrusted-root.badssl.com/" << "No certificates could be verified;SSL Errors: ;The issuer certificate of a locally looked up certificate could not be found;The root CA certificate is not trusted for this purpose";
}
void TestQgsFileDownloader::testSslError()
diff --git a/tests/src/python/test_qgsfiledownloader.py b/tests/src/python/test_qgsfiledownloader.py
index 776ad49..0fe3b09 100644
--- a/tests/src/python/test_qgsfiledownloader.py
+++ b/tests/src/python/test_qgsfiledownloader.py
@@ -78,7 +78,7 @@ class TestQgsFileDownloader(unittest.TestCase):
self.assertTrue(self.progress_was_called)
self.assertFalse(self.canceled_was_called)
self.assertTrue(self.error_was_called)
- self.assertEqual(self.error_args[1], [u'Network error 3: Host www.doesnotexistofthatimsure.qgis not found'])
+ self.assertEqual(self.error_args[1], [u'Download failed: Host www.doesnotexistofthatimsure.qgis not found'])
self.assertFalse(os.path.isfile(destination))
def test_dowloadCanceled(self):
@@ -99,7 +99,7 @@ class TestQgsFileDownloader(unittest.TestCase):
self.assertFalse(self.canceled_was_called)
self.assertTrue(self.error_was_called)
self.assertFalse(os.path.isfile(destination))
- self.assertEqual(self.error_args[1], [u"Network error 301: Protocol \"xyz\" is unknown"])
+ self.assertEqual(self.error_args[1], [u"Download failed: Protocol \"xyz\" is unknown"])
def test_InvalidFile(self):
self._make_download('https://github.com/qgis/QGIS/archive/master.zip', "")
@@ -117,7 +117,7 @@ class TestQgsFileDownloader(unittest.TestCase):
self.assertFalse(self.canceled_was_called)
self.assertTrue(self.error_was_called)
self.assertFalse(os.path.isfile(destination))
- self.assertEqual(self.error_args[1], [u"Network error 301: Protocol \"\" is unknown"])
+ self.assertEqual(self.error_args[1], [u"Download failed: Protocol \"\" is unknown"])
def ssl_compare(self, name, url, error):
destination = tempfile.mktemp()
@@ -130,12 +130,12 @@ class TestQgsFileDownloader(unittest.TestCase):
self.assertFalse(os.path.isfile(destination), msg)
result = sorted(self.error_args[1])
result = ';'.join(result)
- self.assertEqual(result, error, msg + "expected:\n%s\nactual:\n%s\n" % (result, error))
+ self.assertEqual(result, error, msg + "expected:\n%s\nactual:\n%s\n" % (error, result))
def test_sslExpired(self):
- self.ssl_compare("expired", "https://expired.badssl.com/", "Network error 6: SSL handshake failed;SSL Errors: ;The certificate has expired")
- self.ssl_compare("self-signed", "https://self-signed.badssl.com/", "Network error 6: SSL handshake failed;SSL Errors: ;The certificate is self-signed, and untrusted")
- self.ssl_compare("untrusted-root", "https://untrusted-root.badssl.com/", "Network error 6: SSL handshake failed;No certificates could be verified;SSL Errors: ;The issuer certificate of a locally looked up certificate could not be found;The root CA certificate is not trusted for this purpose")
+ self.ssl_compare("expired", "https://expired.badssl.com/", "SSL Errors: ;The certificate has expired")
+ self.ssl_compare("self-signed", "https://self-signed.badssl.com/", "SSL Errors: ;The certificate is self-signed, and untrusted")
+ self.ssl_compare("untrusted-root", "https://untrusted-root.badssl.com/", "No certificates could be verified;SSL Errors: ;The issuer certificate of a locally looked up certificate could not be found;The root CA certificate is not trusted for this purpose")
def _set_slot(self, *args, **kwargs):
#print('_set_slot(%s) called' % args[0])
diff --git a/tests/src/python/test_qgsserver.py b/tests/src/python/test_qgsserver.py
index 99a3ec4..f5e58a9 100644
--- a/tests/src/python/test_qgsserver.py
+++ b/tests/src/python/test_qgsserver.py
@@ -35,6 +35,10 @@ class TestQgsServer(unittest.TestCase):
def setUp(self):
"""Create the server instance"""
self.testdata_path = unitTestDataPath('qgis_server') + '/'
+
+ d = unitTestDataPath('qgis_server_accesscontrol') + '/'
+ self.projectPath = os.path.join(d, "project.qgs")
+
# Clean env just to be sure
env_vars = ['QUERY_STRING', 'QGIS_PROJECT_FILE']
for ev in env_vars:
@@ -407,6 +411,132 @@ class TestQgsServer(unittest.TestCase):
r, h = self._result(self.server.handleRequest(qs))
self._img_diff_error(r, h, "WMS_GetLegendGraphic_test_layertitle_false", 250, QSize(10, 10))
+ def test_wms_GetLegendGraphic_Basic(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello",
+ "LAYERTITLE": "FALSE",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "CRS": "EPSG:3857"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_Basic")
+
+ def test_wms_GetLegendGraphic_BoxSpace(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello",
+ "LAYERTITLE": "FALSE",
+ "BOXSPACE": "100",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "CRS": "EPSG:3857"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_BoxSpace")
+
+ def test_wms_GetLegendGraphic_SymbolSpace(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello",
+ "LAYERTITLE": "FALSE",
+ "SYMBOLSPACE": "100",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "CRS": "EPSG:3857"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSpace")
+
+ def test_wms_GetLegendGraphic_IconLabelSpace(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello",
+ "LAYERTITLE": "FALSE",
+ "ICONLABELSPACE": "100",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "CRS": "EPSG:3857"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_IconLabelSpace")
+
+ def test_wms_GetLegendGraphic_SymbolSize(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello",
+ "LAYERTITLE": "FALSE",
+ "SYMBOLWIDTH": "50",
+ "SYMBOLHEIGHT": "30",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "CRS": "EPSG:3857"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_SymbolSize")
+
+ def test_wms_GetLegendGraphic_BBox(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello,db_point",
+ "LAYERTITLE": "FALSE",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "BBOX": "-151.7,-38.9,51.0,78.0",
+ "CRS": "EPSG:4326"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox")
+
+ def test_wms_GetLegendGraphic_BBox2(self):
+ qs = "&".join(["%s=%s" % i for i in list({
+ "MAP": urllib.quote(self.projectPath),
+ "SERVICE": "WMS",
+ "VERSION": "1.1.1",
+ "REQUEST": "GetLegendGraphic",
+ "LAYER": "Country,Hello,db_point",
+ "LAYERTITLE": "FALSE",
+ "FORMAT": "image/png",
+ "HEIGHT": "500",
+ "WIDTH": "500",
+ "BBOX": "-76.08,-6.4,-19.38,38.04",
+ "SRS": "EPSG:4326"
+ }.items())])
+
+ r, h = self._result(self.server.handleRequest(qs))
+ self._img_diff_error(r, h, "WMS_GetLegendGraphic_BBox2")
+
def _result(self, data):
headers = {}
for line in data[0].decode('UTF-8').split("\n"):
diff --git a/tests/src/python/test_qgsserver_accesscontrol.py b/tests/src/python/test_qgsserver_accesscontrol.py
index 02c7c66..2d58d77 100644
--- a/tests/src/python/test_qgsserver_accesscontrol.py
+++ b/tests/src/python/test_qgsserver_accesscontrol.py
@@ -294,7 +294,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Country,Hello",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -311,7 +311,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Hello",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -327,7 +327,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Country",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -351,7 +351,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Hello",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -390,7 +390,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Hello",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -420,7 +420,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Country",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -842,7 +842,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Country,Hello_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -859,7 +859,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Hello_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -882,7 +882,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"FILTER": "Hello_Filter_SubsetString:\"pkuid\" IN ( 7 , 8 )",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -900,7 +900,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"FILTER": "Hello_Filter_SubsetString:\"pkuid\" IN ( 7 , 8 )",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -919,7 +919,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Hello_Project_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -936,7 +936,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"LAYERS": "Hello_Project_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857"
@@ -954,7 +954,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Hello_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -990,7 +990,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Hello_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -1026,7 +1026,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"QUERY_LAYERS": "Hello_Project_SubsetString",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
@@ -1135,7 +1135,7 @@ class TestQgsServerAccessControl(unittest.TestCase):
"FILTER": "Hello_Filter_SubsetString:\"pkuid\" IN ( 7 , 8 )",
"STYLES": "",
"FORMAT": "image/png",
- "BBOX": "-16817707,-4710778,5696513,14587125",
+ "BBOX": "-16817707,-6318936.5,5696513,16195283.5",
"HEIGHT": "500",
"WIDTH": "500",
"SRS": "EPSG:3857",
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox/WMS_GetLegendGraphic_BBox.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox/WMS_GetLegendGraphic_BBox.png
new file mode 100644
index 0000000..8b720ab
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox/WMS_GetLegendGraphic_BBox.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox2/WMS_GetLegendGraphic_BBox2.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox2/WMS_GetLegendGraphic_BBox2.png
new file mode 100644
index 0000000..131d528
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BBox2/WMS_GetLegendGraphic_BBox2.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_Basic/WMS_GetLegendGraphic_Basic.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_Basic/WMS_GetLegendGraphic_Basic.png
new file mode 100644
index 0000000..131d528
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_Basic/WMS_GetLegendGraphic_Basic.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BoxSpace/WMS_GetLegendGraphic_BoxSpace.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BoxSpace/WMS_GetLegendGraphic_BoxSpace.png
new file mode 100644
index 0000000..0c8e440
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_BoxSpace/WMS_GetLegendGraphic_BoxSpace.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_IconLabelSpace/WMS_GetLegendGraphic_IconLabelSpace.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_IconLabelSpace/WMS_GetLegendGraphic_IconLabelSpace.png
new file mode 100644
index 0000000..b300268
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_IconLabelSpace/WMS_GetLegendGraphic_IconLabelSpace.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSize/WMS_GetLegendGraphic_SymbolSize.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSize/WMS_GetLegendGraphic_SymbolSize.png
new file mode 100644
index 0000000..7a49f43
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSize/WMS_GetLegendGraphic_SymbolSize.png differ
diff --git a/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSpace/WMS_GetLegendGraphic_SymbolSpace.png b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSpace/WMS_GetLegendGraphic_SymbolSpace.png
new file mode 100644
index 0000000..dcab569
Binary files /dev/null and b/tests/testdata/control_images/qgis_server/WMS_GetLegendGraphic_SymbolSpace/WMS_GetLegendGraphic_SymbolSpace.png differ
diff --git a/tests/testdata/qgis_server/getcapabilities.txt b/tests/testdata/qgis_server/getcapabilities.txt
index ea62c81..ac29926 100644
--- a/tests/testdata/qgis_server/getcapabilities.txt
+++ b/tests/testdata/qgis_server/getcapabilities.txt
@@ -97,11 +97,12 @@ Content-Type: text/xml; charset=utf-8
</qgs:GetStyles>
</Request>
<Exception>
- <Format>text/xml</Format>
+ <Format>XML</Format>
</Exception>
<Layer queryable="1">
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
@@ -116,6 +117,7 @@ Content-Type: text/xml; charset=utf-8
<Name>testlayer èé</Name>
<Title>A test vector layer</Title>
<Abstract>A test vector layer with unicode òà</Abstract>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
diff --git a/tests/testdata/qgis_server/getcapabilities_inspire.txt b/tests/testdata/qgis_server/getcapabilities_inspire.txt
index da2f31d..d71d302 100644
--- a/tests/testdata/qgis_server/getcapabilities_inspire.txt
+++ b/tests/testdata/qgis_server/getcapabilities_inspire.txt
@@ -97,7 +97,7 @@ Content-Type: text/xml; charset=utf-8
</qgs:GetStyles>
</Request>
<Exception>
- <Format>text/xml</Format>
+ <Format>XML</Format>
</Exception>
<sld:UserDefinedSymbolization RemoteWFS="0" RemoteWCS="0" InlineFeature="0" UserStyle="1" SupportSLD="1" UserLayer="0"/>
<inspire_vs:ExtendedCapabilities>
@@ -123,6 +123,7 @@ Content-Type: text/xml; charset=utf-8
<Layer queryable="1">
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
@@ -137,6 +138,7 @@ Content-Type: text/xml; charset=utf-8
<Name>testlayer èé</Name>
<Title>A test vector layer</Title>
<Abstract>A test vector layer with unicode òà</Abstract>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
diff --git a/tests/testdata/qgis_server/getprojectsettings.txt b/tests/testdata/qgis_server/getprojectsettings.txt
index 7d25c2e..62b1fe6 100644
--- a/tests/testdata/qgis_server/getprojectsettings.txt
+++ b/tests/testdata/qgis_server/getprojectsettings.txt
@@ -109,7 +109,7 @@ Content-Type: text/xml; charset=utf-8
</GetPrint>
</Request>
<Exception>
- <Format>text/xml</Format>
+ <Format>XML</Format>
</Exception>
<sld:UserDefinedSymbolization RemoteWFS="0" RemoteWCS="0" InlineFeature="0" UserStyle="1" SupportSLD="1" UserLayer="0"/>
<WFSLayers>
@@ -118,6 +118,7 @@ Content-Type: text/xml; charset=utf-8
<Layer queryable="1">
<Name>QGIS Test Project</Name>
<Title>QGIS Test Project</Title>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
@@ -133,6 +134,7 @@ Content-Type: text/xml; charset=utf-8
<Name>testlayer èé</Name>
<Title>A test vector layer</Title>
<Abstract>A test vector layer with unicode òà</Abstract>
+ <CRS>CRS:84</CRS>
<CRS>EPSG:4326</CRS>
<CRS>EPSG:3857</CRS>
<EX_GeographicBoundingBox>
diff --git a/tests/testdata/qgis_server/wfs_getcapabilities.txt b/tests/testdata/qgis_server/wfs_getcapabilities.txt
index 2a7714c..420df60 100644
--- a/tests/testdata/qgis_server/wfs_getcapabilities.txt
+++ b/tests/testdata/qgis_server/wfs_getcapabilities.txt
@@ -7,7 +7,7 @@ Content-Type: text/xml; charset=utf-8
<Title>QGIS TestProject</Title>
<Abstract>Some UTF8 text èòù</Abstract>
<OnlineResource></OnlineResource>
- <Fees>conditions unknown</Fees>
+ <Fees>None</Fees>
<AccessConstraints>None</AccessConstraints>
</Service>
<Capability>
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-grass/qgis.git
More information about the Pkg-grass-devel
mailing list