本文介绍了Openlayers3:使用Geoserver/Geowebcache作为后端时,tiler grid不正确,pixelratio = 3的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Openlayers3和geoserver/geowebcache作为后端来开发一个小型Webmap.

I'm developing a small webmap using Openlayers3 and geoserver/geowebcache as backend.

我的目标是支持Pixelratio = 1,pixelratio = 2和pixelratio = 3的浏览器/显示器.

My goal is to support browsers/displays with pixelratio=1, pixelratio=2 and pixelratio=3.

为此,我在geoserver后端中定义了3个栅格集,其瓦片大小分别为256x256、512x512和768x768.我认为:

For that I defined in geoserver backend 3 gridsets with tiles sizes 256x256, 512x512 and 768x768.I assume that:

  • pixelratio = 1需要一个图块尺寸为256x256的网格集
  • pixelratio = 2需要一个图块大小为512x512的网格集
  • pixelratio = 3需要一个图块尺寸为768x768的网格集

现在,我的代码仅适用于pixelratio = 1和pixelratio = 2.但是,如果pixelratio = 3 geowebcache返回错误:

Now, my code is working only for pixelratio=1 and pixelratio=2.But if pixelratio=3 geowebcache returns a error:

geowebcache-cache-result:MISS
geowebcache-miss-reason:request does not align to grid(s) 'grid_512' 'grid_768' 'grid_256'

如果pixelratio = 3 Openlayers会生成这样的URL:

If pixelratio=3 Openlayers generates such a URL:

http://localhost:8082/wms?SERVICE=WMS&VERSION=1.1.1&REQUEST=GetMap&FORMAT=image%2Fpng&TRANSPARENT=false&layers=mfn_mwb17%3Amfn_mwb17_0_basemap&TILED=true&WIDTH=768&HEIGHT=768&SRS=EPSG%3A32632&STYLES=&FORMAT_OPTIONS=dpi%3A270&BBOX=536964.8438079988%2C5280880.182948656%2C537609.9638079988%2C5281525.3029486565

Openalayers将图块大小更改为768x768,将DPI更改为270,但显然不能正确计算网格.

Openalayers changes the tiles sizes to 768x768 and DPI to 270 but apparently does not calculate correctly the grid.

Geoserver(基于Openlayers2)中的演示地图可用于所有3个网格集.

The demo map in Geoserver (based on Openlayers2) works with all 3 grid sets.

我正在使用geoserver 2.10和google chrome.到目前为止,这是我的代码.后端中所有3个网格集的分辨率和界限都相同.任何帮助表示赞赏:

I'm using geoserver 2.10 and google chrome.This is my code so far. Resolutions and bounds are the same for all 3 grid sets in backend. Any help is appreciated:

<html>
<head>
    <title>WMS Tiles</title>
    <link rel="stylesheet" href="https://openlayers.org/en/v3.19.1/css/ol.css" type="text/css">
    <!-- The line below is only needed for old environments like Internet Explorer and Android 4.x -->
    <script src="https://cdn.polyfill.io/v2/polyfill.min.js?features=requestAnimationFrame,Element.prototype.classList,URL"></script>
    <script src="https://openlayers.org/en/v3.19.1/build/ol.js"></script>
