注:當前使用的是 ol 5.3.0 版本,天地圖使用的
key
請到天地圖官網申請,并替換為自己的key
地圖分屏對比在WebGIS
開發中是很常見的功能,和卷簾圖層不一樣的是,分屏對比是在各個地圖中添加相同或者不同的圖層進行對比查看。通過創建多個地圖,在其中任意一個地圖上縮放或者拖動時,其它地圖也進行同樣的操作。常見的分屏模式有二分屏、四分屏、六分屏和八分屏。本節主要介紹加載地圖分屏對比。
1. 創建分屏視圖
在創建地圖函數中需要傳入綁定地圖ID
值,默認創建二分屏,實現偶數地圖加載天地圖矢量底圖,奇數地圖加載天地圖影像底圖。
/*** 創建地圖 * mapId:地圖ID*/
function createMap(mapId) {const num = mapId.replace(/[^d.]/g, "")const layer = num % 2 === 0 ? TDTVecLayer : TDTImgLayerconst vectorMap = new ol.Map({target: mapId,layers: [layer,TDTCvaLayer],view: new ol.View({center: [11421771, 4288300],zoom: 5,worldsWrap: true,minZoom: 1,maxZoom: 20,projection: projection})})return vectorMap
}
2. 地圖分屏操作
地圖分屏操作最主要在于根據分屏數量創建地圖,通過循環創建地圖,并根據位置調整寬高比例,設置地圖樣式為左浮動。并在點擊分屏按鈕時切換按鈕激活樣式,清除銷毀的地圖元素和清空地圖數據。
/*** 地圖分屏操作*/
function mapSplit() {// 二分屏document.getElementById('two').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 2; i++) {// 創建地圖元素const mapId = 'two-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "100%"mapTarget.style.width = "50%"mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 四分屏document.getElementById('four').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 4; i++) {// 創建地圖元素const mapId = 'four-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "50%"mapTarget.style.width = "50%"mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 六分屏document.getElementById('six').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 6; i++) {// 創建地圖元素const mapId = 'six-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = 100 / 3 + "%"mapTarget.style.width = '50%'mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 八分屏document.getElementById('eight').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 8; i++) {// 創建地圖元素const mapId = 'eight-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "25%"mapTarget.style.width = '50%'mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})
}
3. 地圖聯動
地圖聯動原理很簡單,只需要將其它地圖對象的View
設置為目標對象的視圖即可
// 地圖聯動
function mapZoomAndMove() {maps.forEach(map => {maps.forEach(targetMap => {map.setView(targetMap.getView())})})
}
4. 按鈕漸變色
.disable-btn{background-color: #c8e7ff;border-color: #9e9e9e3d;}.no-disable-btn{color: #d1d1d1;background-color: #0167cc;border-color: #fff;&:hover{color:#fff;filter: brightness(110%) opacity(100%);transition: all .5s ease-in;background: linear-gradient(to bottom right, #9a99f1, #0167cc);}&:focus{filter: brightness(120%);transition: all .5s ease-in;background: radial-gradient(circle at center, #9a99f1, #0167cc);}}// 背景色延遲
.tool-bar-item{width: 30px;height: 30px;color: #ffff;cursor: pointer;border-right: 1px solid #f0f4f76b;&:hover{background-color: #248cfba8;transition-delay: .25s;}
}
5. 完整代碼
其中libs
文件夾下的包需要更換為自己下載的本地包或者引用在線資源。
<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>地圖聯動</title><meta charset="utf-8" /><script src="../libs/js/ol-5.3.3.js"></script><script src="../libs/js/jquery-2.1.1.min.js"></script><script src="../libs/proj4.js"></script><link rel="stylesheet" href="../libs/css/ol.css"><style>* {padding: 0;margin: 0;font-size: 14px;font-family: '微軟雅黑';}html,body {width: 100%;height: 100%;}#imageMap {position: absolute;top: 50px;bottom: 0;left: 0;width: 50%;}#vectorMap {position: absolute;top: 50px;bottom: 0;left: 50%;width: 50%;}.split-div {position: absolute;width: 100%;height: 50px;line-height: 50px;background: linear-gradient(135deg, #ff00cc, #ffcc00, #00ffcc, #ff0066);color: #fff;text-align: center;}.split-span {border-radius: 5px;border: 1px solid #50505040;padding: 5px 20px;color: #fff;margin: 0 10px;background: #377d466e;transition: background-color 10s ease-in-out 10s;}.split-span:hover {cursor: pointer;font-size: 1.25em;filter: brightness(120%);background: linear-gradient(135deg, #c850c0, #4158d0);}.active {background: linear-gradient(135deg, #c850c0, #4158d0);}#map-main {position: absolute;top: 50px;bottom: 0;left: 0;right: 0;}.clearfix::after {display: block;content: "";clear: both;}.split-map {float: left;}</style>
</head><body><div class="split-div "><span id="two" class="split-span">二分屏</span><span id="four" class="split-span">四分屏</span><span id="six" class="split-span">六分屏</span><span id="eight" class="split-span">八分屏</span></div><div id="map-main" class="clearfix"></div>
</body></html><script>//地圖投影坐標系const projection = ol.proj.get('EPSG:3857');//==============================================================================////============================天地圖服務參數簡單介紹==============================////================================vec:矢量圖層==================================////================================img:影像圖層==================================////================================cva:注記圖層==================================////======================其中:_c表示經緯度投影,_w表示球面墨卡托投影================////==============================================================================//const TDTImgLayer = new ol.layer.Tile({title: "天地圖影像圖層",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",attibutions: "天地圖注記描述",crossOrigin: "anoymous",wrapX: false})})const TDTCvaLayer = new ol.layer.Tile({title: "天地圖影像注記圖層",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",attibutions: "天地圖注記描述",crossOrigin: "anoymous",wrapX: false})})const TDTVecLayer = new ol.layer.Tile({title: "天地圖影像圖層",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}&tk=2a890fe711a79cafebca446a5447cfb2",attibutions: "天地圖注記描述",crossOrigin: "anoymous",wrapX: false})})/*** 創建地圖 * mapId:地圖ID*/ function createMap(mapId) {const num = mapId.replace(/[^d.]/g, "")const layer = num % 2 === 0 ? TDTVecLayer : TDTImgLayerconst vectorMap = new ol.Map({target: mapId,layers: [layer,TDTCvaLayer],view: new ol.View({center: [11421771, 4288300],zoom: 5,worldsWrap: true,minZoom: 1,maxZoom: 20,projection: projection})})return vectorMap}// 分屏地圖數組let maps = []/*** 默認二分屏*/const mapsContainer = document.getElementById("map-main")for (let i = 0; i < 2; i++) {// 創建地圖元素const mapId = 'two-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "100%"mapTarget.style.width = "50%"mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()/*** 地圖分屏操作*/function mapSplit() {// 二分屏document.getElementById('two').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 2; i++) {// 創建地圖元素const mapId = 'two-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "100%"mapTarget.style.width = "50%"mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 四分屏document.getElementById('four').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 4; i++) {// 創建地圖元素const mapId = 'four-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "50%"mapTarget.style.width = "50%"mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 六分屏document.getElementById('six').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 6; i++) {// 創建地圖元素const mapId = 'six-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = 100 / 3 + "%"mapTarget.style.width = '50%'mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})// 八分屏document.getElementById('eight').addEventListener('click', evt => {toogleAciveClass(evt.target)maps = []removeChildMap(mapsContainer)for (let i = 0; i < 8; i++) {// 創建地圖元素const mapId = 'eight-' + iconst mapTarget = document.createElement('div')mapTarget.className = 'split-map'mapTarget.style.height = "25%"mapTarget.style.width = '50%'mapTarget.setAttribute('id', mapId)mapsContainer.appendChild(mapTarget)const map = createMap(mapId)maps.push(map)}mapZoomAndMove()})}mapSplit()// 移除子元素function removeChildMap(mapsContainer) {const childNodes = Array.from(mapsContainer.children)if (childNodes.length) {childNodes.forEach(element => {mapsContainer.removeChild(element)});}}// 地圖聯動function mapZoomAndMove() {maps.forEach(map => {maps.forEach(targetMap => {map.setView(targetMap.getView())})})}/*** 切換激活樣式*/function toogleAciveClass(target) {// 判斷split-div子元素是否激活,并切換激活樣式const splitsEle = document.querySelector('.split-div')for (let element of splitsEle.children) {if (target === element) {target.classList.add('active')} else {element.classList.remove('active')}}}
</script>
OpenLayers示例數據下載,請回復關鍵字:ol數據
全國信息化工程師-GIS 應用水平考試資料,請回復關鍵字:GIS考試
【GIS之路】 已經接入了智能助手,歡迎關注,歡迎提問。
歡迎訪問我的博客網站-長談GIS:
http://shanhaitalk.com
都看到這了,不要忘記點贊、收藏 + 關注 哦 !
本號不定時更新有關?GIS開發 相關內容,歡迎關注?!