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。