前言
最近,碰到了需求,想要在高德 sdk 中使用在 geoserver 里面發布的瓦片地圖。
還好經過一番研究,在其官方文檔中發現,從新版本(v1.4.3開始)的高德 sdk 開始,已經支持加載第三方 wms/wmts 服務了。
為了測試一下是否能用,我們先將官方的示例拷貝過來試一試。
wms 服務
先試試 wms 服務加載:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/wms",
blend: false,
tileSize: 512,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
},
});
wms.setMap(map);
運行起來,你會發現,成功加載了 topp:states 這張矢量地圖:
wmts 服務
再試試官方示例的 wmts 服務加載:
var wms = new AMap.TileLayer.WMTS({
url:"https://services.arcgisonline.com/arcgis/rest/services/Demographics/USA_Population_Density/MapServer/WMTS/",
blend: false,
tileSize: 256,
params: { Layer: "0", Version: "1.0.0", Format: "image/png" },
});
wms.setMap(map);
你會發現,也可以成功加載:
但是仔細研究這個示例,你會發現,官方提供的 wmts 服務是加載的 arcgis 提供的瓦片服務。
gwc 方式
我們知道,geoserver 僅提供 gwc 方式來訪問 wmts 服務,并且使用 gwc 方式,還能提高瓦片的訪問速率。
所以接下來我們研究一下,是否可以在高德 sdk 中,采用 geoserver 提供的 gwc 方式訪問 wms 和 wmts 服務。
首先,研究一下 wms 方式,改一下之前的代碼:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/gwc/service/wms", // 改為 gwc 方式
blend: false,
tileSize: 512,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
},
});
再次運行,發現并沒有成功加載圖層,打開控制臺,看一下相關請求,可以發現會返回如下錯誤:
經過一番排查,發現參數里缺少了一個參數 SRS: "EPSG:3857"
,添加上以后,再次嘗試:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/gwc/service/wms",
blend: false,
tileSize: 512,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
SRS: "EPSG:3857",
},
});
wms.setMap(map);
發現還是有問題:
瓦片大小對應不上,更改以后,再次嘗試:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/gwc/service/wms",
blend: false,
tileSize: 256,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
SRS: "EPSG:3857",
},
});
wms.setMap(map);
發現可以成功加載。
那 wmts 的方式呢?
調整代碼如下:
var wms = new AMap.TileLayer.WMTS({
url: "https://ahocevar.com/geoserver/gwc/service/wmts",
blend: false,
tileSize: 256,
params: { Layer: "topp:states", Version: "1.0.0", Format: "image/png" },
});
wms.setMap(map);
再次運行,發現不能正確獲取到瓦片,提示如下錯誤:
發現提示請求的參數不正確,但是高德 sdk 官方文檔里明確說了,不要添加 tilematrixset
等參數:
因此可以得出結論,對于 geoserver 的 gwc 方式,高德 sdk 僅支持 wms 服務,不支持 wmts 服務。
結論
如果想要在高德地圖中加載 geoserver 發布的瓦片地圖服務,得用 wms 的方式,使用方式如下:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/wms",
blend: false,
tileSize: 512,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
},
});
wms.setMap(map);
或者 gwc 方式:
var wms = new AMap.TileLayer.WMS({
url: "https://ahocevar.com/geoserver/gwc/service/wms",
blend: false,
tileSize: 256,
params: {
LAYERS: "topp:states",
VERSION: "1.3.0",
SRS: "EPSG:3857",
},
});
wms.setMap(map);
如果要用 wmts 服務,得用 arcgis 發布的瓦片服務。由于博主也沒用過,這里就不過多的涉及了。
如果你非要在高德 sdk 中使用 geoserver 提供的 wmts 服務,也不是沒有方法。
你必須得修改 AMap.TileLayer.WMTS
這個類的源碼才行,但是由于高德 sdk 并不開源,因此修改起來非常的困難,一般情況下建議直接放棄即可。
其實在高德 sdk 中加載第三方瓦片服務,還存在一個問題,因為高德地圖用的是火星坐標系,因此與根據通用的 wgs84 坐標系生成的地圖比,會存在偏差。
比如,下面,是我在高德 sdk 中疊加的我在 geoserver 中發布的影像圖,我發布的影像圖是未經過加密的,坐標系未 ESPG4326。
可以看到,當我選取了江蘇常州的奧林匹克體育中心這一塊,就會發現瓦片地圖中奧林匹克體育中心的位置,與高德地圖中的位置偏差了很多。
因此想要同時在高德底圖上,疊加標準的第三方瓦片圖,看起來并不現實。
雖然高德 sdk 提供了坐標轉換的接口,但是我們想要實現糾偏,同樣得改源碼才能實現。
但是還是同樣的問題,高德 sdk 并不開源,想要改源碼,著實太困難,并且,對應的接口,也沒有提供實現糾偏的參數或者方法。
其實還有一種方式,就是我們發布一張,火星坐標系的影像圖。但是這更不可能,因為火星坐標系,由于保密需要,其設置偏移的時候,并不是采用一種公開的算法,而是隨機加入偏移,想要保持與高德地圖一致,得把我們的圖發給高德 sdk 官方的人處理才行。
因此,總結一下,在高德地圖 sdk 中加載 geoserver 發布的第三方影像圖,確實能加載成功,但是目前不建議使用,除非接下來官方提供了標準地圖糾偏相關的方案。