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);