2016-12-07 194 views
1

我正在开发一个使用Openlayers3和geoserver/geowebcache作为后端的小型webmap。Openlayers3:使用Geoserver/Geowebcache作为后端的pixelratio = 3的网格栅格不正确

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

为此,我在geoserver backend 3个网格集中定义了256x256,512x512和768x768的图块。 我假定:

  • pixelratio = 1需要与瓷砖的gridset尺寸256×256
  • pixelratio = 2需要与瓷砖的gridset尺寸512×512
  • pixelratio = 3需要与瓷砖的gridset尺寸768x768

现在,我的代码只适用于pixelratio = 1和pixelratio = 2。 但如果pixelratio = 3 geowebcache返回一个错误:

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和谷歌浏览器。 这是我的代码到目前为止。所有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> 

回答

2

有你的代码的几个问题,可能是罪魁祸首:

  1. projection必须在ol.source.TileWMS实例来配置,而不是ol.layer.Tile
  2. 要限制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' 
    }) 
}); 

以上假设你的gridsets被命名为grid_256grid_512grid_768,并且都使用相同的瓦片矩阵集。所以它们只在像素宽度和高度上有所不同(256,512和768)。

+0

谢谢它的作品! 'tilePixelRatio:tilePixelRatio'取得了诀窍。但现在我使用TMS协议测试相同的东西。我在这里问了一个新问题:http://stackoverflow.com/questions/41056640/geowebcache-openlayers3-with-xyz-source-error-by-zooming-the-map。也许你可以看看。 –