当前位置: 首页 > 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开发 相关内容,欢迎关注 !

相关文章:

  • OpenVINO环境配置--OpenVINO安装
  • Vue 渲染 Markdown 文件完全指南
  • 【VLNs篇】06:SmartWay—面向零样本视觉语言导航的增强路径点预测与回溯
  • 【动手学深度学习】2.6. 概率
  • C++递归语句完全指南:从原理到实践
  • 智能仓储解决方案:如何为您的企业选择最佳系统 (提升效率 降低成本)
  • 麒麟系统安装Navicat(14试用,删除文件可接着用)
  • KuiperInfer跟学第二课——张量的构建与实现
  • 嵌入式学习之系统编程(十一)网络编程之协议头,测试命令及工具
  • python闭包与装饰器
  • 跟我学c++中级篇——理解类型推导和C++不同版本的支持
  • 内嵌式mqtt server
  • 成功案例丨基于OptiStruct的三轮车车架结构刚强度仿真计算与优化
  • leetcode1609. 奇偶树-meidum
  • win10/win11禁止系统更新
  • 力扣面试150题--克隆图
  • Python删除大量文件
  • Day46 Python打卡训练营
  • 阿里140 补环境日志
  • C++.OpenGL (3/64)着色器(Shader)深入
  • 海南做网站公司/搜索引擎优化seo专员招聘
  • 免费的网站建设开发/软文平台
  • 信息安全网站建设方案书/拼多多搜索关键词排名
  • 南昌做建网站的/竞价服务托管公司
  • 惠州做网站多少钱/南昌搜索引擎优化
  • 银医网站建设方案/北京seo网站推广