Openlayers3:使用 Geoserver/Geowebcache 作为后端,pixelratio=3 的瓷砖网格不正确
Openlayers3: tile grid incorrect with pixelratio=3 using Geoserver/Geowebcache as backend
我正在使用 Openlayers3 和 geoserver/geowebcache 作为后端开发一个小型网络地图。
我的目标是支持 browsers/displays pixelratio=1、pixelratio=2 和 pixelratio=3。
为此,我在 geoserver 后端定义了 3 个网格集,瓦片尺寸分别为 256x256、512x512 和 768x768。
我假设:
- pixelratio=1 需要 tile 大小为 256x256 的网格集
- pixelratio=2 需要 tile 大小为 512x512 的网格集
- pixelratio=3 需要 tile 尺寸为 768x768 的网格集
现在,我的代码仅适用于 pixelratio=1 和 pixelratio=2。
但是如果pixelratio=3 geowebcache returns 报错:
geowebcache-cache-result:MISS
geowebcache-miss-reason:request does not align to grid(s) 'grid_512' 'grid_768' 'grid_256'
如果pixelratio=3 Openlayers生成这样一个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,但显然没有正确计算网格。
Geoserver 中的演示地图(基于 Openlayers2)适用于所有 3 个网格集。
我正在使用 geoserver 2.10 和 google chrome。
到目前为止,这是我的代码。后端的所有 3 个网格集的分辨率和边界都相同。感谢任何帮助:
<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>
您的代码存在一些问题,可能是罪魁祸首:
projection
必须在 ol.source.TileWMS
实例上配置,而不是在 ol.layer.Tile
. 上配置
- 要限制
ol.layer.Tile
的范围,请使用 extent
选项,而不是 extend
。
修复以上两个 可能 使您的应用程序正常工作,但有一些注意事项:
当您想要确保始终使用缓存的图块时,您必须将应用程序限制为特定的像素比率。在您的情况 1、2 和 3 中。当使用 ol.source.TileWMS
并配置选项 serverType: 'geoserver'
时,将始终使用精确的设备像素比发出请求,也可以是 1.33、1.5、6 或更多您没有磁贴的其他不同值。
要解决此问题,您需要使用 tilePixelRatio
配置源,而不是使用 serverType
选项 - 如果您继续使用 WMS。 tilePixelRatio
可以这样计算:
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,事情看起来像这样:
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_256
、grid_512
和 grid_768
,并且都使用相同的图块矩阵集。所以它们仅在像素宽度和高度上有所不同(256、512 和 768)。
我正在使用 Openlayers3 和 geoserver/geowebcache 作为后端开发一个小型网络地图。
我的目标是支持 browsers/displays pixelratio=1、pixelratio=2 和 pixelratio=3。
为此,我在 geoserver 后端定义了 3 个网格集,瓦片尺寸分别为 256x256、512x512 和 768x768。 我假设:
- pixelratio=1 需要 tile 大小为 256x256 的网格集
- pixelratio=2 需要 tile 大小为 512x512 的网格集
- pixelratio=3 需要 tile 尺寸为 768x768 的网格集
现在,我的代码仅适用于 pixelratio=1 和 pixelratio=2。 但是如果pixelratio=3 geowebcache returns 报错:
geowebcache-cache-result:MISS
geowebcache-miss-reason:request does not align to grid(s) 'grid_512' 'grid_768' 'grid_256'
如果pixelratio=3 Openlayers生成这样一个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,但显然没有正确计算网格。
Geoserver 中的演示地图(基于 Openlayers2)适用于所有 3 个网格集。
我正在使用 geoserver 2.10 和 google chrome。 到目前为止,这是我的代码。后端的所有 3 个网格集的分辨率和边界都相同。感谢任何帮助:
<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>
您的代码存在一些问题,可能是罪魁祸首:
projection
必须在ol.source.TileWMS
实例上配置,而不是在ol.layer.Tile
. 上配置
- 要限制
ol.layer.Tile
的范围,请使用extent
选项,而不是extend
。
修复以上两个 可能 使您的应用程序正常工作,但有一些注意事项:
当您想要确保始终使用缓存的图块时,您必须将应用程序限制为特定的像素比率。在您的情况 1、2 和 3 中。当使用 ol.source.TileWMS
并配置选项 serverType: 'geoserver'
时,将始终使用精确的设备像素比发出请求,也可以是 1.33、1.5、6 或更多您没有磁贴的其他不同值。
要解决此问题,您需要使用 tilePixelRatio
配置源,而不是使用 serverType
选项 - 如果您继续使用 WMS。 tilePixelRatio
可以这样计算:
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,事情看起来像这样:
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_256
、grid_512
和 grid_768
,并且都使用相同的图块矩阵集。所以它们仅在像素宽度和高度上有所不同(256、512 和 768)。