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 メソッドを呼び出してマーカーの緯度と経度を設定し、addTo メソッドを使用してマーカーをマップに追加します。同時に、クリック イベント リスナーを 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 が使用されています。挿入ポイント効果により地図上にプロジェクトの位置情報を表示し、プロジェクトリストをクリックするとプロジェクトの詳細情報を表示します。統計グラフは EChart を使用して視覚化されます。同時に、要素 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 を更新します。

おすすめ

転載: blog.csdn.net/weixin_43025151/article/details/130948830