vue项目中mapboxgl的几个经典操作代码示例
1、创建标记并显示在地图上
功能:在地图上点击时,创建一个标记,并在该标记的弹窗中显示点击位置的经纬度坐标信息。点击标记时,弹窗会显示在地图上。
代码示例:
map.on('click', function (e) {
const coordinates = e.lngLat;
const longitude = coordinates.lng;
const latitude = coordinates.lat;
// 创建一个标记
const marker = new mapboxgl.Marker()
.setLngLat(coordinates)
.addTo(map);
// 创建一个弹窗,并将坐标信息添加到弹窗内容中
const popup = new mapboxgl.Popup()
.setLngLat(coordinates)
.setHTML(`<p>经度: ${
longitude}</p><p>纬度: ${
latitude}</p>`)
.addTo(map);
// 给标记添加点击事件,点击时显示弹窗
marker.getElement().addEventListener('click', function () {
popup.addTo(map);
});
});
2、实现插点效果
功能:使用 Mapbox GL JS 中的符号图层(Symbol Layer)来在地图上绘制点标记,并根据项目列表的位置信息进行插点展示。
代码示例:
// 假设项目列表的数据格式为以下形式
const projectList = [
{
name: '项目1',
latitude: 39.9042,
longitude: 116.4074,
},
{
name: '项目2',
latitude: 31.2304,
longitude: 121.4737,
},
// ...
];
// 创建一个符号图层,用于绘制点标记
map.on('load', function () {
map.addLayer({
id: 'project-markers',
type: 'symbol',
source: {
type: 'geojson',
data: {
type: 'FeatureCollection',
features: projectList.map((project) => ({
type: 'Feature',
properties: {
},
geometry: {
type: 'Point',
coordinates: [project.longitude, project.latitude],
},
})),
},
},
layout: {
'icon-image': 'marker-15', // 使用预定义的图标作为点标记的样式
'icon-size': 1.5,
},
});
});
在上述代码中,我们根据项目列表的位置信息,创建了一个 GeoJSON 对象,其中每个项目都被转换为一个点要素。然后,将该 GeoJSON 对象作为符号图层的数据源,将每个点标记绘制在地图上。
需要注意的是,上述代码中使用了预定义的图标样式 ‘marker-15’,你可以根据需求自定义图标样式或使用其他图标。
通过上述方式,可以将项目列表的位置信息以插点的方式展示在地图上,实现插点效果,并与其他地图元素进行交互。
3、实现点选地图上展示位置
功能:实现点选设备在地图上展示位置
示例代码:
<template>
<div id="app">
<div id="map"></div>
<div class="sidebar">
<h2>项目列表</h2>
<el-collapse v-model="collapse">
<el-collapse-item v-for="project in projectList" :title="project.name" :key="project.id">
<div class="project-details">
<div class="project-info">
<p><strong>项目名称:</strong> {
{
project.name }}</p>
<p><strong>项目经理:</strong> {
{
project.manager }}</p>
<p><strong>设备数量:</strong> {
{
project.deviceCount }}</p>
</div>
<div class="device-list">
<h4>设备列表</h4>
<ul>
<li v-for="device in project.devices" :key="device.id" @click="showDeviceLocation(device)">
{
{
device.name }}
</li>
</ul>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
<div id="charts"></div>
</div>
</template>
<script>
import mapboxgl from 'mapbox-gl'
import * as echarts from 'echarts'
import 'echarts-gl'
export default {
data() {
return {
map: null,
projectList: [
{
id: 1,
name: '项目1',
manager: '经理1',
deviceCount: 5,
devices: [
{
id: 1, name: '设备1', latitude: 39.9042, longitude: 116.4074 },
{
id: 2, name: '设备2', latitude: 31.2304, longitude: 121.4737 },
{
id: 3, name: '设备3', latitude: 25.7617, longitude: -80.1918 },
{
id: 4, name: '设备4', latitude: 51.5074, longitude: -0.1278 },
{
id: 5, name: '设备5', latitude: 37.7749, longitude: -122.4194 },
],
},
// ...
],
collapse: [],
}
},
mounted() {
// 初始化地图
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [0, 0],
zoom: 2,
})
// 添加插点图层
this.map.on('load', () => {
this.addMarkers()
})
// 初始化 ECharts 图表
this.initCharts()
},
methods: {
addMarkers() {
this.projectList.forEach((project) => {
project.devices.forEach((device) => {
const marker = new mapboxgl.Marker().setLngLat([device.longitude, device.latitude]).addTo(this.map)
marker.getElement().addEventListener('click', () => {
this.showDeviceLocation(device)
})
})
})
},
showDeviceLocation(device) {
this.map.flyTo({
center: [device.longitude, device.latitude],
zoom: 10,
})
},
initCharts() {
// 初始化 ECharts 图表
const chartContainer = document.getElementById('charts')
const chart = echarts.init(chartContainer)
const option = {
// 配置 ECharts 统计图的选项
// ...
}
chart.setOption(option)
},
},
}
</script>
<style>
#app {
display: flex;
height: 100vh;
}
#map {
flex: 1;
}
.sidebar {
width: 300px;
padding: 20px;
background-color: #f5f5f5;
overflow-y: auto;
}
.project-details {
margin-bottom: 10px;
}
.project-info p {
margin-bottom: 5px;
}
.device-list {
margin-top: 10px;
}
.device-list h4 {
margin-bottom: 5px;
}
.device-list ul {
list-style: none;
padding: 0;
margin: 0;
}
#charts {
flex: 1;
}
</style>
在上述代码示例中,设备信息中包含了经纬度信息,通过点击设备列表中的设备,在地图上展示设备的位置信息。通过调用 setLngLat 方法设置 Marker 的经纬度,然后使用 addTo 方法将 Marker 添加到地图上。同时,为 Marker 的元素添加点击事件监听器,点击 Marker 时会调用 showDeviceLocation 方法,在地图上展示设备的位置。
将 YOUR_MAPBOX_ACCESS_TOKEN 替换为你自己的 Mapbox 访问令牌。
4、结合 Mapbox GL、ECharts、Element UI 的综合示例1
<template>
<div id="app">
<div id="map"></div>
<div class="sidebar">
<h2>项目列表</h2>
<el-collapse v-model="collapse">
<el-collapse-item v-for="project in projectList" :title="project.name" :key="project.id">
<div class="project-details">
<div class="project-info">
<p><strong>项目名称:</strong> {
{
project.name }}</p>
<p><strong>项目经理:</strong> {
{
project.manager }}</p>
<p><strong>设备数量:</strong> {
{
project.deviceCount }}</p>
</div>
<div class="device-list">
<h4>设备列表</h4>
<ul>
<li v-for="device in project.devices" :key="device.id">{
{
device.name }}</li>
</ul>
</div>
</div>
</el-collapse-item>
</el-collapse>
</div>
<div id="charts"></div>
</div>
</template>
<script>
import mapboxgl from 'mapbox-gl'
import * as echarts from 'echarts'
import 'echarts-gl'
export default {
data() {
return {
map: null,
projectList: [
{
id: 1,
name: '项目1',
manager: '经理1',
deviceCount: 5,
latitude: 39.9042,
longitude: 116.4074,
devices: [
{
id: 1, name: '设备1' },
{
id: 2, name: '设备2' },
{
id: 3, name: '设备3' },
{
id: 4, name: '设备4' },
{
id: 5, name: '设备5' },
],
},
{
id: 2,
name: '项目2',
manager: '经理2',
deviceCount: 3,
latitude: 31.2304,
longitude: 121.4737,
devices: [
{
id: 6, name: '设备6' },
{
id: 7, name: '设备7' },
{
id: 8, name: '设备8' },
],
},
],
collapse: [],
}
},
mounted() {
// 初始化地图
mapboxgl.accessToken = 'YOUR_MAPBOX_ACCESS_TOKEN'
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/streets-v11',
center: [0, 0],
zoom: 2,
})
// 添加插点图层
this.map.on('load', () => {
this.addMarkers()
})
// 初始化 ECharts 图表
this.initCharts()
},
methods: {
addMarkers() {
this.projectList.forEach((project) => {
const marker = new mapboxgl.Marker().setLngLat([project.longitude, project.latitude]).addTo(this.map)
marker.getElement().addEventListener('click', () => {
this.showProjectDetails(project.id)
})
})
},
showProjectDetails(projectId) {
this.collapse = [projectId]
},
initCharts() {
const chartContainer = document.getElementById('charts')
const chart = echarts.init(chartContainer)
const option = {
// 配置 ECharts 统计图的选项
// ...
}
chart.setOption(option)
},
},
}
</script>
<style>
#app {
display: flex;
height: 100vh;
}
#map {
flex: 1;
}
.sidebar {
width: 300px;
padding: 20px;
background-color: #f5f5f5;
overflow-y: auto;
}
.project-details {
margin-bottom: 10px;
}
.project-info p {
margin-bottom: 5px;
}
.device-list {
margin-top: 10px;
}
.device-list h4 {
margin-bottom: 5px;
}
.device-list ul {
list-style: none;
padding: 0;
margin: 0;
}
#charts {
flex: 1;
}
</style>
将 YOUR_MAPBOX_ACCESS_TOKEN 替换为你自己的 Mapbox 访问令牌。
以上代码示例中,使用了 Vue.js、Mapbox GL、ECharts 和 Element UI。通过插点效果在地图上展示项目的位置信息,并通过点击项目列表展示项目的详细信息。统计图使用 ECharts 进行可视化展示。同时,使用了 Element UI 的 Collapse 组件实现可收缩的弹框效果。
5、结合 Mapbox GL、ECharts、Element UI 的综合示例2
项目分布和设备调配案例代码示例:
<template>
<div class="container">
<div class="sidebar">
<h2>项目列表</h2>
<el-collapse v-model="activeProjects">
<el-collapse-item v-for="project in projects" :key="project.id">
<template slot="title">
{
{
project.name }}
</template>
<el-row>
<el-col :span="12">
<h4>项目信息</h4>
<p>工作量: {
{
project.workload }}</p>
<p>位置: {
{
project.location }}</p>
<p>开始日期: {
{
project.startDate }}</p>
<p>负责人: {
{
project.projectManager }}</p>
</el-col>
<el-col :span="12">
<h4>设备列表</h4>
<ul>
<li v-for="deviceId in project.equipmentList" :key="deviceId">
{
{
getDeviceName(deviceId) }}
</li>
</ul>
</el-col>
</el-row>
</el-collapse-item>
</el-collapse>
</div>
<div id="map" class="map"></div>
</div>
</template>
<script>
import mapboxgl from 'mapbox-gl';
import axios from 'axios';
import * as echarts from 'echarts';
export default {
data() {
return {
projects: [], // 项目列表数据
devices: [], // 设备列表数据
activeProjects: [], // 展开的项目列表项
map: null, // Mapbox GL 实例
chart: null, // ECharts 实例
};
},
mounted() {
// 初始化地图
mapboxgl.accessToken = 'your-mapbox-access-token';
this.map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/light-v10',
center: [0, 0],
zoom: 1,
});
// 初始化图表
this.chart = echarts.init(document.getElementById('chart'));
// 获取设备列表数据
axios.get('/api/devices')
.then(response => {
this.devices = response.data;
})
.catch(error => {
console.error('Failed to fetch devices:', error);
});
// 获取项目列表数据
axios.get('/api/projects')
.then(response => {
this.projects = response.data;
})
.catch(error => {
console.error('Failed to fetch projects:', error);
});
},
methods: {
// 根据设备ID获取设备名称
getDeviceName(deviceId) {
const device = this.devices.find(d => d.id === deviceId);
return device ? device.name : '';
},
// 根据项目ID获取项目位置坐标
getProjectCoordinates(projectId) {
// 这里假设项目的位置是经纬度坐标 [longitude, latitude]
const project = this.projects.find(p => p.id === projectId);
return project ? project.location : null;
},
// 在地图上展示项目位置
showProjectLocation(projectId) {
const coordinates = this.getProjectCoordinates(projectId);
if (coordinates) {
// 创建地图标记
const marker = new mapboxgl.Marker().setLngLat(coordinates).addTo(this.map);
// 将地图中心移动到标记位置
this.map.flyTo({
center: coordinates, zoom: 10 });
}
},
// 绘制设备统计图表
drawDeviceChart() {
// 获取设备状态统计数据
const deviceStatus = this.devices.reduce((result, device) => {
result[device.status] = result[device.status] ? result[device.status] + 1 : 1;
return result;
}, {
});
// 绘制统计图表
const options = {
title: {
text: '设备状态统计' },
series: [
{
name: '设备状态',
type: 'pie',
radius: '60%',
data: Object.entries(deviceStatus).map(([status, count]) => ({
name: status, value: count })),
},
],
};
this.chart.setOption(options);
},
},
};
</script>
<style>
.container {
display: flex;
}
.sidebar {
width: 300px;
padding: 20px;
background-color: #f5f5f5;
}
.map {
flex: 1;
height: 600px;
}
</style>
替换 your-mapbox-access-token,并根据您的后端 API 配置更新数据请求的 URL。