vue项目中mapboxgl的几个经典操作代码示例

简介: 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。

目录
相关文章
|
3月前
|
人工智能 JavaScript 算法
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
Vue 中 key 属性的深入解析:改变 key 导致组件销毁与重建
487 0
|
3月前
|
JavaScript UED
用组件懒加载优化Vue应用性能
用组件懒加载优化Vue应用性能
|
3月前
|
JavaScript 前端开发 UED
Vue 表情包输入组件实现代码及详细开发流程解析
这是一篇关于 Vue 表情包输入组件的使用方法与封装指南的文章。通过安装依赖、全局注册和局部使用,可以快速集成表情包功能到 Vue 项目中。文章还详细介绍了组件的封装实现、高级配置(如自定义表情列表、主题定制、动画效果和懒加载)以及完整集成示例。开发者可根据需求扩展功能,例如 GIF 搜索或自定义表情上传,提升用户体验。资源链接提供进一步学习材料。
182 1
|
JavaScript Java 物联网
现有vue项目seo优化
现有vue项目seo优化
|
JavaScript 前端开发
重读vue电商网站45之项目优化上线
重读vue电商网站45之项目优化上线
184 0
重读vue电商网站45之项目优化上线
|
5月前
|
JavaScript
vue实现任务周期cron表达式选择组件
vue实现任务周期cron表达式选择组件
663 4
|
4月前
|
JavaScript 数据可视化 前端开发
基于 Vue 与 D3 的可拖拽拓扑图技术方案及应用案例解析
本文介绍了基于Vue和D3实现可拖拽拓扑图的技术方案与应用实例。通过Vue构建用户界面和交互逻辑,结合D3强大的数据可视化能力,实现了力导向布局、节点拖拽、交互事件等功能。文章详细讲解了数据模型设计、拖拽功能实现、组件封装及高级扩展(如节点类型定制、连接样式优化等),并提供了性能优化方案以应对大数据量场景。最终,展示了基础网络拓扑、实时更新拓扑等应用实例,为开发者提供了一套完整的实现思路和实践经验。
486 77
|
5月前
|
缓存 JavaScript 前端开发
Vue 基础语法介绍
Vue 基础语法介绍
|
3月前
|
JavaScript 前端开发 开发者
Vue 自定义进度条组件封装及使用方法详解
这是一篇关于自定义进度条组件的使用指南和开发文档。文章详细介绍了如何在Vue项目中引入、注册并使用该组件,包括基础与高级示例。组件支持分段配置(如颜色、文本)、动画效果及超出进度提示等功能。同时提供了完整的代码实现,支持全局注册,并提出了优化建议,如主题支持、响应式设计等,帮助开发者更灵活地集成和定制进度条组件。资源链接已提供,适合前端开发者参考学习。
338 17
|
3月前
|
监控 JavaScript 前端开发
Vue 文件批量下载组件封装完整使用方法及优化方案解析
本文详细介绍了批量下载功能的技术实现与组件封装方案。主要包括两种实现方式:**前端打包方案(基于file-saver和jszip)** 和 **后端打包方案**。前者通过前端直接将文件打包为ZIP下载,适合小文件场景;后者由后端生成ZIP文件流返回,适用于大文件或大量文件下载。同时,提供了可复用的Vue组件`BatchDownload`,支持进度条、失败提示等功能。此外,还扩展了下载进度监控和断点续传等高级功能,并针对跨域、性能优化及用户体验改进提出了建议。可根据实际需求选择合适方案并快速集成到项目中。
323 17