</head>
<body>
<div id="map" class="map"></div>
<script>
    console.log("DOMContentLoaded");
    try {
        var config = {
            "bounds": {
                "left": 536319.7238079988,
                "bottom": 5278944.822948656,
                "right": 540150.3790103362,
                "top": 5282223.663765706
            }
        };

        var bounds = [config.bounds.left, config.bounds.bottom, config.bounds.right, config.bounds.top];
        var resolutions = [2.5199999999999996,
            1.2599999999999998,
            0.6299999999999999,
            0.31499999999999995,
            0.15749999999999997,
            0.07874999999999999,
            0.03937499999999999
        ];

        var projection = new ol.proj.Projection({
            code: 'EPSG:32632'
        });

        var params = {
            'VERSION': '1.1.1',
            'layers': "mfn_mwb17:mfn_mwb17_0_basemap",
            'TILED': true,
            'TRANSPARENT': false
        };

        var tileGrid = new ol.tilegrid.TileGrid({
            extent: bounds,
            resolutions: resolutions,
            origin: [config.bounds.left, config.bounds.bottom],
            tileSize: [256, 256]
        });
        var view = new ol.View({
            zoom: 0,
            center: ol.extent.getCenter(bounds),
            projection: projection,
            resolutions: resolutions
        });

        var map = new ol.Map({
            controls: ol.control.defaults(
                {
                    rotate: false,
                    attributionOptions: {
                        collapsible: false
                    }
                }
            ),
            view: view,
            layers: [
                new ol.layer.Tile({
                    source: new ol.source.TileWMS({
                        url: "http://localhost:8082/wms",
                        params: params,
                        tileGrid: tileGrid,
                        serverType: 'geoserver'
                    }),
                    projection: projection,
                    extend: bounds
                })
            ],
            target: 'map'
        });
        console.log("no error");
    } catch (error) {
        console.log("error");
        console.log(error);
    }
</script>
</body>
</html>

推荐答案

您的代码中有一些问题可能是罪魁祸首:

There are a few issues with your code that might be the culprit:

  1. projection必须在ol.source.TileWMS实例上配置,而不是在ol.layer.Tile上.
  2. 要限制ol.layer.Tile的范围,请使用extent选项而不是extend.
  1. projection must be configured on the ol.source.TileWMS instance, not on ol.layer.Tile.
  2. To limit the extent of ol.layer.Tile, use the extent option, not extend.

修复以上两个可能可以使您的应用程序正常工作,但有一些警告:

Fixing the above two might make your application work, but there are caveats:

如果要确保始终使用缓存的图块,则必须将应用程序限制为某些像素比率.在您的情况1、2和3中.在配置了选项serverType: 'geoserver'的情况下使用ol.source.TileWMS时,将始终使用精确的设备像素比率发出请求,该比率也可以是1.33、1.5、6或许多其他不同的值您没有瓷砖.

When you want to ensure that cached tiles are always used, you have to limit your application to certain pixel ratios. In your case 1, 2 and 3. When using ol.source.TileWMS with the option serverType: 'geoserver' configured, requests will always be made using the exact device pixel ratio, which can also be 1.33, 1.5, 6, or many other different values that you do not have tiles for.

要解决此问题,您将需要使用tilePixelRatio配置源,而不使用serverType选项-如果您继续使用WMS. tilePixelRatio可以这样计算:

To fix this, you will want to configure your source with a tilePixelRatio instead, and not use the serverType option - if you continue to use WMS. The tilePixelRatio could be calculated like this:

var tilePixelRatio = 1;
if (ol.has.DEVICE_PIXEL_RATIO > 2.5) {
  tilePixelRatio = 3;
} else if (ol.has.DEVICE_PIXEL_RATIO > 1.5) {
  tilePixelRatio = 2;
}

我建议改用TMS或WMTS.对于TMS,情况将如下所示:

I would recommend to use TMS or WMTS instead. For TMS, things would look like this:

var layerName = 'mfn_mwb17:mfn_mwb17_0_basemap';
var gridset = 'grid_' + (tilePixelRatio * 256);
var layer = new ol.layer.Tile({
  extent: bounds,
  source: new ol.source.XYZ({
    projection: 'EPSG:32632',
    tileGrid: tileGrid,
    tilePixelRatio: tilePixelRatio,
    url: '/geoserver/gwc/service/tms/1.0.0/' + layerName +
        '@' + gridset + '@png/{z}/{x}/{-y}.png'
  })
});

以上假设您的网格集分别命名为grid_256grid_512grid_768,并且都使用相同的图块矩阵集.因此,它们的图块宽度和高度只有像素(256、512和768)不同.

The above assumes your gridsets are named grid_256, grid_512 and grid_768, and all use the same tile matrix set. So they only differ in tile width and height in pixels (256, 512 and 768).

这篇关于Openlayers3:使用Geoserver/Geowebcache作为后端时,tiler grid不正确,pixelratio = 3的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-30 02:22