OpenLayers 分屏對比(地圖聯動)

注:當前使用的是 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之路】 已經接入了智能助手,歡迎關注,歡迎提問。

歡迎訪問我的博客網站-長談GIShttp://shanhaitalk.com

都看到這了,不要忘記點贊、收藏 + 關注

本號不定時更新有關?GIS開發 相關內容,歡迎關注?!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/85974.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/85974.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/85974.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【大模型】大模型數據訓練格式

1. SFT&#xff08;有監督微調&#xff09; 1.1 數據格式 JSONL&#xff08;每行一個 JSON 對象&#xff09;最為流行&#xff1b;也可用 CSV&#xff0f;TSV&#xff0c;但 JSONL 更靈活。字段設計 prompt&#xff1a;用戶輸入或任務指令&#xff08;通常以“系統指令&#…

[論文閱讀] 人工智能 | 利用負信號蒸餾:用REDI框架提升LLM推理能力

【論文速讀】利用負信號蒸餾&#xff1a;用REDI框架提升LLM推理能力 論文信息 arXiv:2505.24850 cs.LG cs.AI cs.CL Harnessing Negative Signals: Reinforcement Distillation from Teacher Data for LLM Reasoning Authors: Shuyao Xu, Cheng Peng, Jiangxuan Long, Weidi…

Cursor 1.0正式推出:全面解析你的AI 編程助手

目錄 前言 一、BugBot&#xff1a;你的私人代碼審查專家 二、Background Agent&#xff1a;7x24小時在線的云端開發伙伴 三、Jupyter Notebook 深度集成&#xff1a;數據科學家的福音 四、記憶功能 (Memories)&#xff1a;讓 AI 更懂你的項目 五、MCP 與工具生態&#xf…

QILSTE 精巧電子元件H4-108FO/5M解析

型號&#xff1a;H4-108FO/5M 在電子元件的浩瀚宇宙中&#xff0c;H4-108FO/5M 仿佛一顆散發著獨特光芒的恒星&#xff0c;其參數和特性交織成一張錯綜復雜的網絡&#xff0c;既令人困惑又充滿驚喜。這款型號的產品&#xff0c;以其 1.60.80.4mm 的微小尺寸&#xff0c;卻蘊含…

第2章_Excel_知識點筆記

Excel 知識點總結&#xff08;第2章&#xff09; 來自&#xff1a;第2章_Excel_知識點筆記&#xff0c;原筆記 基礎操作 狀態欄&#xff1a;快速查看計數/求和等數據&#xff08;右鍵可配置&#xff09;。篩選&#xff08;CtrlShiftL&#xff09;&#xff1a;按條件顯示數據…

【學習筆記】單例類模板

【學習筆記】單例類模板 一、單例類模板 以下為一個通用的單例模式框架&#xff0c;這種設計允許其他類通過繼承Singleton模板類來輕松實現單例模式&#xff0c;而無需為每個類重復編寫單例實現代碼。 // 命名空間&#xff08;Namespace&#xff09; 和 模板&#xff08;Tem…

yolo 訓練 中間可視化

yolo訓練前幾個batch&#xff0c;會可視化target: if plots and ni < 33:f save_dir / ftrain_batch{ni}.jpg # filenameplot_images(imgs, targets, paths, f, kpt_labelkpt_label)

【Linux】虛擬機代理,自動化腳本修改~/.bashrc

