diff --git a/src/ol/format/WMTSCapabilities.js b/src/ol/format/WMTSCapabilities.js index 9e72eb213e..9dceae171d 100644 --- a/src/ol/format/WMTSCapabilities.js +++ b/src/ol/format/WMTSCapabilities.js @@ -103,7 +103,7 @@ const LAYER_PARSERS = makeStructureNS( makeStructureNS(OWS_NAMESPACE_URIS, { 'Title': makeObjectPropertySetter(readString), 'Abstract': makeObjectPropertySetter(readString), - 'WGS84BoundingBox': makeObjectPropertySetter(readWgs84BoundingBox), + 'WGS84BoundingBox': makeObjectPropertySetter(readBoundingBox), 'Identifier': makeObjectPropertySetter(readString), }) ); @@ -196,6 +196,7 @@ const TMS_PARSERS = makeStructureNS( makeStructureNS(OWS_NAMESPACE_URIS, { 'SupportedCRS': makeObjectPropertySetter(readString), 'Identifier': makeObjectPropertySetter(readString), + 'BoundingBox': makeObjectPropertySetter(readBoundingBox), }) ); @@ -304,9 +305,9 @@ function readResourceUrl(node, objectStack) { /** * @param {Element} node Node. * @param {Array<*>} objectStack Object stack. - * @return {Object|undefined} WGS84 BBox object. + * @return {Object|undefined} BBox object. */ -function readWgs84BoundingBox(node, objectStack) { +function readBoundingBox(node, objectStack) { const coordinates = pushParseAndPop( [], WGS84_BBOX_READERS, diff --git a/src/ol/source/WMTS.js b/src/ol/source/WMTS.js index a9cf332e85..68ece7ba05 100644 --- a/src/ol/source/WMTS.js +++ b/src/ol/source/WMTS.js @@ -6,6 +6,7 @@ import TileImage from './TileImage.js'; import WMTSRequestEncoding from './WMTSRequestEncoding.js'; import {appendParams} from '../uri.js'; import {assign} from '../obj.js'; +import {containsExtent} from '../extent.js'; import {createFromCapabilitiesMatrixSet} from '../tilegrid/WMTS.js'; import {createFromTileUrlFunctions, expandUrl} from '../tileurlfunction.js'; import {equivalent, get as getProjection} from '../proj.js'; @@ -442,7 +443,7 @@ export function optionsFromCapabilities(wmtsCap, config) { } } - const wrapX = false; + let wrapX = false; const switchOriginXY = projection.getAxisOrientation().substr(0, 2) == 'ne'; let matrix = matrixSetObj.TileMatrix[0]; @@ -478,8 +479,8 @@ export function optionsFromCapabilities(wmtsCap, config) { : matrix.TopLeftCorner; const tileSpanX = matrix.TileWidth * resolution; const tileSpanY = matrix.TileHeight * resolution; - - const extent = [ + const matrixSetExtent = matrixSetObj['BoundingBox']; + let extent = [ origin[0] + tileSpanX * selectedMatrixLimit.MinTileCol, // add one to get proper bottom/right coordinate origin[1] - tileSpanY * (1 + selectedMatrixLimit.MaxTileRow), @@ -487,6 +488,18 @@ export function optionsFromCapabilities(wmtsCap, config) { origin[1] - tileSpanY * selectedMatrixLimit.MinTileRow, ]; + if ( + matrixSetExtent !== undefined && + !containsExtent(matrixSetExtent, extent) + ) { + const wgs84BoundingBox = l['WGS84BoundingBox']; + const wgs84ProjectionExtent = getProjection('EPSG:4326').getExtent(); + extent = matrixSetExtent; + wrapX = + wgs84BoundingBox[0] === wgs84ProjectionExtent[0] && + wgs84BoundingBox[2] === wgs84ProjectionExtent[2]; + } + if (projection.getExtent() === null) { projection.setExtent(extent); } diff --git a/test/spec/ol/format/wmts/capabilities_wgs84_with_boundingbox.xml b/test/spec/ol/format/wmts/capabilities_wgs84_with_boundingbox.xml new file mode 100644 index 0000000000..a06db94d83 --- /dev/null +++ b/test/spec/ol/format/wmts/capabilities_wgs84_with_boundingbox.xml @@ -0,0 +1,626 @@ + + + basemap.at + basemap.at ist eine Rasterkarte in Form eines vorgenerierten Kachel-Caches, in der Web Mercator Auxiliary Sphere und damit kompatibel zu den gängigen weltweiten Basiskarten wie beispielsweise jenen von OpenStreetMap, Google Maps und Bing Maps. + OGC WMTS + 1.0.0 + none + https://www.basemap.at + + + City of Vienna + + + + + Vienna + Austria + viennagis@post.wien.gv.at + + + + + + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + RESTful + + + + + + + + + + Geoland Basemap + Basemap von Österreich in Farbe + + 8.782379 46.358770 + 17.5 49.037872 + + geolandbasemap + + image/png + + google3857 + + + + + + + + + Geoland Basemap Overlay + Basemap von Österreich nur Beschriftung als transparenter Layer + + 8.782379 46.358770 + 17.5 49.037872 + + bmapoverlay + + image/png + + google3857 + + + + + + + + + Geoland Basemap Grau + Basemap von Österreich in Grau + + 8.782379 46.358770 + 17.5 49.037872 + + bmapgrau + + image/png + + google3857 + + + + + + + + + Basemap High DPI + Basemap mit 512x512px Kacheln für Unterstützung von User Endgeräten mit high dpi Displays (iPad retina, smartphones mit HD Auflösung) + + 8.782379 46.358770 + 17.5 49.037872 + + bmaphidpi + + image/jpeg + + google3857 + + + + + + + + + Geoland Basemap Orthofoto + Basemap als farbiges Orthofoto + + 8.782379 46.358770 + 17.5 49.037872 + + bmaporthofoto30cm + + image/jpeg + + google3857 + + + + + + + + + Geoland Basemap Gelände + Basemap Geländedarstellung von Österreich in Grau + + 8.782379 46.358770 + 17.5 49.037872 + + bmapgelaende + + image/jpeg + + google3857_0-17 + + + + + + + + + Geoland Basemap Oberfläche + Basemap Oberflächendarstellung von Österreich in Grau + + 8.782379 46.358770 + 17.5 49.037872 + + bmapoberflaeche + + image/jpeg + + google3857_0-17 + + + + + + + + + google3857 + + 977650 5838030 + 1913530 6281290 + + urn:ogc:def:crs:EPSG:6.18.3:3857 + urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible + + 0 + 559082264.029 + -20037508.3428 20037508.3428 + 256 + 256 + 1 + 1 + + + 1 + 279541132.015 + -20037508.3428 20037508.3428 + 256 + 256 + 2 + 2 + + + 2 + 139770566.007 + -20037508.3428 20037508.3428 + 256 + 256 + 4 + 4 + + + 3 + 69885283.0036 + -20037508.3428 20037508.3428 + 256 + 256 + 8 + 8 + + + 4 + 34942641.5018 + -20037508.3428 20037508.3428 + 256 + 256 + 16 + 16 + + + 5 + 17471320.7509 + -20037508.3428 20037508.3428 + 256 + 256 + 32 + 32 + + + 6 + 8735660.37545 + -20037508.3428 20037508.3428 + 256 + 256 + 64 + 64 + + + 7 + 4367830.18773 + -20037508.3428 20037508.3428 + 256 + 256 + 128 + 128 + + + 8 + 2183915.09386 + -20037508.3428 20037508.3428 + 256 + 256 + 256 + 256 + + + 9 + 1091957.54693 + -20037508.3428 20037508.3428 + 256 + 256 + 512 + 512 + + + 10 + 545978.773466 + -20037508.3428 20037508.3428 + 256 + 256 + 1024 + 1024 + + + 11 + 272989.386733 + -20037508.3428 20037508.3428 + 256 + 256 + 2048 + 2048 + + + 12 + 136494.693366 + -20037508.3428 20037508.3428 + 256 + 256 + 4096 + 4096 + + + 13 + 68247.3466832 + -20037508.3428 20037508.3428 + 256 + 256 + 8192 + 8192 + + + 14 + 34123.6733416 + -20037508.3428 20037508.3428 + 256 + 256 + 16384 + 16384 + + + 15 + 17061.8366708 + -20037508.3428 20037508.3428 + 256 + 256 + 32768 + 32768 + + + 16 + 8530.91833540 + -20037508.3428 20037508.3428 + 256 + 256 + 65536 + 65536 + + + 17 + 4265.45916770 + -20037508.3428 20037508.3428 + 256 + 256 + 131072 + 131072 + + + 18 + 2132.72958385 + -20037508.3428 20037508.3428 + 256 + 256 + 262144 + 262144 + + + 19 + 1066.36479193 + -20037508.3428 20037508.3428 + 256 + 256 + 524288 + 524288 + + + 20 + 533.18239597 + -20037508.3428 20037508.3428 + 256 + 256 + 1048576 + 1048576 + + + + google3857_0-17 + + 977650 5838030 + 1913530 6281290 + + urn:ogc:def:crs:EPSG:6.18.3:3857 + urn:ogc:def:wkss:OGC:1.0:GoogleMapsCompatible + + 0 + 559082264.029 + -20037508.3428 20037508.3428 + 256 + 256 + 1 + 1 + + + 1 + 279541132.015 + -20037508.3428 20037508.3428 + 256 + 256 + 2 + 2 + + + 2 + 139770566.007 + -20037508.3428 20037508.3428 + 256 + 256 + 4 + 4 + + + 3 + 69885283.0036 + -20037508.3428 20037508.3428 + 256 + 256 + 8 + 8 + + + 4 + 34942641.5018 + -20037508.3428 20037508.3428 + 256 + 256 + 16 + 16 + + + 5 + 17471320.7509 + -20037508.3428 20037508.3428 + 256 + 256 + 32 + 32 + + + 6 + 8735660.37545 + -20037508.3428 20037508.3428 + 256 + 256 + 64 + 64 + + + 7 + 4367830.18773 + -20037508.3428 20037508.3428 + 256 + 256 + 128 + 128 + + + 8 + 2183915.09386 + -20037508.3428 20037508.3428 + 256 + 256 + 256 + 256 + + + 9 + 1091957.54693 + -20037508.3428 20037508.3428 + 256 + 256 + 512 + 512 + + + 10 + 545978.773466 + -20037508.3428 20037508.3428 + 256 + 256 + 1024 + 1024 + + + 11 + 272989.386733 + -20037508.3428 20037508.3428 + 256 + 256 + 2048 + 2048 + + + 12 + 136494.693366 + -20037508.3428 20037508.3428 + 256 + 256 + 4096 + 4096 + + + 13 + 68247.3466832 + -20037508.3428 20037508.3428 + 256 + 256 + 8192 + 8192 + + + 14 + 34123.6733416 + -20037508.3428 20037508.3428 + 256 + 256 + 16384 + 16384 + + + 15 + 17061.8366708 + -20037508.3428 20037508.3428 + 256 + 256 + 32768 + 32768 + + + 16 + 8530.91833540 + -20037508.3428 20037508.3428 + 256 + 256 + 65536 + 65536 + + + 17 + 4265.45916770 + -20037508.3428 20037508.3428 + 256 + 256 + 131072 + 131072 + + + + + diff --git a/test/spec/ol/source/wmts.test.js b/test/spec/ol/source/wmts.test.js index 5c729455b0..6b3a69acca 100644 --- a/test/spec/ol/source/wmts.test.js +++ b/test/spec/ol/source/wmts.test.js @@ -406,7 +406,56 @@ describe('ol.source.WMTS', function () { expectDelta(extent[3], 90); }); }); + describe('when creating options from wgs84 capabilities with BoundingBox', function () { + const parser = new WMTSCapabilities(); + let capabilities; + before(function (done) { + afterLoadText( + 'spec/ol/format/wmts/capabilities_wgs84_with_boundingbox.xml', + function (xml) { + try { + capabilities = parser.read(xml); + } catch (e) { + done(e); + } + done(); + } + ); + }); + it('returns correct bounding box when the layer has BoundingBox', function () { + const options = optionsFromCapabilities(capabilities, { + layer: 'bmaphidpi', + matrixSet: 'google3857', + style: 'normal', + }); + + expect(options.layer).to.be.eql('bmaphidpi'); + + expect(options.matrixSet).to.be.eql('google3857'); + + expect(options.format).to.be.eql('image/jpeg'); + + expect(options.requestEncoding).to.be.eql('REST'); + + expect(options.tileGrid).to.be.a(WMTSTileGrid); + expect(options.style).to.be.eql('normal'); + + expect(options.projection).to.be.a(Projection); + expect(options.projection).to.be.eql(getProjection('EPSG:3857')); + + const expectedMatrixSetExtend = [977650, 5838030, 1913530, 6281290]; + const extent = options.tileGrid.getExtent(); + + // compare with delta, due to rounding not the exact bounding box is returned... + const expectDelta = (value, expected) => + expect(Math.abs(value - expected)).to.below(1e-1); + expectDelta(extent[0], expectedMatrixSetExtend[0]); + expectDelta(extent[1], expectedMatrixSetExtend[1]); + expectDelta(extent[2], expectedMatrixSetExtend[2]); + expectDelta(extent[3], expectedMatrixSetExtend[3]); + }); + }); describe('when creating options from capabilities with TileMatrixSetLink', function () { const parser = new WMTSCapabilities(); let capabilities;