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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈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…