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