Skip to content

Commit

Permalink
Second part of fix for #9196 (WMTS)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
wonder-sk committed Jan 29, 2014
1 parent ba0a637 commit ec7718b
Show file tree
Hide file tree
Showing 2 changed files with 61 additions and 6 deletions.
61 changes: 55 additions & 6 deletions src/providers/wms/qgswmsprovider.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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" ) )
Expand Down Expand Up @@ -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;
}


Expand Down
6 changes: 6 additions & 0 deletions src/providers/wms/qgswmsprovider.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 );

Expand Down

0 comments on commit ec7718b

Please sign in to comment.