diff --git a/src/ol/source/WMTS.js b/src/ol/source/WMTS.js
index 5a98758886..e378d9e02c 100644
--- a/src/ol/source/WMTS.js
+++ b/src/ol/source/WMTS.js
@@ -451,20 +451,39 @@ export function optionsFromCapabilities(wmtsCap, config) {
const wrapX = false;
const switchOriginXY = projection.getAxisOrientation().substr(0, 2) == 'ne';
- const matrix0 = matrixSetObj.TileMatrix[0];
+ let matrix = matrixSetObj.TileMatrix[0];
+
+ // create default matrixLimit
+ let selectedMatrixLimit = {
+ MinTileCol: 0,
+ MinTileRow: 0,
+ // substract one to end up at tile top left
+ MaxTileCol: matrix.MatrixWidth - 1,
+ MaxTileRow: matrix.MatrixHeight - 1,
+ };
+
+ //in case of matrix limits, use matrix limits to calculate extent
+ if (matrixLimits) {
+ selectedMatrixLimit = matrixLimits[matrixLimits.length - 1];
+ matrix = matrixSetObj.TileMatrix.find(
+ (value) => value.Identifier === selectedMatrixLimit.TileMatrix
+ );
+ }
+
const resolution =
- (matrix0.ScaleDenominator * 0.00028) / projection.getMetersPerUnit(); // WMTS 1.0.0: standardized rendering pixel size
+ (matrix.ScaleDenominator * 0.00028) / projection.getMetersPerUnit(); // WMTS 1.0.0: standardized rendering pixel size
const origin = switchOriginXY
- ? [matrix0.TopLeftCorner[1], matrix0.TopLeftCorner[0]]
- : matrix0.TopLeftCorner;
- const tileSpanX = matrix0.TileWidth * resolution;
- const tileSpanY = matrix0.TileHeight * resolution;
+ ? [matrix.TopLeftCorner[1], matrix.TopLeftCorner[0]]
+ : matrix.TopLeftCorner;
+ const tileSpanX = matrix.TileWidth * resolution;
+ const tileSpanY = matrix.TileHeight * resolution;
const extent = [
- origin[0],
- origin[1] - tileSpanY * matrix0.MatrixHeight,
- origin[0] + tileSpanX * matrix0.MatrixWidth,
- origin[1],
+ origin[0] + tileSpanX * selectedMatrixLimit.MinTileCol,
+ // add one to get proper bottom/right coordinate
+ origin[1] - tileSpanY * (1 + selectedMatrixLimit.MaxTileRow),
+ origin[0] + tileSpanX * (1 + selectedMatrixLimit.MaxTileCol),
+ origin[1] - tileSpanY * selectedMatrixLimit.MinTileRow,
];
if (projection.getExtent() === null) {
diff --git a/test/spec/ol/format/wmts/capabilities_wgs84.xml b/test/spec/ol/format/wmts/capabilities_wgs84.xml
index 489ff5f5c8..67bbc0cfc9 100644
--- a/test/spec/ol/format/wmts/capabilities_wgs84.xml
+++ b/test/spec/ol/format/wmts/capabilities_wgs84.xml
@@ -38,103 +38,124 @@
default
image/png
+
+ inspire_quad
+
+
+
+
+ Mean depth full coverage with land coverage
+
+ mean_atlas_land
+
+ -36.0 15.0
+ 43.0 90.0
+
+
+ 14.999942759061003 -36.0
+ 90.0 42.999938986416
+
+
+ image/png
inspire_quad
0
0
- 1
+ 0
0
- 2
+ 1
1
0
- 2
- 0
- 4
+ 0
+ 1
+ 2
2
0
- 4
- 0
- 8
+ 1
+ 3
+ 4
3
0
- 8
- 0
- 16
+ 3
+ 6
+ 9
4
0
- 16
- 0
- 32
+ 6
+ 12
+ 19
5
0
- 32
- 0
- 64
+ 13
+ 25
+ 39
6
0
- 64
- 0
- 128
+ 26
+ 51
+ 79
7
0
- 128
- 0
- 256
+ 53
+ 102
+ 158
8
0
- 256
- 0
- 512
+ 106
+ 204
+ 317
9
0
- 512
- 0
- 1024
+ 213
+ 409
+ 634
10
0
- 1024
- 0
- 2048
+ 426
+ 819
+ 1268
11
0
- 2048
- 0
- 4096
+ 853
+ 1638
+ 2537
12
0
- 4096
- 0
- 8192
+ 1706
+ 3276
+ 5074
-
+
InspireCRS84Quad
diff --git a/test/spec/ol/source/wmts.test.js b/test/spec/ol/source/wmts.test.js
index 569ec55fd4..fae0de95e8 100644
--- a/test/spec/ol/source/wmts.test.js
+++ b/test/spec/ol/source/wmts.test.js
@@ -404,6 +404,51 @@ describe('ol.source.WMTS', function () {
expectDelta(extent[2], 180);
expectDelta(extent[3], 90);
});
+
+ it('returns correct bounding box for a layer restricted by TileMatrixSetLink', function () {
+ const options = optionsFromCapabilities(capabilities, {
+ layer: 'mean_atlas_land',
+ matrixSet: 'inspire_quad',
+ requestEncoding: 'REST',
+ });
+
+ expect(options.urls).to.be.an('array');
+ expect(options.urls).to.have.length(1);
+ expect(options.urls[0]).to.be.eql(
+ 'https://example.com/wmts/mean_atlas_land/{TileMatrixSet}/{TileMatrix}/{TileCol}/{TileRow}.png'
+ );
+
+ expect(options.layer).to.be.eql('mean_atlas_land');
+
+ expect(options.matrixSet).to.be.eql('inspire_quad');
+
+ expect(options.format).to.be.eql('image/png');
+
+ expect(options.projection).to.be.a(Projection);
+ expect(options.projection).to.be.eql(getProjection('EPSG:4326'));
+
+ expect(options.requestEncoding).to.be.eql('REST');
+
+ expect(options.tileGrid).to.be.a(WMTSTileGrid);
+ expect(options.style).to.be.eql('default');
+
+ const extent = options.tileGrid.getExtent();
+
+ // calculate with of one tile, this will be used as tolerance for result extent
+ const tile_width =
+ ((68247.34668319306 * 0.00028) /
+ getProjection('EPSG:4326').getMetersPerUnit()) *
+ 256;
+
+ // compare with delta, due to rounding not the exact bounding box is returned...
+ const expectDelta = (value, expected) =>
+ expect(Math.abs(value - expected)).to.below(tile_width + 1e-10);
+
+ expectDelta(extent[0], -36);
+ expectDelta(extent[1], 15);
+ expectDelta(extent[2], 43);
+ expectDelta(extent[3], 90);
+ });
});
describe('#setUrls()', function () {