國內的地圖服務都必須經過至少一次加密 常見的地圖座標系比如 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進行轉換
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}'
}),
})