当前位置: 首页 > article >正文

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

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


效果图

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探究加载 point、polygon 的极限</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! 🚀


http://www.kler.cn/a/574070.html

相关文章:

  • upload-labs详解(1-12)
  • 如何下载安装 PyCharm?
  • 备考六级:词汇量积累(day4)
  • 三参数水质在线分析仪:从源头保障饮用水安全
  • aardio - 虚表 —— 两个虚表之间互相拖动交换数据
  • 走进聚类的世界:用日常例子解释复杂的算法概念
  • npm install 报错 no such file or directory 的解决方法
  • GoLang的select是什么?在什么时候场景下用
  • Unity多Pass渲染与GPU Instancing深度优化指南
  • OpenCV计算摄影学(16)调整图像光照效果函数illuminationChange()
  • 浅谈Manus智能体与其他AI助手(如ChatGPT、Claude等)的优势
  • 【C++进阶学习】第一讲——继承(下)---深入挖掘继承的奥秘
  • JS—组成:2分钟掌握什么是ECMAScript操作,什么是DOM操作,什么是BOM操作
  • 利用Python爬虫获取17网(17zwd)商品详情:实战指南
  • MySQL学习笔记(3)InnoDB存储引擎对MVCC的实现
  • 计算机毕业设计SpringBoot+Vue.js青年公寓服务平台(源码+文档+PPT+讲解)
  • 深度学习中TorchScript原理、作用浅析(Trace/Script)
  • MySQL事务,函数,性能,索引
  • 【GoTeams】-2:项目基础搭建(下)
  • BGP服务器主要是指什么?