arcgis瓦片通过gwc插件发布后,penlayers调用出现tileCol与tileRow范围计算不对的问题

下好的瓦片文件(我下了11-17级),文件的组织其实是按照瓦片的级别、行、列号来组织的。
WMS请求中由Bbox的参数控制(BBOX=139.5703125%2C-50.262451171875%2C156.4453125%2C-35.474853515625),包含了最小x、最小y、最大x、最大y信息;WMTS请求中由TILEMATRIX、TILEROW、TILECOL这三个参数控制,代表的是瓦片的级别、行、列号(TileMatrix=EPSG%3A3857_tumen_gaode_map:4&TileCol=28203&TileRow=12044))。

怎么控制地图客户端对不同级别、不同行、列的瓦图访问呢?
计算原理参考

现有写的通用的计算瓦片TileMatrix、TileCol、TileRow如下:

var lev = 20;
jilinMapTile:function(){
	 	//对应瓦片的投影坐标
        var projection = ol.proj.get('EPSG:3857');
        //该投影坐标的全图范围[-20037508.342789244, -20037508.342789244, 20037508.342789244, 20037508.342789244]
        var projectionExtent = projection.getExtent();
        //如果把该投影的所有范围都放到宽256像素的图幅里,屏幕上一像素等于实际中size长(156543.03392804097m,即比例尺*每个像素的屏幕长度)
        var size = ol.extent.getWidth(projectionExtent) / 256;
        //resolutions是切片方案信息,这里有20个级别的切片,地图屏幕上1像素代表的实际距离是resolution
        var resolutions = new Array(lev);
        var matrixIds = new Array(lev);
        for (var z = 0; z < lev; z++) {
            resolutions[z] = size / Math.pow(2, z);
            matrixIds[z] = "EPSG:3857_jilinMap:"+z;
        }
        // var map = new ol.Map({
        //     layers: [
                var layer = new ol.layer.Tile({
                    opacity: 1,
                    id:"gaode",
                    source: new ol.source.WMTS({
                        url: 'http://122.137.242.12:7881/geowebcache/service/wmts?',
                        layer: 'jilinMap',
                        matrixSet: 'EPSG:3857_jilinMap',
                        format: 'image/png',
                        projection: projection,
                        tileGrid: new ol.tilegrid.WMTS({
                            origin: ol.extent.getTopLeft(projectionExtent),
                            resolutions: resolutions,
                            matrixIds: matrixIds
                        }),
                        style: 'default',
                        wrapX: true
                    }),
                })
        //     ],
        //     target: 'map',
        //     controls: ol.control.defaults({
        //         attributionOptions: /** @type {olx.control.AttributionOptions} */ ({
        //             collapsible: false
        //         })
        //     }),
        //     view: new ol.View({
        //         center: ol.proj.transform([126.579, 43.812], 'EPSG:4326', 'EPSG:3857'),
        //         projection: 'EPSG:3857',
        //         zoom: 12
        //     })
        // });
        return layer;
    },

计算不当会出现Unknown TILEMATRIXColumn xx is out of range的报错。

Unknown TILEMATRIX是因为瓦片的级别没设置对。
比如我下了7个级别,lev就应该是7。

Column xx is out of range是因为行列号没有计算对。
debug时发现resolutions的值是:

0: 156543.03392804097
1: 78271.51696402048
2: 39135.75848201024
3: 19567.87924100512
4: 9783.93962050256
5: 4891.96981025128
6: 2445.98490512564

而我发布的瓦片文件里切片信息是这样的:

<LODInfos xsi:type="typens:ArrayOfLODInfo">
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>0</LevelID>
                <Scale>288895.27714399999</Scale>
                <Resolution>76.437028285073239</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>1</LevelID>
                <Scale>144447.638572</Scale>
                <Resolution>38.21851414253662</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>2</LevelID>
                <Scale>72223.819285999998</Scale>
                <Resolution>19.10925707126831</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>3</LevelID>
                <Scale>36111.909642999999</Scale>
                <Resolution>9.5546285356341549</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>4</LevelID>
                <Scale>18055.954822</Scale>
                <Resolution>4.7773142679493699</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>5</LevelID>
                <Scale>9027.9774109999998</Scale>
                <Resolution>2.3886571339746849</Resolution>
            </LODInfo>
            <LODInfo xsi:type="typens:LODInfo">
                <LevelID>6</LevelID>
                <Scale>4513.9887049999998</Scale>
                <Resolution>1.1943285668550503</Resolution>
            </LODInfo>

LevelID本该是11到17,但通过gwc服务发布报错,显示400,就按这里改了

显然对不上,resolutions的值需要这样才对:

0: 76.43702828517625
1: 38.21851414258813
2: 19.109257071294063
3: 9.554628535647032
4: 4.777314267823516
5: 2.388657133911758
6: 1.194328566955879

按照现有的算法算下来,lev=20,如下:

0: 156543.03392804097
1: 78271.51696402048
2: 39135.75848201024
3: 19567.87924100512
4: 9783.93962050256
5: 4891.96981025128
6: 2445.98490512564
7: 1222.99245256282
8: 611.49622628141
9: 305.748113140705
10: 152.8740565703525
11: 76.43702828517625
12: 38.21851414258813
13: 19.109257071294063
14: 9.554628535647032
15: 4.777314267823516
16: 2.388657133911758
17: 1.194328566955879
18: 0.5971642834779395
19: 0.29858214173896974

算法里的循环需要作以下修改即可:

        for (var z = 11; z < 18; z++) {
            resolutions[z] = size / Math.pow(2, z);
            matrixIds[z] = "EPSG:3857_jilinMap:"+(z-11);
        }

总体来说,就是下载的瓦片文件里配置的分片信息与openlayers里的resolutions应该对的上。

posted @ 2020-05-14 15:50  cashew  阅读(2758)  评论(0编辑  收藏  举报