一、寫在前面
在項(xiàng)目中往往使用地圖作為底圖(比如 天地圖衛(wèi)星圖等),再其上覆蓋你的通過geoserver發(fā)布自定義圖層。本文記錄了我的實(shí)現(xiàn)方法。
二、過程
2.1 我遇到的難題
- 遇到難題1:使用無人機(jī)拍攝制作的正射影像圖有幾百M(fèi)B甚至1個(gè)G,直接展示圖片方式會(huì)很卡頓。我的解決方法是,使用geoserver作為 GIS 地圖服務(wù),發(fā)布 GEO TIFF 圖層,再在Openlayers 中展示。
- 遇到難題2:geoserver 默認(rèn)未開啟跨域支持,需要修改web.xml配置文件開啟跨域支持。
- 遇到難題3:坐標(biāo)系問題,無人機(jī)拍攝制作的正射影像圖 是EPSG:4326 坐標(biāo)系的,要注意在 geoserver中的選擇這個(gè)配置。配合合適的底圖來使用。
- 遇到難題4:使用什么底圖合適?無人機(jī)拍攝制作的正射影像圖在地圖展示會(huì)很突兀,在衛(wèi)星圖上展示比較合適,我選擇了支持 EPSG:4326 坐標(biāo)系的天地圖
2.2 方法和步驟
整體來說,就是先制作 正射影像圖,發(fā)布成圖層,并在 Web 前端展示的過程。
過程如下圖所示:

制作 正射影像.TIFF 和發(fā)布圖層 的步驟:
1、無人機(jī)飛行 拍攝得到 正射影像照片
2、使用 大疆智圖 生成 正射影像圖.TIF
3、Geoserver 發(fā)布Geo TIFF圖層
使用Geoserver發(fā)布圖層的操作步驟:
1、添加工作區(qū)(工作空間)
2、添加存儲(chǔ)倉庫(數(shù)據(jù)源)并發(fā)布
3、添加圖層
完成后,就可以通過 WMS 服務(wù)來使用圖層了。
WMS服務(wù):Web Map Service,?絡(luò)地圖服務(wù)或者?叫動(dòng)態(tài)地圖服務(wù),是利?具有地理空間位置信息的數(shù)據(jù)制作地圖,其中將地圖定義為地理數(shù)據(jù)的可視化表現(xiàn),能夠根據(jù)?戶的請求,返回相應(yīng)的地圖,包括PNG、GIF、JPEG等柵格形式,或者SVG或者WEB CGM等?量形式。WMS?持HTTP協(xié)議,所?持的操作是由URL決定的。
WMS基礎(chǔ)知識(shí)參考:https://www.osgeo.cn/geoserver-user-manual/services/wms/basics.html
2.3 使用geoserver發(fā)布tif柵格地圖并使用openlayers加載
參考這篇文章:https://code84.com/739653.html
2.4 Geoserver 跨域的解決
我使用 jar 直接啟動(dòng),僅修改 web.xml 即可。
參考這篇文章:https://www.bbsmax.com/A/QV5ZkjyZdy/
2.5 openlayers 作為客戶端框架展示發(fā)布的圖層
參考文章:
openlayers基礎(chǔ)概念和使用:https://zhuanlan.zhihu.com/p/395609503?utm_id=0
openlayers快速開始:https://openlayers.org/doc/quickstart.html
三、我的代碼
完整的代碼參考如下:
import './style.css';
import {Map, View} from 'ol';
import {Tile as TileLayer} from 'ol/layer';
import {Image as ImageLayer} from 'ol/layer';
import OSM from 'ol/source/OSM';
import TileWMS from 'ol/source/TileWMS';
import ImageWMS from 'ol/source/ImageWMS'
import GeoTIFF from "ol/source/GeoTIFF";
import XYZ from "ol/source/XYZ";
var format = 'image/png';
var bounds = [102.98741086512345, 36.05409683075217,
102.9959459772909, 36.063839197733444];
var tiandiKey = '你的天地圖KEY';
var tiandiLayer = new TileLayer({
visible: true,
source: new XYZ({
visible: true,
url: `https://t7.tianditu.gov.cn/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=${tiandiKey}`,
// url: 'https://wprd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&style=7&x={x}&y={y}&z={z}'
}),
maxZoom: 19
});
var untiled = new ImageLayer({
source: new ImageWMS({
ratio: 1,
url: 'http://zyf:8080/geoserver/works/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
"STYLES": '',
"LAYERS": 'works:massif_1667368218555_1',
"exceptions": 'application/vnd.ogc.se_inimage',
}
})
});
var tiled = new TileLayer({
visible: false,
source: new TileWMS({
url: 'http://zyf:8080/geoserver/works/wms',
params: {'FORMAT': format,
'VERSION': '1.1.1',
tiled: true,
"STYLES": '',
"LAYERS": 'works:massif_1667368218555_1',
"exceptions": 'application/vnd.ogc.se_inimage',
tilesOrigin: 102.98741086512345 + "," + 36.05409683075217
}
})
});
const map = new Map({
target: 'map',
layers: [
// new TileLayer({
// source: new OSM()
// }),
tiandiLayer,
untiled,
tiled
],
view: new View({
projection: 'EPSG:4326',
center: [102.98741086512345, 36.05409683075217],
zoom: 2
})
});
map.getView().fit(bounds, map.getSize());
四、參考
https://code84.com/739653.html
https://www.bbsmax.com/A/QV5ZkjyZdy/
https://openlayers.org/doc/quickstart.html