Second part of fix for #9196 (WMTS)

If WMTS capabilities do not include a bounding box, try to detect it from
tileset matrix information (instead of using conservative assumption
that the layer spans the whole world: -180,-90 - 180,90 in WGS84)
This commit is contained in:
Martin Dobias 2014-01-29 18:27:06 +07:00
parent ba0a637803
commit ec7718b55e
2 changed files with 61 additions and 6 deletions

View File

@ -2964,12 +2964,6 @@ void QgsWmsProvider::parseWMTSContents( QDomElement const &e )
}
}
if ( l.boundingBox.crs.isEmpty() )
{
l.boundingBox.box = QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
l.boundingBox.crs = DEFAULT_LATLON_CRS;
}
for ( QDomElement e1 = e0.firstChildElement( "Style" );
!e1.isNull();
e1 = e1.nextSiblingElement( "Style" ) )
@ -3170,6 +3164,61 @@ void QgsWmsProvider::parseWMTSContents( QDomElement const &e )
mTileThemes << QgsWmtsTheme();
parseTheme( e0, mTileThemes.back() );
}
// make sure that all layers have a bounding box
for( QList<QgsWmtsTileLayer>::iterator it = mTileLayersSupported.begin(); it != mTileLayersSupported.end(); ++it )
{
QgsWmtsTileLayer& l = *it;
if ( l.boundingBox.crs.isEmpty() )
{
if ( !detectTileLayerBoundingBox( l ) )
{
QgsDebugMsg( "failed to detect bounding box for " + l.identifier + " - using extent of the whole world" );
l.boundingBox.box = QgsRectangle( -180.0, -90.0, 180.0, 90.0 );
l.boundingBox.crs = DEFAULT_LATLON_CRS;
}
}
}
}
bool QgsWmsProvider::detectTileLayerBoundingBox( QgsWmtsTileLayer& l )
{
if ( l.setLinks.isEmpty() )
return false;
// take first supported tile matrix set
const QgsWmtsTileMatrixSetLink& setLink = l.setLinks.constBegin().value();
QHash<QString, QgsWmtsTileMatrixSet>::const_iterator tmsIt = mTileMatrixSets.constFind( setLink.tileMatrixSet );
if ( tmsIt == mTileMatrixSets.constEnd() )
return false;
QgsCoordinateReferenceSystem crs;
if ( !crs.createFromOgcWmsCrs( tmsIt->crs ) )
return false;
// take most coarse tile matrix ...
QMap<double, QgsWmtsTileMatrix>::const_iterator tmIt = tmsIt->tileMatrices.constEnd() - 1;
if ( tmIt == tmsIt->tileMatrices.constEnd() )
return false;
const QgsWmtsTileMatrix& tm = *tmIt;
double metersPerUnit = QGis::fromUnitToUnitFactor( crs.mapUnits(), QGis::Meters );
double res = tm.scaleDenom * 0.00028 / metersPerUnit;
QgsPoint bottomRight( tm.topLeft.x() + res * tm.tileWidth * tm.matrixWidth,
tm.topLeft.y() - res * tm.tileHeight * tm.matrixHeight );
QgsDebugMsg( QString( "detecting WMTS layer bounding box: tileset %1 matrix %2 crs %3 res %4" )
.arg( tmsIt->identifier ).arg( tm.identifier ).arg( tmsIt->crs ).arg( res ) );
QgsRectangle extent( tm.topLeft, bottomRight );
extent.normalize();
l.boundingBox.box = extent;
l.boundingBox.crs = tmsIt->crs;
return true;
}

View File

@ -783,6 +783,12 @@ class QgsWmsProvider : public QgsRasterDataProvider
*/
bool extentForNonTiledLayer( const QString& layerName, const QString& crs, QgsRectangle& extent );
/**
* In case no bounding box is present in WMTS capabilities, try to estimate it from tile matrix sets.
* Returns true if the detection went fine.
*/
bool detectTileLayerBoundingBox( QgsWmtsTileLayer& l );
// case insensitive attribute value lookup
static QString nodeAttribute( const QDomElement &e, QString name, QString defValue = QString::null );