当 WMTS getCapabilities TileMatrixSet 未列出低缩放级别 TileMatrix 时,OpenLayers 性能非常差

OpenLayers very poor performance when WMTS getCapabilities TileMatrixSet does not list low zoom level TileMatrix's

运行OL版本6.4.3

我正在与具有 TileMatrixSet 的 WMTS 服务交互:

<TileMatrixSet>
  <ows:Title>GoogleMapsCompatible</ows:Title>
  <ows:Abstract>GoogleMapsCompatible EPSG:3857</ows:Abstract>
  <ows:Identifier>GoogleMapsCompatible</ows:Identifier>
  <ows:SupportedCRS>urn:ogc:def:crs:EPSG::3857</ows:SupportedCRS>

然后列出对应于缩放级别 11 到 18 的 TileMatrix。

示例:

<TileMatrix>
  <ows:Identifier>11</ows:Identifier>
  <ScaleDenominator>272989.38673277345</ScaleDenominator>
  <TopLeftCorner>-20037508.34278925 20037508.34278925</TopLeftCorner>
  <TileWidth>256</TileWidth>
  <TileHeight>256</TileHeight>
  <MatrixWidth>2048</MatrixWidth>
  <MatrixHeight>2048</MatrixHeight>
</TileMatrix>

就像我说的那样,只列出了 11 到 18,因此缺少 0-10。这似乎不寻常。当缩小到 0 到 10 之间时,openlayers 似乎试图做的是用缩放级别 11 的图块填充屏幕。在缩放级别 0 时有数千个图块。这对浏览器来说非常费力 CPU .奇怪的是,即使在上述 service/layer 的 getCapabilities 中定义了 ows:WGS84BoundingBox,也会发生这种沉重的负担。也许 openlayers 正在对所有数千个图块执行一些数学运算,也许是为了确定该图块是否在边界框内。 Openlayers 不在 ows:WGS84BoundingBox 之外执行网络请求。如果在范围内,它会请求缩放级别 11 并按预期显示在地图上。这里的主要问题是 CPU 征税。我不担心因大量请求而对服务过度征税。

我可以通过使用 setMinZoom() 将地图层的最小缩放 属性 设置为 11 来消除这个问题。但是,我不知道确定 minzoom 应该是 11 的好方法。在 TileMatrixSet 中,ows:Identifier 不能保证等同于缩放级别。这只是我认为的一个名字。我应该使用比例分母来做一点数学吗?

也就是说,我也不是特别希望数据在缩放级别 11 以下时消失。请注意,对于上述 service/layer,在缩放级别 11 时,数据适合一个 256x256 的图块。我想我可以根据自己的喜好减去大约 2 个缩放级别:layer.setMinZoom(max(0,min_zoom_available-2)).

我相信有一种方法可以重现 CPU 对自己造成的巨大负担,采用 https://openlayers.org/en/latest/examples/wmts.html 并将第 14-16 行修改为:

var resolutions = new Array(4);
var matrixIds = new Array(4);
for (var z = 10; z < 14; ++z) {

然后缩小以降低缩放级别。这不会模拟确切的场景,因为示例代码中的 Demographics/USA_Population_Density 服务是全局的。也许您可以以某种方式修改范围。

如果答案是我需要拒绝服务提供商不满足 spec/standard,那是可以接受的答案。特别是如果我能找到这样的标准。或者如果有 getCapabilities 属性 服务提供商可以设置 openlayers(或我的应用程序代码)可以读取以设置 minzoom,我认为这也是一个可以接受的答案。

设置 maxResolution 而不是 minZoom 会更容易

如果您使用 optionsFromCapabilities,您可以获得瓦片网格中使用的 maxResolution

        var source = new ol.source.WMTS(options);
        var layer = new ol.layer.Tile({
            source: source,
            maxResolution: options.tileGrid.getResolution(0)
        });

如果你想让它超过 1 或 2 个额外的缩放级别,则乘以 2 或 4