阅读 9
^ 关注我,带你一起学GIS ^
❝
注:当前使用的是 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 : TDTImgLayer
const 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-' + i
const 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-' + i
const 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-' + i
const 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-' + i
const 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 : TDTImgLayer
const 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-' + i
const 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-' + i
const 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-' + i
const 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-' + i
const 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-' + i
const 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开发 相关内容,欢迎关注