OpenLayers очень низкая производительность, когда WMTS GetCapabilities TileMatrixSet не отображает TileMatrix низкого уровня масштабирования

#openlayers #geoserver #ogc

#openlayers #geoserver #ogc

Вопрос:

Работает на старой версии 6.4.3

Я взаимодействую с сервисом WMTS, у которого есть TileMatrixSet, подобный этому:

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

Затем в нем перечислены TileMatrix, которые соответствуют уровню масштабирования 11, хотя и 18.

Пример:

 <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 отсутствуют. Это кажется необычным. Что openlayers, похоже, пытается сделать при уменьшении масштаба от 0 до 10, так это заполнить экран плитками с уровня масштабирования 11. Это тысячи плиток при уровне масштабирования 0. Это чрезвычайно обременительно для процессора браузера. Странно то, что это серьезное налогообложение происходит, даже если ows:WGS84BoundingBox определено в GetCapabilities для вышеупомянутого сервиса / уровня. Возможно, openlayers выполняет небольшую математику для всех этих тысяч плиток, возможно, чтобы определить, находится ли эта плитка в пределах ограничивающей рамки. Openlayers не выполняет сетевой запрос за пределами ows:WGS84BoundingBox . Если он находится внутри, он запрашивает уровень масштабирования 11 и отображается на карте, как ожидалось. Основной проблемой здесь является загрузка процессора. Я не беспокоюсь о чрезмерном обложении сервиса большим количеством запросов.

Я могу устранить эту проблему, установив для свойства minzoom для слоя карты значение 11 с помощью setMinZoom() . Однако я не знаю отличного способа определить, что минимальный масштаб должен быть 11. В TileMatrixSet ows:Identifier не гарантируется соответствие уровню масштабирования. Я думаю, это просто название. Должен ли я использовать знаменатель масштаба для выполнения небольшой математики?

Тем не менее, я также не особенно хочу, чтобы данные исчезали при увеличении ниже уровня масштабирования 11. Обратите внимание, что для вышеупомянутого сервиса / слоя при уровне масштабирования 11 данные помещаются в одну плитку размером 256×256. Я полагаю, я мог бы вычесть примерно 2 уровня масштабирования по своему вкусу: layer.setMinZoom(max(0,min_zoom_available-2)) .

Я считаю, что один из способов воспроизвести большую нагрузку на процессор для себя, взять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 сервис в коде примера является глобальным. Возможно, вы могли бы как-то изменить степень.

Если ответ заключается в том, что мне нужно нажать на поставщика услуг за несоответствие спецификации / стандарту, это приемлемый ответ. Особенно, если я могу разместить такой стандарт. Или, если есть свойство GetCapabilities, поставщик услуг может установить, что openlayers (или мой код приложения) могут читать, чтобы установить minzoom, я думаю, что это также было бы приемлемым ответом.

Ответ №1:

Было бы проще установить maxResolution вместо minZoom

Если вы используете optionsFromCapabilities, вы можете получить максимальное разрешение, используемое в сетке плиток

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

умножьте на 2 или 4, если вы хотите, чтобы он был превышен на 1 или 2 дополнительных уровня масштабирования

Комментарии:

1. Это работает, если набор матриц равен 3857, но не работает должным образом, если он равен 4326. Есть идеи для этого случая? Я могу получить минимальное масштабирование из options.TileGrid.getFullTileRange (0), и это, похоже, работает для любых CRS.