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。

目录
相关文章
|
1天前
|
监控 JavaScript
Vue中的数据变化监控与响应——深入理解Watchers
Vue中的数据变化监控与响应——深入理解Watchers
|
1天前
|
JSON 数据可视化 前端开发
vue3+threejs+koa可视化项目——模型文件上传(第四步)
vue3+threejs+koa可视化项目——模型文件上传(第四步)
15 7
|
1天前
|
JSON 数据可视化 数据库
vue3+threejs+koa可视化项目——实现登录注册(第三步)
vue3+threejs+koa可视化项目——实现登录注册(第三步)
18 5
|
1天前
|
JavaScript 数据可视化 算法
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
vue3+threejs可视化项目——搭建vue3+ts+antd路由布局(第一步)
16 6
|
1天前
|
JavaScript 安全 前端开发
Vue 项目中的权限管理:让页面也学会说“你无权访问!
Vue 项目中的权限管理:让页面也学会说“你无权访问!
10 3
|
1天前
|
JavaScript 前端开发 开发者
Vue的神奇解锁:冒险的开始
Vue的神奇解锁:冒险的开始
5 1
|
JavaScript 测试技术 容器
Vue2+VueRouter2+webpack 构建项目
1). 安装Node环境和npm包管理工具 检测版本 node -v npm -v 图1.png 2). 安装vue-cli(vue脚手架) npm install -g vue-cli --registry=https://registry.
982 0
|
3天前
|
资源调度 JavaScript 前端开发
Vue的路由管理:VueRouter的配置和使用
【4月更文挑战第24天】VueRouter是Vue.js的官方路由管理器,用于在单页面应用中管理URL路径与组件的映射。通过安装并引入VueRouter,设置路由规则和创建router实例,可以实现不同路径下显示不同组件。主要组件包括:`&lt;router-link&gt;`用于创建导航链接,`&lt;router-view&gt;`负责渲染当前路由对应的组件。此外,VueRouter还支持编程式导航和各种高级特性,如嵌套路由、路由参数和守卫,以应对复杂路由场景。
|
2天前
|
JavaScript 前端开发
【vue】iview如何把input输入框和点击输入框之后的边框去掉
【vue】iview如何把input输入框和点击输入框之后的边框去掉
8 0
|
2天前
|
JavaScript
【vue实战】父子组件互相传值
【vue实战】父子组件互相传值
8 1