Several classic operation code examples of mapboxgl in the vue project

1. Create a marker and display it on the map

Function: When clicking on the map, create a marker, and display the latitude and longitude coordinate information of the clicked position in the pop-up window of the marker. When the marker is clicked, a pop-up will appear on the map.

Code example:

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. Realize the effect of inserting points

Function: Use the symbol layer (Symbol Layer) in Mapbox GL JS to draw point markers on the map, and perform interpolation display according to the position information of the item list.

Code example:

// 假设项目列表的数据格式为以下形式
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,
    },
  });
});

In the above code, we create a GeoJSON object based on the location information of the list of items, where each item is converted to a point feature. Then, use this GeoJSON object as the data source for the symbol layer to draw each point marker on the map.

It should be noted that the predefined icon style 'marker-15' is used in the above code, and you can customize the icon style or use other icons according to your needs.

Through the above method, the location information of the item list can be displayed on the map in the way of inserting points, so as to realize the effect of inserting points and interact with other map elements.

3. Realize clicking on the display location on the map

Function: Realize clicking on the device to display the location on the map

Sample code:

<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>

In the above code example, the device information includes latitude and longitude information, and the location information of the device is displayed on the map by clicking on the device in the device list. Set the latitude and longitude of the Marker by calling the setLngLat method, and then use the addTo method to add the Marker to the map. At the same time, add a click event listener to the Marker element, and when the Marker is clicked, the showDeviceLocation method will be called to display the location of the device on the map.

Replace YOUR_MAPBOX_ACCESS_TOKEN with your own Mapbox access token.

4. Comprehensive example 1 combining Mapbox GL, ECharts, and Element UI

<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>

Replace YOUR_MAPBOX_ACCESS_TOKEN with your own Mapbox access token.

In the above code example, Vue.js, Mapbox GL, ECharts and Element UI are used. Display the location information of the project on the map through the insertion point effect, and display the detailed information of the project by clicking on the project list. Statistical graphs are visualized using ECharts. At the same time, the Collapse component of Element UI is used to realize the collapsible bullet box effect.

5. Comprehensive example 2 combining Mapbox GL, ECharts, and Element UI

Project distribution and equipment provisioning case code example:

<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>

Replace your-mapbox-access-token and update the URL of the data request according to your backend API configuration.

Guess you like

Origin blog.csdn.net/weixin_43025151/article/details/130948830