二選一執行 {echo ""echo "# Cla Verge代理設置 "echo "alias use-proxyexport http_proxy\"socks5h://192.168.88.1:7897\"; export https_proxy\"socks5h://192.168.88.1:7897\""echo "alias use-proxy-httpexport…

JavaScript 原型與原型鏈:深入理解 __proto__ 和 prototype 的由來與關系

引言 在 JavaScript 的世界中&#xff0c;原型和原型鏈是理解這門語言面向對象編程&#xff08;OOP&#xff09;機制的核心。不同于傳統的基于類的語言如 Java&#xff0c;JavaScript 采用了一種獨特的原型繼承機制。本文將深入探討 __proto__ 和 prototype 的由來、關系以及它…

Linux非管理員用戶安裝python環境

目錄 1. 下載2. 解壓3. 配置并指定安裝路徑&#xff08;本地用戶目錄&#xff09;4. 編譯&#xff08;不安裝系統目錄&#xff09;5. 安裝到本地用戶目錄6. 添加 Python 到環境變量7. 驗證安裝是否成功 1. 下載 版本根據需要自行指定 cd /tmp wget https://www.python.org/ft…

獵板PCB:建滔PCB板材怎么樣?

在電子元器件的精密世界中&#xff0c;PCB板材如同骨骼般支撐著整個產品的性能與壽命。面對市場上琳瑯滿目的品牌選擇&#xff0c;建滔積層板憑借三十余年技術沉淀&#xff0c;逐漸成為行業工程師與采購方口中的“品質代名詞”。今天&#xff0c;我們不談參數堆砌&#xff0c;只…

ONLYOFFICE協作空間3.1.1 企業版 介紹及部署說明:家庭云計算專家

ONLYOFFICE協作空間3.1企業版是一款專為深度集成需求設計的開源解決方案&#xff0c;其核心功能聚焦于安全性與靈活性。該版本支持私有化部署&#xff0c;允許企業將協作空間嵌入自有服務器并實現品牌定制化&#xff0c;滿足對數據主權和品牌一致性的嚴苛要求。 在安全方面&…

接IT方案編寫(PPT/WORD)、業務架構設計、投標任務

1、IT 方案編寫&#xff08;PPT/WORD&#xff09;? 定制化方案&#xff1a;根據客戶需求&#xff0c;提供涵蓋云計算、大數據、人工智能等前沿技術領域的 PPT/WORD 方案編寫服務&#xff0c;精準提煉核心價值&#xff0c;呈現專業技術內容。? 邏輯清晰架構&#xff1a;采用…

前端面試之變量與數據類型

目錄 一、聲明變量 &#xff08;1&#xff09;let &#xff08;2&#xff09;const &#xff08;3&#xff09;var var、let 和 const 的作用域差異 二、數據類型 &#xff08;1&#xff09;基本類型 undefined和null String 模板字符串拼接&#xff1a; number和b…

python queue

Python中的queue模塊提供了多種隊列實現&#xff0c;主要用于線程間安全通信。以下是主要用法&#xff1a; 基本隊列類型&#xff1a; Queue&#xff1a;先進先出(FIFO)隊列LifoQueue&#xff1a;后進先出(LIFO)隊列&#xff0c;即棧PriorityQueue&#xff1a;優先級隊列 常用方…

Linux驅動:class_create、device_create

udev是什么 動態管理設備文件 傳統的 Linux 系統通過靜態創建 /dev 目錄下的設備文件&#xff08;如早期的 mknod 命令&#xff09;&#xff0c;但現代系統中硬件設備&#xff08;如 USB 設備、存儲設備、串口等&#xff09;熱插拔頻繁&#xff0c;udev 可實時響應設備事件&…

【vLLM 學習】Cpu Offload Lmcache

vLLM 是一款專為大語言模型推理加速而設計的框架&#xff0c;實現了 KV 緩存內存幾乎零浪費&#xff0c;解決了內存管理瓶頸問題。 更多 vLLM 中文文檔及教程可訪問 →https://vllm.hyper.ai/ *在線運行 vLLM 入門教程&#xff1a;零基礎分步指南 源碼 examples/offline_inf…

基于深度強化學習的Scrapy-Redis分布式爬蟲動態調度策略研究

在大數據時代&#xff0c;網絡數據的采集與分析變得至關重要&#xff0c;分布式爬蟲作為高效獲取海量數據的工具&#xff0c;被廣泛應用于各類場景。然而&#xff0c;傳統的爬蟲調度策略在面對復雜多變的網絡環境和動態的抓取需求時&#xff0c;往往存在效率低下、資源浪費等問…

openlayers實現可拖拽的節點(類似知識圖譜)

/** * 本文介紹了實現知識圖譜可視化的技術方案&#xff0c;主要分為兩個圖層實現&#xff1a; * 1、線圖層 不拖動 * 2、點圖層 需要拖動 */ 線圖層 - 負責繪制靜態連接線&#xff0c;使用LineString創建線要素并添加到矢量圖層&#xff1b; // 線圖層 export function add…

酷黑NBA足球賽事直播源碼體育直播M39模板賽事源碼

源碼名稱&#xff1a;NBA足球賽事直播源碼酷黑體育直播M39模板賽事源碼 開發環境&#xff1a;帝國cms7.5 空間支持&#xff1a;phpmysql 帶軟件采集&#xff0c;可以掛著自動采集發布&#xff0c;無需人工操作&#xff01; 演示地址&#xff1a;https://www.52muban.com/shop…