mapboxGL列表和地图联动
Posted 牛老师讲GIS
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mapboxGL列表和地图联动相关的知识,希望对你有一定的参考价值。
概述
列表和地图联动是webgis中一个非常常见的功能,本文讲一下在mapboxGL中结合vue如何实现此功能。
效果
实现思路
1. 获取数据
获取数据并将数据保存起来;
2. 列表展示
列表简单的用ul
、li
来实现。
3. 地图展示
数据获取之后,通过document.createElement()
的方式创建marker,将结果在地图上展示。
4. 列表地图联动
联动存在两个交互:鼠标移动和点击选中,所以需要两个变量用来记录当前鼠标经过的和点击选中的,如果鼠标经过的和点击选中发生变化的时候,去设置对应的样式即可。
实现代码
<template>
<div class="search-panel">
<div
class="search-result">
<h4 class="title">
查询结果
</h4>
<ul
class="result-list">
<li
v-for="(item, index) in searchResult"
:key="index"
:class="getClass(item)"
@mouseover="currentMarker = item"
@mouseout="currentMarker = "
@click="selectMarker = item">
<div class="marker">
<span> index + 1 </span>
</div>
<div class="info">
<b> item.name </b><br>
item.addr
</div>
</li>
</ul>
</div>
</template>
<script>
export default
name: 'Search',
data()
return
searchResult: [], //记录查询结果
markers: [],
currentMarker: ,
selectMarker: ,
markerPopup: null
;
,
methods:
init()
this.markerPopup = new mapboxgl.Popup(
closeButton: false,
closeOnClick: false,
className: 'marker-popup',
offset: [0, -15],
anchor: 'bottom'
);
// 造测试数据
this.searchByKeyword();
,
getRandomPos()
const bbox = [79.740682, 20.10212, 134.0345, 44.8279];
const lon = Math.random() * (bbox[2] - bbox[0] + 1) + bbox[0];
const lat = Math.random() * (bbox[3] - bbox[1] + 1) + bbox[1];
return [lon, lat];
,
getClass(item) // 设置列表样式
let cls = item.id === this.currentMarker.id ? 'active' : '';
cls += item.id === this.selectMarker.id ? ' select' : '';
return cls;
,
setMarkersClass() // 设置地图marker样式
this.searchResult.forEach(item =>
const dom = document.getElementById(item.id);
if (item.id === this.currentMarker.id)
dom.classList.add('active');
else
dom.classList.remove('active');
if (item.id === this.selectMarker.id)
dom.classList.add('select');
else
dom.classList.remove('select');
);
,
searchByKeyword()
const that = this;
if (this.keyword !== '')
that.loading = true;
that.searchResult = [];
this.removeMarkers();
setTimeout(() =>
for (let i = 0; i < 10; ++i)
that.searchResult.push(
id: 'marker' + i,
name: '大石地铁站',
addr: '广东省广州市番禺区大石地铁站',
pos: that.getRandomPos()
);
// 添加markers
that.addMarkers2Map();
that.loading = false;
, 2000);
,
addMarkers2Map()
const that = this;
const map = window.map;
that.searchResult.forEach((item, index) =>
const ele = document.createElement('div');
ele.setAttribute('class', 'map-marker');
ele.setAttribute('id', item.id);
ele.innerText = (index + 1).toString();
const option =
element: ele
;
const marker = new mapboxgl.Marker(option)
.setLngLat(item.pos)
.addTo(map);
that.markers.push(marker);
ele.onmouseover = () =>
that.currentMarker = item;
;
ele.onmouseout = () =>
that.currentMarker = ;
;
ele.onclick = () =>
that.selectMarker = item;
;
);
,
removeMarkers()
this.markers.forEach(marker =>
marker.remove();
);
,
showMarkerInfo()
const that = this;
if (this.selectMarker.id)
const description = `
<h5>
$this.selectMarker.name
<span class="close el-icon-close" id="popupClose"></span>
</h5>
<ul>
<li>温度: 20℃</li>
<li>湿度: 52%</li>
<li>降水: 1mm</li>
<li>风速: 4m/s</li>
<li>风向: 无持续风向</li>
</ul>
`;
this.markerPopup
.setLngLat(this.selectMarker.pos)
.sethtml(description)
.addTo(window.map);
// 添加关闭事件
document.getElementById('popupClose').onclick = () =>
that.selectMarker = ;
;
window.map.flyTo(
center: this.selectMarker.pos
);
else
this.markerPopup.remove();
,
watch:
currentMarker(val)
this.setMarkersClass();
,
selectMarker(val)
this.setMarkersClass();
this.showMarkerInfo();
;
</script>
<style scoped lang="scss">
@import '../../assets/css/map';
.search-panel
position: absolute;
top: $padding;
left: $padding;
z-index: 99;
.search-result
width: 315px;
background-color: $bg-color;
border-radius: 4px;
padding-bottom: 10px;
.title
margin: 0;
padding: 10px;
border-bottom: 1px solid #ccc;
i
float: right;
font-size: 14px;
&:hover,
&.active
cursor: pointer;
color: $active-color;
text-decoration: underline;
.result-list
margin: 10px 0;
min-height: 100px;
li
padding: 8px 10px;
overflow: hidden;
border-bottom: 1px dashed #ddd;
&:hover,
&.active,
&.select
cursor: pointer;
.marker span
background-image: url('../../assets/images/marker-blue.png');
&.select
background-color: rgba(0, 0, 0, 0.05);
.marker
float: left;
width: 35px;
text-align: center;
line-height: 30px;
span
width: 26px;
height: 26px;
line-height: 20px;
text-align: center;
display: inline-block;
background-image: url('../../assets/images/marker-red.png');
background-size: 100%;
color: white;
border-radius: 100%;
.info
float: left;
</style>
<style lang="scss">
@import '../../assets/css/map';
.map-marker
width: 26px;
height: 26px;
line-height: 20px;
text-align: center;
background-image: url('../../assets/images/marker-red.png');
background-size: 100%;
color: white;
border-radius: 100%;
cursor: pointer;
&:hover,
&.active,
&.select
background-image: url('../../assets/images/marker-blue.png');
.marker-popup
color: white;
.mapboxgl-popup-content
background-color: $black65;
margin: 0;
padding: 8px;
white-space: nowrap;
font-size: 12px;
h5
margin: 0 0 3px 0;
padding: 3px 0;
font-size: 14px;
span
float: right;
cursor: pointer;
label
display: inline-block;
text-align: right;
width: 65px;
.mapboxgl-popup-tip
border-top-color: $black65 !important;
.mapboxgl-popup-close-button
color: white;
</style>
以上是关于mapboxGL列表和地图联动的主要内容,如果未能解决你的问题,请参考以下文章