当前位置: 首页 > news >正文

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.xdnf.cn/news/900505.html

相关文章:

  • 【 java 集合知识 第二篇 】
  • CSS 定位:原理 + 场景 + 示例全解析
  • 使用 SymPy 进行向量和矩阵的高级操作
  • uni-app 如何实现选择和上传非图像、视频文件?
  • 山东大学《数据可视化》期末复习宝典
  • 机器学习框架PyTorch
  • Opencv中的copyto函数
  • ESP8266(NodeMcu)+GPS模块+TFT屏幕实现GPS码表
  • 关于双网卡优先级:有效跃点数的解析(设置值×2)
  • day48 python通道注意力
  • 基于AWS Serverless架构:零运维构建自动化SEO内容生成系统
  • Spark 之 DataFrame 开发
  • 内嵌式mqtt server
  • IoT/HCIP实验-3/LiteOS操作系统内核实验(任务、内存、信号量、CMSIS..)
  • halcon 透视矩阵
  • Opencv中的addweighted函数
  • OpenCV 图像色彩空间转换与抠图
  • VTK如何让部分单位不可见
  • uniapp 安卓 APP 后台持续运行(保活)的尝试办法
  • 【Veristand】Veristand环境安装教程-Linux RT / Windows
  • OpenCV为图像添加边框
  • MVC与MVP设计模式对比详解
  • PCB特种工艺应用扩展:厚铜、高频与软硬结合板
  • 加法c++
  • 【驱动】Orin NX恢复备份失败:does not match the current board you‘re flashing onto
  • 【网络安全】Qt免杀样本分析
  • 令牌桶 滑动窗口->限流 分布式信号量->限并发的原理 lua脚本分析介绍
  • ReadWriteLock(读写锁)和 StampedLock
  • tpc udp http
  • 自动化提示生成框架(AutoPrompt)