openlayers中 使用 wgs84的 wms 服務 適配 gcj02的底圖

國內的地圖服務都必須經過至少一次加密 常見的地圖座標系比如 gcj02 bd09

國外的地圖有wgs84的 但是錯誤很多 帶有不懷好意的標註和國界線

使用不當會在工作中給自己和公司帶來不小的麻煩和誤解

發佈的wms服務 如果要適配 gcj02的地圖 最優解 是把wms服務也設計成 gcj02的數據  這樣就不會產生偏移

但如果初始設計爲wgs84 而且不易修改後 我們可以通過將wms服務進行 一定的適配工作

核心思路就是wms服務進行獲取數據時重新設置 BBOX參數

核心代碼

function WMSTileLoadFunction(imageTile, src) {
            let srcs = src.split('?')
            let q = decodeURIComponent(srcs[1])
            let url = srcs[0] + '?'
            let arrs = getUrlVariable(q)
            let bbox = arrs['BBOX'].split(',')
            let a = coordtransform.gcj02towgs84(bbox[0], bbox[3])
            let b = coordtransform.gcj02towgs84(bbox[2], bbox[1])
            arrs['BBOX'] = a[0] + ',' + b[1] + ',' + b[0] + ',' + a[1]
            imageTile.getImage().src = url + urlEncode(arrs)
        }

首先是獲取 wms的服務圖層

這裏需要關注  projection: 'EPSG:4326',  設置爲 4326 就是wgs84座標 方便後面進行 wgs84到 gcj02的轉換

另一個就是   tileLoadFunction: WMSTileLoadFunction 這個是爲了實現請求的url重寫


        new ol.layer.Tile({
            visible: true,
            source: new ol.source.TileWMS({
                url: 'wms服務',
                params: {
                    'FORMAT': 'image/png8',
                    'VERSION': '1.1.1',
                    tiled: true, // 使用瓦片圖
                    STYLES: 'static', // 使用的樣式
                    "LAYERS": '', // 使用的圖層
                    "exceptions": 'application/vnd.ogc.se_inimage',
                    // 自定義參數
                    'viewparams': viewparams
                },
                projection: 'EPSG:4326',
                tileLoadFunction: WMSTileLoadFunction
            }),
        });

WMSTileLoadFunction 函數

獲取 目前的請求url 最後 替換 請求的url  imageTile.getImage().src = url + urlEncode(arrs)

首先是 獲取 url裏的 參數  let arrs = getUrlVariable(q)

然後獲取原先的bbox進行轉換 

let bbox = arrs['BBOX'].split(',')
let a = coordtransform.gcj02towgs84(bbox[0], bbox[3])
let b = coordtransform.gcj02towgs84(bbox[2], bbox[1])
最後重寫bbox   arrs['BBOX'] = a[0] + ',' + b[1] + ',' + b[0] + ',' + a[1]
function WMSTileLoadFunction(imageTile, src) {
            let srcs = src.split('?')
            let q = decodeURIComponent(srcs[1])
            let url = srcs[0] + '?'
            let arrs = getUrlVariable(q)
            let bbox = arrs['BBOX'].split(',')
            let a = coordtransform.gcj02towgs84(bbox[0], bbox[3])
            let b = coordtransform.gcj02towgs84(bbox[2], bbox[1])
            arrs['BBOX'] = a[0] + ',' + b[1] + ',' + b[0] + ',' + a[1]
            imageTile.getImage().src = url + urlEncode(arrs)
        }

其他:

let q = decodeURIComponent(srcs[1])  解碼url

獲取url中 參數的函數

 

function getUrlVariable(q) {
            // 獲取url中的參數
            let vars = q.split("&");
            // let arrs = new Array()
            let arrs = {}
            for (let i = 0; i < vars.length; i++) {
                let pair = vars[i].split("=");
                arrs[pair[0]] = pair[1];
            }
            return arrs;
        }

將對象轉換爲url:

function urlEncode(param, key, encode) {
            if (param == null) return '';
            var paramStr = '';
            var t = typeof (param);
            if (t == 'string' || t == 'number' || t == 'boolean') {
                paramStr += '&' + key + '=' + ((encode == null || encode) ? encodeURIComponent(param) : param);
            } else {
                for (var i in param) {
                    var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '.' + i);
                    paramStr += urlEncode(param[i], k, encode);
                }
            }
            return paramStr;
        };

底圖:

new ol.layer.Tile({
            source: new ol.source.XYZ({
                url: 'http://map.geoq.cn/arcgis/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}'
            }),
        })

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章