Skip to content

Commit bc87d51

Browse files
committedFeb 23, 2014
wms provider [hopefully fully adapted to merged threading]
* store all given bounding boxes and if available choose the given bbox for the requested srid, otherwise pick one that transforms fin(it)e * remove unused mCoordinateTransform * wmts: show tile matrix size with warnings when the matrix is not large enough to cover the layer extents
1 parent 4e162fa commit bc87d51

File tree

3 files changed

+483
-350
lines changed

3 files changed

+483
-350
lines changed
 

‎src/providers/wms/qgswmscapabilities.cpp

Lines changed: 100 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -103,8 +103,8 @@ bool QgsWmsSettings::parseUri( QString uriString )
103103

104104

105105
QgsWmsCapabilities::QgsWmsCapabilities()
106-
: mValid( false )
107-
, mLayerCount( -1 )
106+
: mValid( false )
107+
, mLayerCount( -1 )
108108
{
109109
}
110110

@@ -591,7 +591,7 @@ void QgsWmsCapabilities::parseCapability( QDomElement const & e, QgsWmsCapabilit
591591
else if ( name == "GetFeatureInfo" )
592592
{
593593
ot = &capabilityProperty.request.getFeatureInfo;
594-
}
594+
}
595595
else if ( name == "GetLegendGraphic" || name == "sld:GetLegendGraphic" )
596596
{
597597
ot = &capabilityProperty.request.getLegendGraphic;
@@ -692,7 +692,7 @@ void QgsWmsCapabilities::parseLegendUrl( QDomElement const & e, QgsWmsLegendUrlP
692692
}
693693

694694
void QgsWmsCapabilities::parseLayer( QDomElement const & e, QgsWmsLayerProperty& layerProperty,
695-
QgsWmsLayerProperty *parentProperty )
695+
QgsWmsLayerProperty *parentProperty )
696696
{
697697
QgsDebugMsg( "entering." );
698698

@@ -732,7 +732,7 @@ void QgsWmsCapabilities::parseLayer( QDomElement const & e, QgsWmsLayerProperty&
732732
// Ref: 7.2.4.8 Inheritance of layer properties
733733
subLayerProperty.style = layerProperty.style;
734734
subLayerProperty.crs = layerProperty.crs;
735-
subLayerProperty.boundingBox = layerProperty.boundingBox;
735+
subLayerProperty.boundingBoxes = layerProperty.boundingBoxes;
736736
subLayerProperty.ex_GeographicBoundingBox = layerProperty.ex_GeographicBoundingBox;
737737
// TODO
738738

@@ -846,7 +846,7 @@ void QgsWmsCapabilities::parseLayer( QDomElement const & e, QgsWmsLayerProperty&
846846
bbox.box = invAxisBbox;
847847
}
848848

849-
layerProperty.boundingBox.push_back( bbox );
849+
layerProperty.boundingBoxes << bbox;
850850
}
851851
else
852852
{
@@ -1180,20 +1180,33 @@ void QgsWmsCapabilities::parseTileSetProfile( QDomElement const &e )
11801180
}
11811181
else if ( tagName == "BoundingBox" )
11821182
{
1183-
l.boundingBox.box = QgsRectangle(
1184-
e1.attribute( "minx" ).toDouble(),
1185-
e1.attribute( "miny" ).toDouble(),
1186-
e1.attribute( "maxx" ).toDouble(),
1187-
e1.attribute( "maxy" ).toDouble()
1188-
);
1183+
QgsWmsBoundingBoxProperty bb;
1184+
bb.box = QgsRectangle(
1185+
e1.attribute( "minx" ).toDouble(),
1186+
e1.attribute( "miny" ).toDouble(),
1187+
e1.attribute( "maxx" ).toDouble(),
1188+
e1.attribute( "maxy" ).toDouble()
1189+
);
11891190
if ( e1.hasAttribute( "SRS" ) )
1190-
l.boundingBox.crs = e1.attribute( "SRS" );
1191+
bb.crs = e1.attribute( "SRS" );
11911192
else if ( e1.hasAttribute( "srs" ) )
1192-
l.boundingBox.crs = e1.attribute( "srs" );
1193+
bb.crs = e1.attribute( "srs" );
11931194
else if ( e1.hasAttribute( "CRS" ) )
1194-
l.boundingBox.crs = e1.attribute( "CRS" );
1195+
bb.crs = e1.attribute( "CRS" );
11951196
else if ( e1.hasAttribute( "crs" ) )
1196-
l.boundingBox.crs = e1.attribute( "crs" );
1197+
bb.crs = e1.attribute( "crs" );
1198+
else
1199+
QgsDebugMsg( "crs of bounding box undefined" );
1200+
1201+
if ( !bb.crs.isEmpty() )
1202+
{
1203+
QgsCoordinateReferenceSystem crs;
1204+
crs.createFromOgcWmsCrs( bb.crs );
1205+
if ( crs.isValid() )
1206+
bb.crs = crs.authid();
1207+
1208+
l.boundingBoxes << bb;
1209+
}
11971210
}
11981211
else if ( tagName == "Resolutions" )
11991212
{
@@ -1225,9 +1238,10 @@ void QgsWmsCapabilities::parseTileSetProfile( QDomElement const &e )
12251238
{
12261239
double r = rS.toDouble();
12271240
m.identifier = QString::number( i );
1228-
m.matrixWidth = ceil( l.boundingBox.box.width() / m.tileWidth / r );
1229-
m.matrixHeight = ceil( l.boundingBox.box.height() / m.tileHeight / r );
1230-
m.topLeft = QgsPoint( l.boundingBox.box.xMinimum(), l.boundingBox.box.yMinimum() + m.matrixHeight * m.tileHeight * r );
1241+
Q_ASSERT( l.boundingBoxes.size() == 1 );
1242+
m.matrixWidth = ceil( l.boundingBoxes[0].box.width() / m.tileWidth / r );
1243+
m.matrixHeight = ceil( l.boundingBoxes[0].box.height() / m.tileHeight / r );
1244+
m.topLeft = QgsPoint( l.boundingBoxes[0].box.xMinimum(), l.boundingBoxes[0].box.yMinimum() + m.matrixHeight * m.tileHeight * r );
12311245
ms.tileMatrices.insert( r, m );
12321246
i++;
12331247
}
@@ -1242,20 +1256,22 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
12421256
//
12431257

12441258
mTileMatrixSets.clear();
1245-
for ( QDomNode n0 = e.firstChildElement( "TileMatrixSet" ); !n0.isNull(); n0 = n0.nextSiblingElement( "TileMatrixSet" ) )
1259+
for ( QDomElement e0 = e.firstChildElement( "TileMatrixSet" );
1260+
!e0.isNull();
1261+
e0 = e0.nextSiblingElement( "TileMatrixSet" ) )
12461262
{
12471263
QgsWmtsTileMatrixSet s;
1248-
s.identifier = n0.firstChildElement( "ows:Identifier" ).text();
1249-
s.title = n0.firstChildElement( "ows:Title" ).text();
1250-
s.abstract = n0.firstChildElement( "ows:Abstract" ).text();
1251-
parseKeywords( n0, s.keywords );
1264+
s.identifier = e0.firstChildElement( "ows:Identifier" ).text();
1265+
s.title = e0.firstChildElement( "ows:Title" ).text();
1266+
s.abstract = e0.firstChildElement( "ows:Abstract" ).text();
1267+
parseKeywords( e0, s.keywords );
12521268

1253-
QString supportedCRS = n0.firstChildElement( "ows:SupportedCRS" ).text();
1269+
QString supportedCRS = e0.firstChildElement( "ows:SupportedCRS" ).text();
12541270

12551271
QgsCoordinateReferenceSystem crs;
12561272
crs.createFromOgcWmsCrs( supportedCRS );
12571273

1258-
s.wkScaleSet = n0.firstChildElement( "WellKnownScaleSet" ).text();
1274+
s.wkScaleSet = e0.firstChildElement( "WellKnownScaleSet" ).text();
12591275

12601276
double metersPerUnit = QGis::fromUnitToUnitFactor( crs.mapUnits(), QGis::Meters );
12611277

@@ -1273,20 +1289,20 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
12731289
.arg( invert ? "yes" : "no" )
12741290
);
12751291

1276-
for ( QDomNode n1 = n0.firstChildElement( "TileMatrix" );
1277-
!n1.isNull();
1278-
n1 = n1.nextSiblingElement( "TileMatrix" ) )
1292+
for ( QDomElement e1 = e0.firstChildElement( "TileMatrix" );
1293+
!e1.isNull();
1294+
e1 = e1.nextSiblingElement( "TileMatrix" ) )
12791295
{
12801296
QgsWmtsTileMatrix m;
12811297

1282-
m.identifier = n1.firstChildElement( "ows:Identifier" ).text();
1283-
m.title = n1.firstChildElement( "ows:Title" ).text();
1284-
m.abstract = n1.firstChildElement( "ows:Abstract" ).text();
1285-
parseKeywords( n1, m.keywords );
1298+
m.identifier = e1.firstChildElement( "ows:Identifier" ).text();
1299+
m.title = e1.firstChildElement( "ows:Title" ).text();
1300+
m.abstract = e1.firstChildElement( "ows:Abstract" ).text();
1301+
parseKeywords( e1, m.keywords );
12861302

1287-
m.scaleDenom = n1.firstChildElement( "ScaleDenominator" ).text().toDouble();
1303+
m.scaleDenom = e1.firstChildElement( "ScaleDenominator" ).text().toDouble();
12881304

1289-
QStringList topLeft = n1.firstChildElement( "TopLeftCorner" ).text().split( " " );
1305+
QStringList topLeft = e1.firstChildElement( "TopLeftCorner" ).text().split( " " );
12901306
if ( topLeft.size() == 2 )
12911307
{
12921308
if ( invert )
@@ -1304,10 +1320,10 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
13041320
continue;
13051321
}
13061322

1307-
m.tileWidth = n1.firstChildElement( "TileWidth" ).text().toInt();
1308-
m.tileHeight = n1.firstChildElement( "TileHeight" ).text().toInt();
1309-
m.matrixWidth = n1.firstChildElement( "MatrixWidth" ).text().toInt();
1310-
m.matrixHeight = n1.firstChildElement( "MatrixHeight" ).text().toInt();
1323+
m.tileWidth = e1.firstChildElement( "TileWidth" ).text().toInt();
1324+
m.tileHeight = e1.firstChildElement( "TileHeight" ).text().toInt();
1325+
m.matrixWidth = e1.firstChildElement( "MatrixWidth" ).text().toInt();
1326+
m.matrixHeight = e1.firstChildElement( "MatrixHeight" ).text().toInt();
13111327

13121328
double res = m.scaleDenom * 0.00028 / metersPerUnit;
13131329

@@ -1344,7 +1360,7 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
13441360
l.abstract = e0.firstChildElement( "ows:Abstract" ).text();
13451361
parseKeywords( e0, l.keywords );
13461362

1347-
l.boundingBox.crs = "";
1363+
QgsWmsBoundingBoxProperty bb;
13481364

13491365
QDomElement bbox = e0.firstChildElement( "ows:WGS84BoundingBox" );
13501366
if ( !bbox.isNull() )
@@ -1354,43 +1370,46 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
13541370

13551371
if ( ll.size() == 2 && ur.size() == 2 )
13561372
{
1357-
l.boundingBox.box = QgsRectangle( QgsPoint( ll[0].toDouble(), ll[1].toDouble() ),
1358-
QgsPoint( ur[0].toDouble(), ur[1].toDouble() ) );
1359-
l.boundingBox.crs = DEFAULT_LATLON_CRS;
1373+
bb.crs = DEFAULT_LATLON_CRS;
1374+
bb.box = QgsRectangle( QgsPoint( ll[0].toDouble(), ll[1].toDouble() ),
1375+
QgsPoint( ur[0].toDouble(), ur[1].toDouble() ) );
13601376
}
13611377
}
13621378

1363-
if ( l.boundingBox.crs.isEmpty() )
1379+
for ( bbox = e0.firstChildElement( "ows:BoundingBox" );
1380+
!bbox.isNull();
1381+
bbox = bbox.nextSiblingElement( "ows:BoundingBox" ) )
13641382
{
1365-
bbox = e0.firstChildElement( "ows:BoundingBox" );
1366-
if ( !bbox.isNull() )
1383+
QStringList ll = bbox.firstChildElement( "ows:LowerCorner" ).text().split( " " );
1384+
QStringList ur = bbox.firstChildElement( "ows:UpperCorner" ).text().split( " " );
1385+
1386+
if ( ll.size() == 2 && ur.size() == 2 )
13671387
{
1368-
QStringList ll = bbox.firstChildElement( "ows:LowerCorner" ).text().split( " " );
1369-
QStringList ur = bbox.firstChildElement( "ows:UpperCorner" ).text().split( " " );
1388+
bb.box = QgsRectangle( QgsPoint( ll[0].toDouble(), ll[1].toDouble() ),
1389+
QgsPoint( ur[0].toDouble(), ur[1].toDouble() ) );
1390+
1391+
if ( bbox.hasAttribute( "SRS" ) )
1392+
bb.crs = bbox.attribute( "SRS" );
1393+
else if ( bbox.hasAttribute( "srs" ) )
1394+
bb.crs = bbox.attribute( "srs" );
1395+
else if ( bbox.hasAttribute( "CRS" ) )
1396+
bb.crs = bbox.attribute( "CRS" );
1397+
else if ( bbox.hasAttribute( "crs" ) )
1398+
bb.crs = bbox.attribute( "crs" );
1399+
else
1400+
QgsDebugMsg( "crs of bounding box undefined" );
13701401

1371-
if ( ll.size() == 2 && ur.size() == 2 )
1402+
if ( !bb.crs.isEmpty() )
13721403
{
1373-
l.boundingBox.box = QgsRectangle( QgsPoint( ll[0].toDouble(), ll[1].toDouble() ),
1374-
QgsPoint( ur[0].toDouble(), ur[1].toDouble() ) );
1375-
1376-
if ( bbox.hasAttribute( "SRS" ) )
1377-
l.boundingBox.crs = bbox.attribute( "SRS" );
1378-
else if ( bbox.hasAttribute( "srs" ) )
1379-
l.boundingBox.crs = bbox.attribute( "srs" );
1380-
else if ( bbox.hasAttribute( "CRS" ) )
1381-
l.boundingBox.crs = bbox.attribute( "CRS" );
1382-
else if ( bbox.hasAttribute( "crs" ) )
1383-
l.boundingBox.crs = bbox.attribute( "crs" );
1404+
QgsCoordinateReferenceSystem crs;
1405+
crs.createFromOgcWmsCrs( bb.crs );
1406+
if ( crs.isValid() )
1407+
bb.crs = crs.authid();
1408+
l.boundingBoxes << bb;
13841409
}
13851410
}
13861411
}
13871412

1388-
if ( l.boundingBox.crs.isEmpty() )
1389-
{
1390-
l.boundingBox.box = QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
1391-
l.boundingBox.crs = DEFAULT_LATLON_CRS;
1392-
}
1393-
13941413
for ( QDomElement e1 = e0.firstChildElement( "Style" );
13951414
!e1.isNull();
13961415
e1 = e1.nextSiblingElement( "Style" ) )
@@ -1597,13 +1616,16 @@ void QgsWmsCapabilities::parseWMTSContents( QDomElement const &e )
15971616
{
15981617
QgsWmtsTileLayer& l = *it;
15991618

1600-
if ( l.boundingBox.crs.isEmpty() )
1619+
if ( l.boundingBoxes.isEmpty() )
16011620
{
16021621
if ( !detectTileLayerBoundingBox( l ) )
16031622
{
16041623
QgsDebugMsg( "failed to detect bounding box for " + l.identifier + " - using extent of the whole world" );
1605-
l.boundingBox.box = QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
1606-
l.boundingBox.crs = DEFAULT_LATLON_CRS;
1624+
1625+
QgsWmsBoundingBoxProperty bb;
1626+
bb.crs = DEFAULT_LATLON_CRS;
1627+
bb.box = QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
1628+
l.boundingBoxes << bb;
16071629
}
16081630
}
16091631
}
@@ -1699,8 +1721,11 @@ bool QgsWmsCapabilities::detectTileLayerBoundingBox( QgsWmtsTileLayer& l )
16991721
QgsRectangle extent( tm.topLeft, bottomRight );
17001722
extent.normalize();
17011723

1702-
l.boundingBox.box = extent;
1703-
l.boundingBox.crs = tmsIt->crs;
1724+
QgsWmsBoundingBoxProperty bb;
1725+
bb.box = extent;
1726+
bb.crs = crs.authid();
1727+
l.boundingBoxes << bb;
1728+
17041729
return true;
17051730
}
17061731

@@ -1731,9 +1756,9 @@ bool QgsWmsCapabilities::shouldInvertAxisOrientation( const QString& ogcCrs )
17311756

17321757

17331758
QgsWmsCapabilitiesDownload::QgsWmsCapabilitiesDownload( const QString& baseUrl, const QgsWmsAuthorization& auth, QObject *parent )
1734-
: QObject( parent )
1735-
, mBaseUrl( baseUrl )
1736-
, mAuth( auth )
1759+
: QObject( parent )
1760+
, mBaseUrl( baseUrl )
1761+
, mAuth( auth )
17371762
{
17381763
}
17391764

@@ -1764,7 +1789,7 @@ bool QgsWmsCapabilitiesDownload::downloadCapabilities()
17641789
connect( mCapabilitiesReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( capabilitiesReplyProgress( qint64, qint64 ) ), Qt::DirectConnection );
17651790

17661791
QEventLoop loop;
1767-
connect(mCapabilitiesReply, SIGNAL(finished()), &loop, SLOT(quit()));
1792+
connect( mCapabilitiesReply, SIGNAL( finished() ), &loop, SLOT( quit() ) );
17681793
loop.exec( QEventLoop::ExcludeUserInputEvents );
17691794

17701795
return mError.isEmpty();

‎src/providers/wms/qgswmscapabilities.h

Lines changed: 181 additions & 185 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,6 @@ struct QgsWmsContactInformationProperty
115115
// TODO: Fill to WMS specifications
116116
struct QgsWmsServiceProperty
117117
{
118-
// QString name; // Should always be "WMS"
119118
QString title;
120119
QString abstract;
121120
QStringList keywordList;
@@ -134,8 +133,6 @@ struct QgsWmsBoundingBoxProperty
134133
{
135134
QString crs;
136135
QgsRectangle box; // consumes minx, miny, maxx, maxy.
137-
double resx; // spatial resolution (in CRS units)
138-
double resy; // spatial resolution (in CRS units)
139136
};
140137

141138
/** Dimension Property structure */
@@ -262,7 +259,7 @@ struct QgsWmsLayerProperty
262259
QStringList keywordList;
263260
QStringList crs; // coord ref sys
264261
QgsRectangle ex_GeographicBoundingBox;
265-
QVector<QgsWmsBoundingBoxProperty> boundingBox;
262+
QVector<QgsWmsBoundingBoxProperty> boundingBoxes;
266263
QVector<QgsWmsDimensionProperty> dimension;
267264
QgsWmsAttributionProperty attribution;
268265
QVector<QgsWmsAuthorityUrlProperty> authorityUrl;
@@ -314,7 +311,6 @@ struct QgsWmtsTileMatrixSet
314311
QString identifier;
315312
QString title, abstract;
316313
QStringList keywords;
317-
QVector<QgsWmsBoundingBoxProperty> boundingBox;
318314
QString crs;
319315
QString wkScaleSet;
320316
QMap<double, QgsWmtsTileMatrix> tileMatrices;
@@ -370,7 +366,7 @@ struct QgsWmtsTileLayer
370366
QString identifier;
371367
QString title, abstract;
372368
QStringList keywords;
373-
QgsWmsBoundingBoxProperty boundingBox;
369+
QVector<QgsWmsBoundingBoxProperty> boundingBoxes;
374370
QStringList formats;
375371
QStringList infoFormats;
376372
QString defaultStyle;
@@ -439,7 +435,7 @@ struct QgsWmsParserSettings
439435
struct QgsWmsAuthorization
440436
{
441437
QgsWmsAuthorization( const QString& userName = QString(), const QString& password = QString(), const QString& referer = QString() )
442-
: mUserName( userName ), mPassword( password ), mReferer( referer ) {}
438+
: mUserName( userName ), mPassword( password ), mReferer( referer ) {}
443439

444440
void setAuthorization( QNetworkRequest &request ) const
445441
{
@@ -470,249 +466,249 @@ struct QgsWmsAuthorization
470466
/** URI that gets passed to provider */
471467
class QgsWmsSettings
472468
{
473-
public:
469+
public:
474470

475-
bool parseUri( QString uriString );
471+
bool parseUri( QString uriString );
476472

477-
QString baseUrl() const { return mBaseUrl; }
478-
QgsWmsAuthorization authorization() const { return mAuth; }
473+
QString baseUrl() const { return mBaseUrl; }
474+
QgsWmsAuthorization authorization() const { return mAuth; }
479475

480-
QgsWmsParserSettings parserSettings() const { return mParserSettings; }
476+
QgsWmsParserSettings parserSettings() const { return mParserSettings; }
481477

482-
protected:
483-
QgsWmsParserSettings mParserSettings;
478+
protected:
479+
QgsWmsParserSettings mParserSettings;
484480

485-
//! layer is tiled, tile layer and active matrix set
486-
bool mTiled;
487-
QHash<QString, QString> mTileDimensionValues;
488-
QString mTileMatrixSetId;
481+
//! layer is tiled, tile layer and active matrix set
482+
bool mTiled;
483+
QHash<QString, QString> mTileDimensionValues;
484+
QString mTileMatrixSetId;
489485

490-
/**
491-
* Maximum width and height of getmap requests
492-
*/
493-
int mMaxWidth;
494-
int mMaxHeight;
486+
/**
487+
* Maximum width and height of getmap requests
488+
*/
489+
int mMaxWidth;
490+
int mMaxHeight;
495491

496-
//! Data source URI of the WMS for this layer
497-
QString mHttpUri;
492+
//! Data source URI of the WMS for this layer
493+
QString mHttpUri;
498494

499-
//! URL part of URI (httpuri)
500-
QString mBaseUrl;
495+
//! URL part of URI (httpuri)
496+
QString mBaseUrl;
501497

502-
QgsWmsAuthorization mAuth;
498+
QgsWmsAuthorization mAuth;
503499

504-
bool mIgnoreGetMapUrl;
505-
bool mIgnoreGetFeatureInfoUrl;
506-
bool mSmoothPixmapTransform;
507-
enum QgsWmsDpiMode mDpiMode;
500+
bool mIgnoreGetMapUrl;
501+
bool mIgnoreGetFeatureInfoUrl;
502+
bool mSmoothPixmapTransform;
503+
enum QgsWmsDpiMode mDpiMode;
508504

509-
/**
510-
* Active sublayers managed by this provider in a draw function, in order from bottom to top
511-
* (some may not be visible in a draw function, cf. activeSubLayerVisibility)
512-
*/
513-
QStringList mActiveSubLayers;
514-
QStringList mActiveSubStyles;
505+
/**
506+
* Active sublayers managed by this provider in a draw function, in order from bottom to top
507+
* (some may not be visible in a draw function, cf. activeSubLayerVisibility)
508+
*/
509+
QStringList mActiveSubLayers;
510+
QStringList mActiveSubStyles;
515511

516-
/**
517-
* Visibility status of the given active sublayer
518-
*/
519-
QMap<QString, bool> mActiveSubLayerVisibility;
512+
/**
513+
* Visibility status of the given active sublayer
514+
*/
515+
QMap<QString, bool> mActiveSubLayerVisibility;
520516

521-
//! FEATURE_COUNT for GetFeatureInfo
522-
int mFeatureCount;
517+
//! FEATURE_COUNT for GetFeatureInfo
518+
int mFeatureCount;
523519

524-
/**
525-
* MIME type of the image encoding used from the WMS server
526-
*/
527-
QString mImageMimeType;
520+
/**
521+
* MIME type of the image encoding used from the WMS server
522+
*/
523+
QString mImageMimeType;
528524

529-
QString mCrsId;
525+
QString mCrsId;
530526

531-
friend class QgsWmsProvider;
527+
friend class QgsWmsProvider;
532528
};
533529

534530

535531
/** keeps information about capabilities of particular URI */
536532
class QgsWmsCapabilities
537533
{
538-
public:
539-
QgsWmsCapabilities();
540-
541-
bool isValid() const { return mValid; }
542-
543-
bool parseResponse( const QByteArray& response, const QgsWmsParserSettings& settings );
544-
545-
QString lastError() const { return mError; }
546-
QString lastErrorFormat() const { return mErrorFormat; }
547-
548-
QgsWmsCapabilitiesProperty capabilitiesProperty() { return mCapabilities; }
549-
550-
/**
551-
* \brief Returns a list of the supported layers of the WMS server
552-
*
553-
* \retval The list of layers will be placed here.
554-
*
555-
* \todo Document this better
556-
*/
557-
QVector<QgsWmsLayerProperty> supportedLayers() const { return mLayersSupported; }
558-
559-
//! get raster image encodings supported by the WMS, expressed as MIME types
560-
QStringList supportedImageEncodings() const { return mCapabilities.capability.request.getMap.format; }
561-
562-
/**
563-
* \brief Returns a map for the hierarchy of layers
564-
*/
565-
void layerParents( QMap<int, int> &parents, QMap<int, QStringList> &parentNames ) const { parents = mLayerParents; parentNames = mLayerParentNames; }
566-
567-
/**
568-
* \brief Returns a list of the supported tile layers of the WMS server
569-
*
570-
* \retval The list of tile sets will be placed here.
571-
*/
572-
QList<QgsWmtsTileLayer> supportedTileLayers() const { return mTileLayersSupported; }
534+
public:
535+
QgsWmsCapabilities();
536+
537+
bool isValid() const { return mValid; }
538+
539+
bool parseResponse( const QByteArray& response, const QgsWmsParserSettings& settings );
540+
541+
QString lastError() const { return mError; }
542+
QString lastErrorFormat() const { return mErrorFormat; }
543+
544+
QgsWmsCapabilitiesProperty capabilitiesProperty() { return mCapabilities; }
545+
546+
/**
547+
* \brief Returns a list of the supported layers of the WMS server
548+
*
549+
* \retval The list of layers will be placed here.
550+
*
551+
* \todo Document this better
552+
*/
553+
QVector<QgsWmsLayerProperty> supportedLayers() const { return mLayersSupported; }
554+
555+
//! get raster image encodings supported by the WMS, expressed as MIME types
556+
QStringList supportedImageEncodings() const { return mCapabilities.capability.request.getMap.format; }
557+
558+
/**
559+
* \brief Returns a map for the hierarchy of layers
560+
*/
561+
void layerParents( QMap<int, int> &parents, QMap<int, QStringList> &parentNames ) const { parents = mLayerParents; parentNames = mLayerParentNames; }
562+
563+
/**
564+
* \brief Returns a list of the supported tile layers of the WMS server
565+
*
566+
* \retval The list of tile sets will be placed here.
567+
*/
568+
QList<QgsWmtsTileLayer> supportedTileLayers() const { return mTileLayersSupported; }
573569

574-
/**
575-
* \brief Returns a list of the available tile matrix sets
576-
*/
577-
QHash<QString, QgsWmtsTileMatrixSet> supportedTileMatrixSets() const { return mTileMatrixSets; }
570+
/**
571+
* \brief Returns a list of the available tile matrix sets
572+
*/
573+
QHash<QString, QgsWmtsTileMatrixSet> supportedTileMatrixSets() const { return mTileMatrixSets; }
578574

579-
/** Find out whether to invert axis orientation when parsing/writing coordinates */
580-
bool shouldInvertAxisOrientation( const QString& ogcCrs );
575+
/** Find out whether to invert axis orientation when parsing/writing coordinates */
576+
bool shouldInvertAxisOrientation( const QString& ogcCrs );
581577

582-
protected:
583-
bool parseCapabilitiesDom( QByteArray const &xml, QgsWmsCapabilitiesProperty& capabilitiesProperty );
578+
protected:
579+
bool parseCapabilitiesDom( QByteArray const &xml, QgsWmsCapabilitiesProperty& capabilitiesProperty );
584580

585-
void parseService( QDomElement const & e, QgsWmsServiceProperty& serviceProperty );
586-
void parseOnlineResource( QDomElement const & e, QgsWmsOnlineResourceAttribute& onlineResourceAttribute );
587-
void parseKeywordList( QDomElement const & e, QStringList& keywordListProperty );
588-
void parseContactInformation( QDomElement const & e, QgsWmsContactInformationProperty& contactInformationProperty );
589-
void parseContactPersonPrimary( QDomElement const & e, QgsWmsContactPersonPrimaryProperty& contactPersonPrimaryProperty );
590-
void parseContactAddress( QDomElement const & e, QgsWmsContactAddressProperty& contactAddressProperty );
581+
void parseService( QDomElement const & e, QgsWmsServiceProperty& serviceProperty );
582+
void parseOnlineResource( QDomElement const & e, QgsWmsOnlineResourceAttribute& onlineResourceAttribute );
583+
void parseKeywordList( QDomElement const & e, QStringList& keywordListProperty );
584+
void parseContactInformation( QDomElement const & e, QgsWmsContactInformationProperty& contactInformationProperty );
585+
void parseContactPersonPrimary( QDomElement const & e, QgsWmsContactPersonPrimaryProperty& contactPersonPrimaryProperty );
586+
void parseContactAddress( QDomElement const & e, QgsWmsContactAddressProperty& contactAddressProperty );
591587

592-
void parseCapability( QDomElement const & e, QgsWmsCapabilityProperty& capabilityProperty );
593-
void parseRequest( QDomElement const & e, QgsWmsRequestProperty& requestProperty );
594-
void parseLegendUrl( QDomElement const &e, QgsWmsLegendUrlProperty &legendUrlProperty );
595-
void parseLayer( QDomElement const & e, QgsWmsLayerProperty& layerProperty, QgsWmsLayerProperty *parentProperty = 0 );
596-
void parseStyle( QDomElement const & e, QgsWmsStyleProperty& styleProperty );
588+
void parseCapability( QDomElement const & e, QgsWmsCapabilityProperty& capabilityProperty );
589+
void parseRequest( QDomElement const & e, QgsWmsRequestProperty& requestProperty );
590+
void parseLegendUrl( QDomElement const &e, QgsWmsLegendUrlProperty &legendUrlProperty );
591+
void parseLayer( QDomElement const & e, QgsWmsLayerProperty& layerProperty, QgsWmsLayerProperty *parentProperty = 0 );
592+
void parseStyle( QDomElement const & e, QgsWmsStyleProperty& styleProperty );
597593

598-
void parseOperationType( QDomElement const & e, QgsWmsOperationType& operationType );
599-
void parseDcpType( QDomElement const & e, QgsWmsDcpTypeProperty& dcpType );
600-
void parseHttp( QDomElement const & e, QgsWmsHttpProperty& httpProperty );
601-
void parseGet( QDomElement const & e, QgsWmsGetProperty& getProperty );
602-
void parsePost( QDomElement const & e, QgsWmsPostProperty& postProperty );
594+
void parseOperationType( QDomElement const & e, QgsWmsOperationType& operationType );
595+
void parseDcpType( QDomElement const & e, QgsWmsDcpTypeProperty& dcpType );
596+
void parseHttp( QDomElement const & e, QgsWmsHttpProperty& httpProperty );
597+
void parseGet( QDomElement const & e, QgsWmsGetProperty& getProperty );
598+
void parsePost( QDomElement const & e, QgsWmsPostProperty& postProperty );
603599

604-
void parseTileSetProfile( QDomElement const &e );
605-
void parseWMTSContents( QDomElement const &e );
606-
void parseKeywords( const QDomNode &e, QStringList &keywords );
607-
void parseTheme( const QDomElement &e, QgsWmtsTheme &t );
600+
void parseTileSetProfile( QDomElement const &e );
601+
void parseWMTSContents( QDomElement const &e );
602+
void parseKeywords( const QDomNode &e, QStringList &keywords );
603+
void parseTheme( const QDomElement &e, QgsWmtsTheme &t );
608604

609-
QString nodeAttribute( const QDomElement &e, QString name, QString defValue = QString::null );
605+
QString nodeAttribute( const QDomElement &e, QString name, QString defValue = QString::null );
610606

611-
/**
612-
* In case no bounding box is present in WMTS capabilities, try to estimate it from tile matrix sets.
613-
* Returns true if the detection went fine.
614-
*/
615-
bool detectTileLayerBoundingBox( QgsWmtsTileLayer& l );
607+
/**
608+
* In case no bounding box is present in WMTS capabilities, try to estimate it from tile matrix sets.
609+
* Returns true if the detection went fine.
610+
*/
611+
bool detectTileLayerBoundingBox( QgsWmtsTileLayer& l );
616612

617-
protected:
618-
bool mValid;
613+
protected:
614+
bool mValid;
619615

620-
QString mError;
621-
QString mErrorCaption;
622-
QString mErrorFormat;
616+
QString mError;
617+
QString mErrorCaption;
618+
QString mErrorFormat;
623619

624-
QgsWmsParserSettings mParserSettings;
620+
QgsWmsParserSettings mParserSettings;
625621

626-
//! number of layers and parents
627-
int mLayerCount;
628-
QMap<int, int> mLayerParents;
629-
QMap<int, QStringList> mLayerParentNames;
622+
//! number of layers and parents
623+
int mLayerCount;
624+
QMap<int, int> mLayerParents;
625+
QMap<int, QStringList> mLayerParentNames;
630626

631-
/**
632-
* WMS "queryable" per layer
633-
* Used in determining if the Identify map tool can be useful on the rendered WMS map layer.
634-
*/
635-
QMap<QString, bool> mQueryableForLayer;
627+
/**
628+
* WMS "queryable" per layer
629+
* Used in determining if the Identify map tool can be useful on the rendered WMS map layer.
630+
*/
631+
QMap<QString, bool> mQueryableForLayer;
636632

637-
/**
638-
* available CRSs per layer
639-
*/
640-
QMap<QString, QStringList > mCrsForLayer;
633+
/**
634+
* available CRSs per layer
635+
*/
636+
QMap<QString, QStringList > mCrsForLayer;
641637

642-
/**
643-
* layers hosted by the WMS
644-
*/
645-
QVector<QgsWmsLayerProperty> mLayersSupported;
638+
/**
639+
* layers hosted by the WMS
640+
*/
641+
QVector<QgsWmsLayerProperty> mLayersSupported;
646642

647-
/**
648-
* tilesets hosted by the WMTS
649-
*/
650-
QList<QgsWmtsTileLayer> mTileLayersSupported;
643+
/**
644+
* tilesets hosted by the WMTS
645+
*/
646+
QList<QgsWmtsTileLayer> mTileLayersSupported;
651647

652-
/**
653-
* themes hosted by the WMTS
654-
*/
655-
QList<QgsWmtsTheme> mTileThemes;
648+
/**
649+
* themes hosted by the WMTS
650+
*/
651+
QList<QgsWmtsTheme> mTileThemes;
656652

657-
/**
658-
* Parsed capabilities of the WMS
659-
*/
660-
QgsWmsCapabilitiesProperty mCapabilities;
653+
/**
654+
* Parsed capabilities of the WMS
655+
*/
656+
QgsWmsCapabilitiesProperty mCapabilities;
661657

662-
//! Formats supported by server and provider
663-
QMap<QgsRaster::IdentifyFormat, QString> mIdentifyFormats;
658+
//! Formats supported by server and provider
659+
QMap<QgsRaster::IdentifyFormat, QString> mIdentifyFormats;
664660

665661

666-
/**
667-
* tile matrix sets hosted by the WMS
668-
*/
669-
QHash<QString, QgsWmtsTileMatrixSet> mTileMatrixSets;
662+
/**
663+
* tile matrix sets hosted by the WMS
664+
*/
665+
QHash<QString, QgsWmtsTileMatrixSet> mTileMatrixSets;
670666

671667

672-
friend class QgsWmsProvider;
668+
friend class QgsWmsProvider;
673669
};
674670

675671

676672

677673
/** class that handles download of capabilities */
678674
class QgsWmsCapabilitiesDownload : public QObject
679675
{
680-
Q_OBJECT
676+
Q_OBJECT
681677

682-
public:
683-
QgsWmsCapabilitiesDownload( const QString& baseUrl, const QgsWmsAuthorization& auth, QObject* parent = 0 );
678+
public:
679+
QgsWmsCapabilitiesDownload( const QString& baseUrl, const QgsWmsAuthorization& auth, QObject* parent = 0 );
684680

685-
bool downloadCapabilities();
681+
bool downloadCapabilities();
686682

687-
QString lastError() const { return mError; }
683+
QString lastError() const { return mError; }
688684

689-
QByteArray response() const { return mHttpCapabilitiesResponse; }
685+
QByteArray response() const { return mHttpCapabilitiesResponse; }
690686

691-
signals:
692-
/** \brief emit a signal to be caught by qgisapp and display a msg on status bar */
693-
void statusChanged( QString const & theStatusQString );
687+
signals:
688+
/** \brief emit a signal to be caught by qgisapp and display a msg on status bar */
689+
void statusChanged( QString const & theStatusQString );
694690

695-
protected slots:
696-
void capabilitiesReplyFinished();
697-
void capabilitiesReplyProgress( qint64, qint64 );
691+
protected slots:
692+
void capabilitiesReplyFinished();
693+
void capabilitiesReplyProgress( qint64, qint64 );
698694

699-
protected:
700-
//! URL part of URI (httpuri)
701-
QString mBaseUrl;
695+
protected:
696+
//! URL part of URI (httpuri)
697+
QString mBaseUrl;
702698

703-
QgsWmsAuthorization mAuth;
699+
QgsWmsAuthorization mAuth;
704700

705-
/** The reply to the capabilities request */
706-
QNetworkReply *mCapabilitiesReply;
701+
/** The reply to the capabilities request */
702+
QNetworkReply *mCapabilitiesReply;
707703

708-
/** The error message associated with the last WMS error. */
709-
QString mError;
704+
/** The error message associated with the last WMS error. */
705+
QString mError;
710706

711-
/** The mime type of the message */
712-
QString mErrorFormat;
707+
/** The mime type of the message */
708+
QString mErrorFormat;
713709

714-
/** Capabilities of the WMS (raw) */
715-
QByteArray mHttpCapabilitiesResponse;
710+
/** Capabilities of the WMS (raw) */
711+
QByteArray mHttpCapabilitiesResponse;
716712

717713
};
718714

‎src/providers/wms/qgswmsprovider.cpp

Lines changed: 202 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ QgsWmsProvider::QgsWmsProvider( QString const& uri, const QgsWmsCapabilities* ca
8989
, mImageCrs( DEFAULT_LATLON_CRS )
9090
, mCachedImage( 0 )
9191
, mCachedViewExtent( 0 )
92-
, mCoordinateTransform( 0 )
9392
, mExtentDirty( true )
9493
, mGetFeatureInfoUrlBase( "" )
9594
, mTileReqNo( 0 )
@@ -177,13 +176,6 @@ QgsWmsProvider::~QgsWmsProvider()
177176
delete mCachedImage;
178177
mCachedImage = 0;
179178
}
180-
181-
if ( mCoordinateTransform )
182-
{
183-
delete mCoordinateTransform;
184-
mCoordinateTransform = 0;
185-
}
186-
187179
}
188180

189181
QgsRasterInterface * QgsWmsProvider::clone() const
@@ -346,15 +338,7 @@ bool QgsWmsProvider::setImageCrs( QString const & crs )
346338

347339
if ( crs != mImageCrs && !crs.isEmpty() )
348340
{
349-
// delete old coordinate transform as it is no longer valid
350-
if ( mCoordinateTransform )
351-
{
352-
delete mCoordinateTransform;
353-
mCoordinateTransform = 0;
354-
}
355-
356341
mExtentDirty = true;
357-
358342
mImageCrs = crs;
359343
}
360344

@@ -934,12 +918,12 @@ bool QgsWmsProvider::extentForNonTiledLayer( const QString& layerName, const QSt
934918
return false;
935919

936920
// see if we can refine the bounding box with the CRS-specific bounding boxes
937-
for ( int i = 0; i < layerProperty->boundingBox.size(); i++ )
921+
for ( int i = 0; i < layerProperty->boundingBoxes.size(); i++ )
938922
{
939-
if ( layerProperty->boundingBox[i].crs == crs )
923+
if ( layerProperty->boundingBoxes[i].crs == crs )
940924
{
941925
// exact bounding box is provided for this CRS
942-
extent = layerProperty->boundingBox[i].box;
926+
extent = layerProperty->boundingBoxes[i].box;
943927
return true;
944928
}
945929
}
@@ -951,15 +935,15 @@ bool QgsWmsProvider::extentForNonTiledLayer( const QString& layerName, const QSt
951935
// Use the coarse bounding box
952936
extent = layerProperty->ex_GeographicBoundingBox;
953937

954-
for ( int i = 0; i < layerProperty->boundingBox.size(); i++ )
938+
for ( int i = 0; i < layerProperty->boundingBoxes.size(); i++ )
955939
{
956-
if ( layerProperty->boundingBox[i].crs == DEFAULT_LATLON_CRS )
940+
if ( layerProperty->boundingBoxes[i].crs == DEFAULT_LATLON_CRS )
957941
{
958-
if ( layerProperty->boundingBox[i].box.contains( extent ) )
942+
if ( layerProperty->boundingBoxes[i].box.contains( extent ) )
959943
continue; // this bounding box is less specific (probably inherited from parent)
960944

961945
// this BBox is probably better than the one in ex_GeographicBoundingBox
962-
extent = layerProperty->boundingBox[i].box;
946+
extent = layerProperty->boundingBoxes[i].box;
963947
break;
964948
}
965949
}
@@ -1014,10 +998,10 @@ bool QgsWmsProvider::parseServiceExceptionReportDom( QByteArray const & xml, QSt
1014998
{
1015999
errorTitle = tr( "Dom Exception" );
10161000
errorText = tr( "Could not get WMS Service Exception: %1 at line %2 column %3\n\nResponse was:\n\n%4" )
1017-
.arg( errorMsg )
1018-
.arg( errorLine )
1019-
.arg( errorColumn )
1020-
.arg( QString( xml ) );
1001+
.arg( errorMsg )
1002+
.arg( errorLine )
1003+
.arg( errorColumn )
1004+
.arg( QString( xml ) );
10211005

10221006
QgsLogger::debug( "Dom Exception: " + errorText );
10231007

@@ -1085,7 +1069,7 @@ void QgsWmsProvider::parseServiceException( QDomElement const & e, QString& erro
10851069
else if ( seCode == "LayerNotDefined" )
10861070
{
10871071
errorText = tr( "GetMap request is for a Layer not offered by the server, "
1088-
"or GetFeatureInfo request is for a Layer not shown on the map." );
1072+
"or GetFeatureInfo request is for a Layer not shown on the map." );
10891073
}
10901074
else if ( seCode == "StyleNotDefined" )
10911075
{
@@ -1102,17 +1086,17 @@ void QgsWmsProvider::parseServiceException( QDomElement const & e, QString& erro
11021086
else if ( seCode == "CurrentUpdateSequence" )
11031087
{
11041088
errorText = tr( "Value of (optional) UpdateSequence parameter in GetCapabilities request is equal to "
1105-
"current value of service metadata update sequence number." );
1089+
"current value of service metadata update sequence number." );
11061090
}
11071091
else if ( seCode == "InvalidUpdateSequence" )
11081092
{
11091093
errorText = tr( "Value of (optional) UpdateSequence parameter in GetCapabilities request is greater "
1110-
"than current value of service metadata update sequence number." );
1094+
"than current value of service metadata update sequence number." );
11111095
}
11121096
else if ( seCode == "MissingDimensionValue" )
11131097
{
11141098
errorText = tr( "Request does not include a sample dimension value, and the server did not declare a "
1115-
"default value for that dimension." );
1099+
"default value for that dimension." );
11161100
}
11171101
else if ( seCode == "InvalidDimensionValue" )
11181102
{
@@ -1182,48 +1166,54 @@ bool QgsWmsProvider::calculateExtent()
11821166

11831167
QgsDebugMsg( "entered." );
11841168

1185-
// Set up the coordinate transform from the WMS standard CRS:84 bounding
1186-
// box to the user's selected CRS
1187-
if ( !mCoordinateTransform )
1188-
{
1189-
QgsCoordinateReferenceSystem qgisSrsSource;
1190-
QgsCoordinateReferenceSystem qgisSrsDest;
1191-
1192-
if ( mSettings.mTiled && mTileLayer )
1193-
{
1194-
QgsDebugMsg( QString( "Tile layer's extent: %1 %2" ).arg( mTileLayer->boundingBox.box.toString() ).arg( mTileLayer->boundingBox.crs ) );
1195-
qgisSrsSource.createFromOgcWmsCrs( mTileLayer->boundingBox.crs );
1196-
}
1197-
else
1198-
{
1199-
qgisSrsSource.createFromOgcWmsCrs( DEFAULT_LATLON_CRS );
1200-
}
1201-
1202-
qgisSrsDest.createFromOgcWmsCrs( mImageCrs );
1203-
1204-
mCoordinateTransform = new QgsCoordinateTransform( qgisSrsSource, qgisSrsDest );
1205-
}
1206-
12071169
if ( mSettings.mTiled )
12081170
{
12091171
if ( mTileLayer )
12101172
{
1211-
try
1173+
int i;
1174+
for ( i = 0; i < mTileLayer->boundingBoxes.size() && mTileLayer->boundingBoxes[i].crs != mImageCrs; i++ )
1175+
QgsDebugMsg( QString( "Skip %1 [%2]" ).arg( mTileLayer->boundingBoxes[i].crs ).arg( mImageCrs ) );
1176+
1177+
if ( i < mTileLayer->boundingBoxes.size() )
12121178
{
1213-
QgsRectangle extent = mCoordinateTransform->transformBoundingBox( mTileLayer->boundingBox.box, QgsCoordinateTransform::ForwardTransform );
1179+
mLayerExtent = mTileLayer->boundingBoxes[i].box;
1180+
}
1181+
else
1182+
{
1183+
QgsCoordinateReferenceSystem qgisSrsDest;
1184+
qgisSrsDest.createFromOgcWmsCrs( mImageCrs );
12141185

1215-
//make sure extent does not contain 'inf' or 'nan'
1216-
if ( extent.isFinite() )
1186+
// pick the first that transforms fin(it)e
1187+
for ( i = 0; i < mTileLayer->boundingBoxes.size(); i++ )
12171188
{
1218-
QgsDebugMsg( "exiting with '" + mLayerExtent.toString() + "'." );
1219-
mLayerExtent = extent;
1220-
return true;
1189+
QgsCoordinateReferenceSystem qgisSrsSource;
1190+
qgisSrsSource.createFromOgcWmsCrs( mTileLayer->boundingBoxes[i].crs );
1191+
1192+
QgsCoordinateTransform ct( qgisSrsSource, qgisSrsDest );
1193+
1194+
QgsDebugMsg( QString( "ct: %1 => %2" ).arg( mTileLayer->boundingBoxes[i].crs ).arg( mImageCrs ) );
1195+
1196+
try
1197+
{
1198+
QgsRectangle extent = ct.transformBoundingBox( mTileLayer->boundingBoxes[i].box, QgsCoordinateTransform::ForwardTransform );
1199+
1200+
//make sure extent does not contain 'inf' or 'nan'
1201+
if ( extent.isFinite() )
1202+
{
1203+
mLayerExtent = extent;
1204+
break;
1205+
}
1206+
}
1207+
catch ( QgsCsException &cse )
1208+
{
1209+
Q_UNUSED( cse );
1210+
}
12211211
}
12221212
}
1223-
catch ( QgsCsException &cse )
1224-
{
1225-
Q_UNUSED( cse );
1226-
}
1213+
1214+
QgsDebugMsg( "exiting with '" + mLayerExtent.toString() + "'." );
1215+
1216+
return true;
12271217
}
12281218

12291219
QgsDebugMsg( "no extent returned" );
@@ -1760,7 +1750,7 @@ QString QgsWmsProvider::metadata()
17601750

17611751
foreach ( const QgsWmtsTileLayer &l, mCaps.mTileLayersSupported )
17621752
{
1763-
metadata += "<tr><td colspan=\"2\">";
1753+
metadata += "<tr><td>";
17641754
metadata += l.identifier;
17651755
metadata += "</td><td class=\"glossy\">";
17661756

@@ -1774,7 +1764,7 @@ QString QgsWmsProvider::metadata()
17741764
}
17751765
else
17761766
{
1777-
Q_ASSERT( l.tileMode == WMTS || l.tileMode == WMSC );
1767+
metadata += tr( "Invalid tile mode" );
17781768
}
17791769

17801770
metadata += "</td></tr>";
@@ -1812,16 +1802,23 @@ QString QgsWmsProvider::metadata()
18121802
metadata += "<tr><td class=\"glossy\">";
18131803
metadata += tr( "CRS" );
18141804
metadata += "</td>";
1805+
metadata += "<td>";
1806+
metadata += "<table><tr>";
18151807
metadata += "<td class=\"glossy\">";
1816-
metadata += l.boundingBox.crs;
1817-
metadata += "</td></tr>";
1818-
1819-
metadata += "<tr><td class=\"glossy\">";
1820-
metadata += tr( "Bounding Box" );
1808+
metadata += tr( "CRS" );
18211809
metadata += "</td>";
18221810
metadata += "<td class=\"glossy\">";
1823-
metadata += l.boundingBox.box.toString();
1824-
metadata += "</td></tr>";
1811+
metadata += tr( "Bounding Box" );
1812+
metadata += "</td>";
1813+
for ( int i = 0; i < l.boundingBoxes.size(); i++ )
1814+
{
1815+
metadata += "<tr><td>";
1816+
metadata += l.boundingBoxes[i].crs;
1817+
metadata += "</td><td>";
1818+
metadata += l.boundingBoxes[i].box.toString();
1819+
metadata += "</td></tr>";
1820+
}
1821+
metadata += "</table></td></tr>";
18251822

18261823
metadata += "<tr><td class=\"glossy\">";
18271824
metadata += tr( "Available Tilesets" );
@@ -1847,15 +1844,130 @@ QString QgsWmsProvider::metadata()
18471844
metadata += "<tr><td>";
18481845
metadata += "<table width=\"100%\">";
18491846

1847+
if ( mTileMatrixSet )
1848+
{
1849+
metadata += "<tr><table width=\"100%\">";
1850+
1851+
metadata += QString( "<tr><th colspan=14 class=\"glossy\">%1 %2</th></tr>"
1852+
"<tr>"
1853+
"<th rowspan=2 class=\"glossy\">%3</th>"
1854+
"<th colspan=2 class=\"glossy\">%4</th>"
1855+
"<th colspan=2 class=\"glossy\">%5</th>"
1856+
"<th colspan=2 class=\"glossy\">%6</th>"
1857+
"<th colspan=2 class=\"glossy\">%7</th>"
1858+
"<th colspan=4 class=\"glossy\">%8</th>"
1859+
"</tr><tr>"
1860+
"<th class=\"glossy\">%9</th><th class=\"glossy\">%10</th>"
1861+
"<th class=\"glossy\">%9</th><th class=\"glossy\">%10</th>"
1862+
"<th class=\"glossy\">%9</th><th class=\"glossy\">%10</th>"
1863+
"<th class=\"glossy\">%9</th><th class=\"glossy\">%10</th>"
1864+
"<th class=\"glossy\">%11</th>"
1865+
"<th class=\"glossy\">%12</th>"
1866+
"<th class=\"glossy\">%13</th>"
1867+
"<th class=\"glossy\">%14</th>"
1868+
"</tr>" )
1869+
.arg( tr( "Selected tile matrix set " ) ).arg( mSettings.mTileMatrixSetId )
1870+
.arg( tr( "Scale" ) )
1871+
.arg( tr( "Tile size [px]" ) )
1872+
.arg( tr( "Tile size [mu]" ) )
1873+
.arg( tr( "Matrix size" ) )
1874+
.arg( tr( "Matrix extent [mu]" ) )
1875+
.arg( tr( "Bounds" ) )
1876+
.arg( tr( "Width" ) ).arg( tr( "Height" ) )
1877+
.arg( tr( "Top" ) ).arg( tr( "Left" ) )
1878+
.arg( tr( "Bottom" ) ).arg( tr( "Right" ) );
1879+
1880+
foreach ( QVariant res, property( "resolutions" ).toList() )
1881+
{
1882+
double key = res.toDouble();
1883+
1884+
QgsWmtsTileMatrix &tm = mTileMatrixSet->tileMatrices[ key ];
1885+
1886+
double tw = key * tm.tileWidth;
1887+
double th = key * tm.tileHeight;
1888+
1889+
QgsRectangle r( tm.topLeft.x(), tm.topLeft.y() - tw * tm.matrixWidth, tm.topLeft.x() + th * tm.matrixHeight, tm.topLeft.y() );
1890+
1891+
metadata += QString( "<tr>"
1892+
"<td>%1</td>"
1893+
"<td>%2</td><td>%3</td>"
1894+
"<td>%4</td><td>%5</td>"
1895+
"<td>%6</td><td>%7</td>"
1896+
"<td>%8</td><td>%9</td>" )
1897+
.arg( tm.scaleDenom )
1898+
.arg( tm.tileWidth ).arg( tm.tileHeight )
1899+
.arg( tw ).arg( th )
1900+
.arg( tm.matrixWidth ).arg( tm.matrixHeight )
1901+
.arg( tw * tm.matrixWidth, 0, 'f' )
1902+
.arg( th * tm.matrixHeight, 0, 'f' );
1903+
1904+
// top
1905+
if ( mLayerExtent.yMaximum() > r.yMaximum() )
1906+
{
1907+
metadata += QString( "<td title=\"%1<br>%2\"><font color=\"red\">%3</font></td>" )
1908+
.arg( tr( "%n missing row(s)", 0, ( int ) ceil(( mLayerExtent.yMaximum() - r.yMaximum() ) / th ) ) )
1909+
.arg( tr( "Layer's upper bound: %1" ).arg( mLayerExtent.yMaximum(), 0, 'f' ) )
1910+
.arg( r.yMaximum(), 0, 'f' );
1911+
}
1912+
else
1913+
{
1914+
metadata += QString( "<td>%1</td>" ).arg( r.yMaximum(), 0, 'f' );
1915+
}
1916+
1917+
// left
1918+
if ( mLayerExtent.xMinimum() < r.xMinimum() )
1919+
{
1920+
metadata += QString( "<td title=\"%1<br>%2\"><font color=\"red\">%3</font></td>" )
1921+
.arg( tr( "%n missing column(s)", 0, ( int ) ceil(( r.xMinimum() - mLayerExtent.xMinimum() ) / tw ) ) )
1922+
.arg( tr( "Layer's left bound: %1" ).arg( mLayerExtent.xMinimum(), 0, 'f' ) )
1923+
.arg( r.xMinimum(), 0, 'f' );
1924+
}
1925+
else
1926+
{
1927+
metadata += QString( "<td>%1</td>" ).arg( r.xMinimum(), 0, 'f' );
1928+
}
1929+
1930+
// bottom
1931+
if ( mLayerExtent.yMaximum() > r.yMaximum() )
1932+
{
1933+
metadata += QString( "<td title=\"%1<br>%2\"><font color=\"red\">%3</font></td>" )
1934+
.arg( tr( "%n missing row(s)", 0, ( int ) ceil(( mLayerExtent.yMaximum() - r.yMaximum() ) / th ) ) )
1935+
.arg( tr( "Layer's lower bound: %1" ).arg( mLayerExtent.yMaximum(), 0, 'f' ) )
1936+
.arg( r.yMaximum(), 0, 'f' );
1937+
}
1938+
else
1939+
{
1940+
metadata += QString( "<td>%1</td>" ).arg( r.yMaximum(), 0, 'f' );
1941+
}
1942+
1943+
// right
1944+
if ( mLayerExtent.xMaximum() > r.xMaximum() )
1945+
{
1946+
metadata += QString( "<td title=\"%1<br>%2\"><font color=\"red\">%3</font></td>" )
1947+
.arg( tr( "%n missing column(s)", 0, ( int ) ceil(( mLayerExtent.xMaximum() - r.xMaximum() ) / tw ) ) )
1948+
.arg( tr( "Layer's right bound: %1" ).arg( mLayerExtent.xMaximum(), 0, 'f' ) )
1949+
.arg( r.xMaximum(), 0, 'f' );
1950+
}
1951+
else
1952+
{
1953+
metadata += QString( "<td>%1</td>" ).arg( r.xMaximum(), 0, 'f' );
1954+
}
1955+
1956+
metadata += "</tr>";
1957+
}
1958+
1959+
metadata += "</table></td></tr>";
1960+
}
1961+
1962+
const QgsWmsStatistics::Stat& stat = QgsWmsStatistics::statForUri( dataSourceUri() );
1963+
18501964
metadata += "<tr><th class=\"glossy\">";
18511965
metadata += tr( "Property" );
18521966
metadata += "</th>";
18531967
metadata += "<th class=\"glossy\">";
18541968
metadata += tr( "Value" );
18551969
metadata += "</th></tr>";
18561970

1857-
const QgsWmsStatistics::Stat& stat = QgsWmsStatistics::statForUri( dataSourceUri() );
1858-
18591971
metadata += "<tr><td>";
18601972
metadata += tr( "Hits" );
18611973
metadata += "</td><td>";
@@ -2076,7 +2188,7 @@ QgsRasterIdentifyResult QgsWmsProvider::identify( const QgsPoint & thePoint, Qgs
20762188
connect( mIdentifyReply, SIGNAL( finished() ), this, SLOT( identifyReplyFinished() ) );
20772189

20782190
QEventLoop loop;
2079-
connect(mIdentifyReply, SIGNAL(finished()), &loop, SLOT(quit()));
2191+
connect( mIdentifyReply, SIGNAL( finished() ), &loop, SLOT( quit() ) );
20802192
loop.exec( QEventLoop::ExcludeUserInputEvents );
20812193

20822194
if ( mIdentifyResultBodies.size() == 0 ) // no result
@@ -2599,7 +2711,7 @@ QImage QgsWmsProvider::getLegendGraphic( double scale, bool forceRefresh )
25992711
connect( mGetLegendGraphicReply, SIGNAL( downloadProgress( qint64, qint64 ) ), this, SLOT( getLegendGraphicReplyProgress( qint64, qint64 ) ) );
26002712

26012713
QEventLoop loop;
2602-
connect(mGetLegendGraphicReply, SIGNAL(finished()), &loop, SLOT(quit()));
2714+
connect( mGetLegendGraphicReply, SIGNAL( finished() ), &loop, SLOT( quit() ) );
26032715
loop.exec( QEventLoop::ExcludeUserInputEvents );
26042716

26052717
QgsDebugMsg( "exiting." );
@@ -2724,10 +2836,10 @@ QGISEXTERN bool isProvider()
27242836
// -----------------
27252837

27262838
QgsWmsImageDownloadHandler::QgsWmsImageDownloadHandler( const QString& providerUri, const QUrl& url, const QgsWmsAuthorization& auth, QImage* image )
2727-
: mProviderUri( providerUri )
2728-
, mCachedImage( image )
2729-
, mEventLoop( new QEventLoop )
2730-
, mNAM( new QgsNetworkAccessManager )
2839+
: mProviderUri( providerUri )
2840+
, mCachedImage( image )
2841+
, mEventLoop( new QEventLoop )
2842+
, mNAM( new QgsNetworkAccessManager )
27312843
{
27322844
mNAM->setupDefaultProxyAndCache();
27332845

@@ -2797,7 +2909,7 @@ void QgsWmsImageDownloadHandler::cacheReplyFinished()
27972909
p.drawImage( 0, 0, myLocalImage );
27982910
}
27992911
else if ( contentType.startsWith( "image/", Qt::CaseInsensitive ) ||
2800-
contentType.compare( "application/octet-stream", Qt::CaseInsensitive ) == 0 )
2912+
contentType.compare( "application/octet-stream", Qt::CaseInsensitive ) == 0 )
28012913
{
28022914
QgsMessageLog::logMessage( tr( "Returned image is flawed [Content-Type:%1; URL:%2]" )
28032915
.arg( contentType ).arg( mCacheReply->url().toString() ), tr( "WMS" ) );
@@ -2864,14 +2976,14 @@ void QgsWmsImageDownloadHandler::cacheReplyProgress( qint64 bytesReceived, qint6
28642976

28652977

28662978
QgsWmsTiledImageDownloadHandler::QgsWmsTiledImageDownloadHandler( const QString& providerUri, const QgsWmsAuthorization& auth, int tileReqNo, const QList<QgsWmsTiledImageDownloadHandler::TileRequest>& requests, QImage* cachedImage, const QgsRectangle& cachedViewExtent, bool smoothPixmapTransform )
2867-
: mProviderUri( providerUri )
2868-
, mAuth( auth )
2869-
, mCachedImage( cachedImage )
2870-
, mCachedViewExtent( cachedViewExtent )
2871-
, mEventLoop( new QEventLoop )
2872-
, mNAM( new QgsNetworkAccessManager )
2873-
, mTileReqNo( tileReqNo )
2874-
, mSmoothPixmapTransform( smoothPixmapTransform )
2979+
: mProviderUri( providerUri )
2980+
, mAuth( auth )
2981+
, mCachedImage( cachedImage )
2982+
, mCachedViewExtent( cachedViewExtent )
2983+
, mEventLoop( new QEventLoop )
2984+
, mNAM( new QgsNetworkAccessManager )
2985+
, mTileReqNo( tileReqNo )
2986+
, mSmoothPixmapTransform( smoothPixmapTransform )
28752987
{
28762988
mNAM->setupDefaultProxyAndCache();
28772989

0 commit comments

Comments
 (0)
Please sign in to comment.