目录

96.在-Vue-3-中使用-OpenLayers-探究加载-PointPolygon-的极限

96.在 Vue 3 中使用 OpenLayers 探究加载 Point、Polygon 的极限

🚀 本篇文章将介绍如何在 Vue 3 中使用 OpenLayers 加载大量 Point(点)和 Polygon(多边形),并探究其渲染性能的极限。


效果图

https://i-blog.csdnimg.cn/direct/9cdb95c1c63a4c1bab398044ecfc7778.gif

1. 前言

在前端 GIS(地理信息系统)开发中,OpenLayers 作为一个功能强大的 Web 地图库,广泛用于加载地图、渲染矢量数据(点、线、面)、叠加图层等场景。然而,当涉及到 大量 Point(点)或 Polygon(多边形) 时,渲染性能往往成为瓶颈。因此,本文将基于 Vue 3,探讨 OpenLayers 在 大规模点、面数据 加载上的极限性能。


2. 技术选型

本次实现基于:

  • Vue 3 组合式 API(Composition API)
  • Vite 5.x (更快的构建工具)
  • OpenLayers 作为地图引擎
  • Element Plus 提供 UI 交互按钮

3. 项目初始化

(1)创建 Vue 3 + Vite 项目

如果你还没有 Vue 3 项目,可以使用 Vite 快速初始化:

npm create vite@latest vue-openlayers-test --template vue cd vue-openlayers-test npm install

(2)安装 OpenLayers

npm install ol


4. 代码实现

(1) App.vue 代码

<!--
 * @Author: 彭麒
 * @Date: 2025/3/6
 * @Email: 1062470959@qq.com
 * @Description: 此源码版权归吉檀迦俐所有可供学习和借鉴或商用
 -->
<template>
  <div class="container">
    <div class="w-full flex justify-center flex-wrap">
      <div class="font-bold text-[24px]">在Vue3中使用OpenLayers探究加载 pointpolygon 的极限</div>
    </div>
    <h4>
      <el-button type="primary" size="small" @click="showPoint">显示点</el-button>
      <el-button type="primary" size="small" @click="showPolygon">显示多边形</el-button>
      <el-button type="primary" size="small" @click="clearLayer">清除图层</el-button>
    </h4>
    <div id="vue-openlayers"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue';
import 'ol/ol.css';
import { Map, View } from 'ol';
import TileLayer from 'ol/layer/Tile';
import VectorLayer from 'ol/layer/Vector';
import VectorSource from 'ol/source/Vector';
import OSM from 'ol/source/OSM';
import Feature from 'ol/Feature';
import { Point, Polygon } from 'ol/geom';
import Style from 'ol/style/Style';
import Fill from 'ol/style/Fill';
import Stroke from 'ol/style/Stroke';
import CircleStyle from 'ol/style/Circle';

// **状态管理**
const map = ref(null);
const dataSource = ref(new VectorSource({ wrapX: false }));

// **初始化地图**
const initMap = () => {
  const OSM_Layer = new TileLayer({
    source: new OSM(),
  });

  const feature_Layer = new VectorLayer({
    source: dataSource.value,
    style: featureStyle(), // 统一设置 vector 样式
  });

  map.value = new Map({
    target: 'vue-openlayers',
    layers: [OSM_Layer, feature_Layer],
    view: new View({
      projection: 'EPSG:4326',
      center: [45, 45],
      zoom: 3,
    }),
  });
};

// **设置 vector 样式**
const featureStyle = () => {
  return new Style({
    stroke: new Stroke({
      width: 1,
      color: '#0f0',
    }),
    image: new CircleStyle({
      radius: 2,
      fill: new Fill({
        color: '#ff0000',
      }),
    }),
  });
};

// **清除 vector 数据源**
const clearLayer = () => {
  dataSource.value.clear();
};

// **生成随机点**
const showPoint = () => {
  for (let i = 0; i < 2000; i++) {
    let a = Math.random() * 100;
    let b = Math.random() * 90;
    let pointFeature = new Feature({
      geometry: new Point([a, b]),
    });
    dataSource.value.addFeature(pointFeature);
  }
};

// **生成随机多边形**
const showPolygon = () => {
  let data = [];
  for (let i = 0; i < 2000; i++) {
    let a = Math.random() * 180;
    let b = Math.random() * 90;
    data.push([a, b]);
  }
  let arr = data.concat([data[0]]); // 闭合多边形

  let polygonFeature = new Feature({
    geometry: new Polygon([arr]),
  });
  dataSource.value.addFeature(polygonFeature);
};

// **在组件挂载后初始化地图**
onMounted(() => {
  initMap();
});
</script>

<style scoped>
.container {
  width: 840px;
  height: 570px;
  margin: 50px auto;
  border: 1px solid #42B983;
}

#vue-openlayers {
  width: 800px;
  height: 400px;
  margin: 0 auto;
  border: 1px solid #42B983;
  position: relative;
}
</style>

6. 性能测试

测试 1:加载 2000 个点

✅ 地图可以流畅渲染,无明显卡顿。

测试 2:加载 2000 个多边形

⚠️ 出现轻微卡顿 ,说明 OpenLayers 在大规模面数据上渲染性能较点数据差。

测试 3:同时加载 4000 个点 + 2000 个多边形

页面开始卡顿 ,性能瓶颈显现,建议:

  • 优化矢量渲染 (使用 WebGL 方式)
  • 使用 Cluster 点聚合
  • 降低复杂多边形的点数

7. 总结

在 Vue 3 + OpenLayers 的开发中: ✅ 点数据的渲染性能较好 ,即使 2000+ 也不会明显卡顿。

多边形数据的渲染性能较差 ,大量复杂多边形会降低 FPS。

如果要进一步优化,可以:

  • 采用 WebGL 层
  • 使用点聚合
  • 减少不必要的矢量对象

📌 希望这篇文章能帮助你在 Vue 3 项目中更高效地使用 OpenLayers! 🚀