diff --git a/src/ol/source/WMTS.js b/src/ol/source/WMTS.js
index c8b11c9c32..77663ad2a3 100644
--- a/src/ol/source/WMTS.js
+++ b/src/ol/source/WMTS.js
@@ -4,9 +4,8 @@
import {expandUrl, createFromTileUrlFunctions, nullTileUrlFunction} from '../tileurlfunction.js';
import {find, findIndex, includes} from '../array.js';
-import {containsExtent} from '../extent.js';
import {assign} from '../obj.js';
-import {get as getProjection, equivalent, transformExtent} from '../proj.js';
+import {get as getProjection, equivalent} from '../proj.js';
import TileImage from './TileImage.js';
import WMTSRequestEncoding from './WMTSRequestEncoding.js';
import {createFromCapabilitiesMatrixSet} from '../tilegrid/WMTS.js';
@@ -377,22 +376,25 @@ export function optionsFromCapabilities(wmtsCap, config) {
}
}
- const wgs84BoundingBox = l['WGS84BoundingBox'];
- let extent, wrapX;
- if (wgs84BoundingBox !== undefined) {
- const wgs84ProjectionExtent = getProjection('EPSG:4326').getExtent();
- wrapX = (wgs84BoundingBox[0] == wgs84ProjectionExtent[0] &&
- wgs84BoundingBox[2] == wgs84ProjectionExtent[2]);
- extent = transformExtent(
- wgs84BoundingBox, 'EPSG:4326', projection);
- const projectionExtent = projection.getExtent();
- if (projectionExtent) {
- // If possible, do a sanity check on the extent - it should never be
- // bigger than the validity extent of the projection of a matrix set.
- if (!containsExtent(projectionExtent, extent)) {
- extent = undefined;
- }
- }
+ const wrapX = false;
+
+ const matrix0 = matrixSetObj.TileMatrix[0];
+ const resolution = matrix0.ScaleDenominator * 0.00028; // WMTS 1.0.0: standardized rendering pixel size
+ const origin = projection === getProjection('EPSG:4326')
+ ? [matrix0.TopLeftCorner[1], matrix0.TopLeftCorner[0]]
+ : matrix0.TopLeftCorner;
+ const tileSpanX = matrix0.TileWidth * resolution;
+ const tileSpanY = matrix0.TileHeight * resolution;
+
+ const extent = [
+ origin[0],
+ origin[1] - tileSpanY * matrix0.MatrixHeight,
+ origin[0] + tileSpanX * matrix0.MatrixWidth,
+ origin[1]
+ ];
+
+ if (projection.getExtent() === null) {
+ projection.setExtent(extent);
}
const tileGrid = createFromCapabilitiesMatrixSet(matrixSetObj, extent, matrixLimits);
diff --git a/test/spec/ol/format/wmts/ogcsample.xml b/test/spec/ol/format/wmts/ogcsample.xml
index fbf7b282b8..7eb006bf2b 100644
--- a/test/spec/ol/format/wmts/ogcsample.xml
+++ b/test/spec/ol/format/wmts/ogcsample.xml
@@ -92,6 +92,9 @@ access interface to some TileMatrixSets
google3857
+
+ google3857subset
+
@@ -372,6 +375,29 @@ access interface to some TileMatrixSets
7000
-
+
+
+ google3857subset
+ urn:ogc:def:crs:EPSG:6.18:3:3857
+
+ 18
+ 2132.72958385
+ -10000000 10000000
+ 256
+ 256
+ 1
+ 1
+
+
+ 18
+ 1066.36479193
+ -10000000 10000000
+ 256
+ 256
+ 2
+ 2
+
+
+
diff --git a/test/spec/ol/format/wmtscapabilities.test.js b/test/spec/ol/format/wmtscapabilities.test.js
index 72b907cb3f..5bcf881758 100644
--- a/test/spec/ol/format/wmtscapabilities.test.js
+++ b/test/spec/ol/format/wmtscapabilities.test.js
@@ -54,11 +54,13 @@ describe('ol.format.WMTSCapabilities', function() {
expect(layer.Style[0].LegendURL[0].format).to.be.eql('image/png');
expect(layer.TileMatrixSetLink).to.be.an('array');
- expect(layer.TileMatrixSetLink).to.have.length(2);
+ expect(layer.TileMatrixSetLink).to.have.length(3);
expect(layer.TileMatrixSetLink[0].TileMatrixSet).to.be
.eql('BigWorldPixel');
expect(layer.TileMatrixSetLink[1].TileMatrixSet).to.be
.eql('google3857');
+ expect(layer.TileMatrixSetLink[2].TileMatrixSet).to.be
+ .eql('google3857subset');
const wgs84Bbox = layer.WGS84BoundingBox;
expect(wgs84Bbox).to.be.an('array');
diff --git a/test/spec/ol/source/wmts.test.js b/test/spec/ol/source/wmts.test.js
index b49d71e787..20cf5a41e1 100644
--- a/test/spec/ol/source/wmts.test.js
+++ b/test/spec/ol/source/wmts.test.js
@@ -1,4 +1,5 @@
import WMTSCapabilities from '../../../../src/ol/format/WMTSCapabilities.js';
+import {getBottomLeft, getTopRight} from '../../../../src/ol/extent.js';
import {get as getProjection} from '../../../../src/ol/proj.js';
import Projection from '../../../../src/ol/proj/Projection.js';
import WMTSTileGrid from '../../../../src/ol/tilegrid/WMTS.js';
@@ -149,6 +150,32 @@ describe('ol.source.WMTS', function() {
expect(options.projection.getCode()).to.be.eql('urn:ogc:def:crs:OGC:1.3:CRS84');
});
+ it('uses extent of tile matrix instead of projection extent', function() {
+ const options = optionsFromCapabilities(capabilities,
+ {layer: 'BlueMarbleNextGeneration', matrixSet: 'google3857subset'});
+
+ // Since google3857subset defines subset of space defined by the google3857 matrix set:
+ // - top left corner: -10000000, 10000000
+ // - calculated grid extent: [-10000000, 9999694.25188686, -9999694.25188686, 10000000]
+ // then the tile grid extent is only a part of the full projection extent.
+
+ const gridExtent = options.tileGrid.getExtent();
+ const gridBottomLeft = getBottomLeft(gridExtent);
+ const gridTopRight = getTopRight(gridExtent);
+ expect(Math.round(gridBottomLeft[0])).to.be.eql(-10000000);
+ expect(Math.round(gridBottomLeft[1])).to.be.eql(9999847);
+ expect(Math.round(gridTopRight[0])).to.be.eql(-9999847);
+ expect(Math.round(gridTopRight[1])).to.be.eql(10000000);
+
+ const projExtent = options.projection.getExtent();
+ const projBottomLeft = getBottomLeft(projExtent);
+ const projTopRight = getTopRight(projExtent);
+ expect(Math.round(projBottomLeft[0])).to.be.eql(-20037508);
+ expect(Math.round(projBottomLeft[1])).to.be.eql(-20037508);
+ expect(Math.round(projTopRight[0])).to.be.eql(20037508);
+ expect(Math.round(projTopRight[1])).to.be.eql(20037508);
+ });
+
it('doesn\'t fail if the GetCap doesn\'t contains Constraint tags', function() {
const tmpXml = content.replace(//g, '');
const tmpCapabilities = parser.read(tmpXml);