36.在 Vue 3 中使用 OpenLayers 上传包含 SHP 的 ZIP 文件并显示图形

在 Web 开发中,地图相关的应用需求越来越多。尤其是在地理信息系统(GIS)领域,如何在 Web 中展示地理数据、上传文件并显示图形成为了开发中的一个常见需求。今天,我将为大家介绍如何使用 Vue 3OpenLayers 来实现一个功能:上传包含 SHP 文件的 ZIP 文件,并将图形解析并显示在地图上

前言

SHP 文件(Shapefile)是常见的地理空间数据格式,由 ESRI(Environmental Systems Research Institute)开发,广泛应用于地理信息系统(GIS)中。SHP 文件实际上是由多个文件组成的,主要包括 .shp(几何数据)、.shx(索引文件)和 .dbf(属性数据)。它们通常被打包成一个 ZIP 文件一起分发和存储。

本篇文章将指导你如何在 Vue 3 中使用 OpenLayers 库来加载包含 SHP 文件的 ZIP 文件,并在地图上显示其图形。

需要的工具

  1. Vue 3:Vue 是一个用于构建用户界面的 JavaScript 框架。
  2. OpenLayers:一个强大的 JavaScript 地图库,可以用来展示地图以及进行地理空间数据的处理。
  3. JSZip:一个 JavaScript 库,用于解压 ZIP 文件。
  4. Shapefile:一个 JavaScript 库,用于解析 SHP 文件。

1. 安装依赖

首先,我们需要安装一些依赖库:

npm install ol shapefile jszip
  • ol:OpenLayers 库。
  • shapefile:解析 SHP 文件的库。
  • jszip:解压 ZIP 文件的库。

2. 创建 Vue 3 组件

接下来,我们将创建一个 Vue 3 组件来实现这个功能。在此组件中,我们将使用 OpenLayers 来显示地图,上传并解析包含 SHP 文件的 ZIP 文件,最后将 SHP 文件中的几何数据显示在地图上。

<!--* @Author: 彭麒* @Date: 2024/12/19* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div class="container"><div class="font-bold text-[24px]">在vue3中使用OpenLayers: 上传包含shp的zip文件,在map上解析显示图形</div><h4><input style="margin-top: 16px" type="file" id="fileselect" accept=".kml,.kmz,.zip" @change="readFile"/></h4><div id="vue-openlayers"></div></div>
</template><script setup>
import { ref, onMounted } from 'vue'; // 引入 Vue 3 的 ref 和 onMounted 钩子
import 'ol/ol.css'; // 引入 OpenLayers 样式
import { Map, View } from 'ol'; // 引入 OpenLayers 的 Map 和 View 类
import SourceVector from 'ol/source/Vector'; // 引入 OpenLayers 的矢量数据源类
import LayerVector from 'ol/layer/Vector'; // 引入 OpenLayers 的矢量图层类
import { Tile } from 'ol/layer'; // 引入 OpenLayers 的瓦片图层类
import OSM from 'ol/source/OSM'; // 引入 OpenLayers 的 OSM 数据源类
import { fromLonLat } from 'ol/proj'; // 引入坐标转换函数
import Fill from 'ol/style/Fill'; // 引入填充样式
import Stroke from 'ol/style/Stroke'; // 引入描边样式
import Style from 'ol/style/Style'; // 引入样式
import Circle from 'ol/style/Circle'; // 引入圆形样式
import Text from 'ol/style/Text'; // 引入文本样式
import GeoJSON from 'ol/format/GeoJSON'; // 引入 GeoJSON 格式解析
import JSZip from 'jszip'; // 正确引入 JSZip
import * as shapefile from 'shapefile'; // 引入 shapefile 解析库// 使用 ref 来管理响应式数据
const map = ref(null); // 定义地图的响应式引用
const source = ref(new SourceVector({ wrapX: false })); // 定义矢量数据源的响应式引用// 随机生成 RGBA 颜色
const randomRgbaColor = () => {const r = Math.floor(Math.random() * 256); // 生成随机的红色值const g = Math.floor(Math.random() * 256); // 生成随机的绿色值const b = Math.floor(Math.random() * 256); // 生成随机的蓝色值const alpha = 1; // 设置透明度为 1return `rgb(${r},${g},${b},${alpha})`; // 返回随机生成的 RGBA 颜色
};// 自定义样式
const mystyle = (fea) => {return new Style({fill: new Fill({color: 'yellow', // 填充颜色为黄色}),stroke: new Stroke({color: 'blue', // 描边颜色为蓝色width: 2, // 描边宽度为 2}),image: new Circle({radius: 10, // 圆形半径为 10fill: new Fill({color: randomRgbaColor(), // 填充颜色为随机生成的 RGBA 颜色}),stroke: new Stroke({color: '#fff', // 描边颜色为白色width: 2, // 描边宽度为 2}),}),text: new Text({text: fea.get('name') || ' ', // 文本内容为要素的 name 属性值或空格font: '12px Calibri,sans-serif', // 字体样式fill: new Fill({color: '#000', // 填充颜色为黑色}),stroke: new Stroke({color: '#fff', // 描边颜色为白色width: 2, // 描边宽度为 2}),offsetX: 20, // X 轴偏移量为 20offsetY: 20, // Y 轴偏移量为 20}),});
};// 读取文件并解析 zip 包中的 shp 文件
const readFile = (e) => {const files = e.target.files; // 获取选中的文件const filetype = files[0].name.split('.').pop(); // 获取文件类型if (files.length === 0 || filetype !== 'zip') {alert('请重新上传 zip 格式的文件!'); // 如果没有选中文件或文件类型不是 zip,则提示重新上传return false;}const zip = new JSZip(); // 创建 JSZip 实例zip.loadAsync(files[0]).then((zipData) => {zipData.file(/.shp$/i)[0].async('arraybuffer').then((item) => {shapefile.open(item).then((sourceData) => {sourceData.read().then(function log(result) {if (result.done) return; // 如果读取完成,则返回const feature = new GeoJSON().readFeature(result.value, {dataProjection: 'EPSG:4326', // 数据投影为 EPSG:4326featureProjection: 'EPSG:3857', // 要素投影为 EPSG:3857});feature.setStyle(mystyle(feature)); // 设置要���样式source.value.addFeature(feature); // 添加要素到矢量数据源return sourceData.read().then(log); // 递归读取下一个要素});}).catch((error) => console.error(error.stack)); // 捕获并打印错误});});
};// 初始化地图
const initMap = () => {map.value = new Map({target: 'vue-openlayers', // 目标容器 IDlayers: [new Tile({source: new OSM(), // 使用 OSM 数据源}),new LayerVector({source: source.value, // 使用矢量数据源}),],view: new View({projection: 'EPSG:3857', // 设置投影为 EPSG:3857center: fromLonLat([13.7373, 51.0504]), // 设置地图初始中心点为德累斯顿zoom: 8, // 设置初始缩放级别}),});
};// Vue 生命周期钩子,组件挂载时执行
onMounted(() => {initMap(); // 初始化地图
});
</script><style scoped>
.container {width: 840px;height: 590px;margin: 50px auto;border: 1px solid #42B983;
}#vue-openlayers {width: 800px;height: 400px;margin: 0 auto;border: 1px solid #42B983;position: relative;
}
</style>

代码解析

1. Vue 3 Composition API 的应用

我们将 Vue 2 中的 datamethodsmounted 改为 Vue 3 中的 Composition API 写法,使用 ref 来声明响应式的数据和 onMounted 钩子来处理组件挂载时的初始化逻辑。

2. 文件读取和解析

readFile 方法通过监听文件选择框的变化事件,获取用户选择的 ZIP 文件,使用 JSZip 解压缩 ZIP 文件,并利用 shapefile 库读取 .shp 文件内容。读取后,我们使用 OpenLayers 的 GeoJSON 格式类将其转换为可在地图上展示的要素。

3. 自定义样式

我们为地图上的每个图形(点、线、面)设置了自定义样式,使用 randomRgbaColor 方法随机生成颜色,使每个图形的样式看起来更加丰富。

4. 地图初始化

我们使用 OpenLayers 的 Map 类初始化地图,并使用 OSM 瓦片图层作为底图,结合矢量图层显示 SHP 文件的图形。

3. SHP 文件格式介绍

SHP(Shapefile)格式是 GIS 中非常常见的一种矢量数据格式,通常用于存储地理空间数据。一个完整的 SHP 文件通常由多个文件组成:

  • .shp 文件:存储几何数据,描述地理对象的位置、形状(点、线、面)。
  • .shx 文件:存储索引数据,用于加速 SHP 文件中的数据查询。
  • .dbf 文件:存储与几何数据相关的属性数据,例如名称、类型、面积等。

结语

在这篇文章中,我们介绍了如何在 Vue 3 中使用 OpenLayers 加载并显示上传的 SHP 文件。通过结合使用 shapefilejszip 和 OpenLayers,我们能够轻松地在 Web 页面中显示地理空间数据,并将 SHP 文件格式的内容呈现给用户。

希望本文能帮助你快速了解如何在 Vue 中实现类似的地理数据展示功能,如果有任何问题,欢迎留言讨论。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/492790.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

量子通信学习路径(一)

量子通信是一门融合量子力学和通信技术的交叉学科&#xff0c;其核心目标是利用量子力学的特性&#xff08;如叠加态和纠缠&#xff09;实现信息传递和安全通信。以下是一个系统学习量子通信的完整大纲&#xff0c;从基础知识到实际应用逐步深入&#xff0c;帮助建立全面的知识…

QGIS修行记-如何使用QGIS进行换行标注

问题描述 QGIS根据指定的文字进行换行标注 项目的需要先描述一下&#xff1a; 需要标注的字段太长&#xff0c;需要进行换行标注需要换行的数据不确定有多少&#xff08;适用于批量数据的操作&#xff09;我需要根据指定文字进行换行 如&#xff1a;成山头海洋生态自然保护区…

指针的深入讲解

本章重点&#xff1a; 字符指针数组指针指针数组数组传参和指针传参函数指针函数指针数组指向函数指针数组的指针回调函数 我们在指针的初阶的时候主要讲了&#xff1a; 1.指针就是变量&#xff0c;用来存放地址&#xff0c;地址唯一标识一块内存空间 2.指针的大小是固定4个…

LWIP协议:三次握手和四次挥手、TCP/IP模型

一、三次握手&#xff1a;是客户端与服务器建立连接的方式&#xff1b; 1、客户端发送建立TCP连接的请求。seq序列号是由发送端随机生成的&#xff0c;SYN字段置为1表示需要建立TCP连接。&#xff08;SYN1&#xff0c;seqx&#xff0c;x为随机生成数值&#xff09;&#xff1b;…

WEB开发: 全栈工程师起步 - Python Flask +SQLite的管理系统实现

一、前言 罗马不是一天建成的。 每个全栈工程师都是从HELLO WORLD 起步的。 之前我们分别用NODE.JS 、ASP.NET Core 这两个框架实现过基于WebServer的全栈工程师入门教程。 今天我们用更简单的来实现&#xff1a; Python。 我们将用Python来实现一个学生管理应用&#xff0…

WatchAlert - 开源多数据源告警引擎

概述 在现代 IT 环境中&#xff0c;监控和告警是确保系统稳定性和可靠性的关键环节。然而&#xff0c;随着业务规模的扩大和数据源的多样化&#xff0c;传统的单一数据源告警系统已经无法满足复杂的需求。为了解决这一问题&#xff0c;我开发了一个开源的多数据源告警引擎——…

ABAP SQL 取日期+时间最新的一条数据

我们在系统对接的时候&#xff0c;外部系统可能会推送多个数据给到我们。 我们 SAP 系统的表数据中日期和时间是作为主键的&#xff0c;那么如果通过 ABAP SQL 取到最新日期的最新时间呢。 解决方案&#xff1a; 方式 1&#xff1a;SELECT MAX 可以通过两个 SELECT MAX 来取…

Vue3 + Element-Plus + vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS 父组件实现真正上传(最新保姆级)

Vue3 Element-Plus vue-draggable-plus 实现图片拖拽排序和图片上传到阿里云 OSS&#xff08;最新保姆级&#xff09;父组件实现真正上传 1、效果展示2、UploadImage.vue 组件封装3、相关请求封装4、SwiperConfig.vue 调用组件5、后端接口 1、效果展示 如果没有安装插件&…

容器化技术全面解析:Docker 与 Containerd 的深入解读

目录 Docker 简介 1. 什么是 Docker&#xff1f; 2. Docker 的核心组件 3. Docker 的主要功能 4. Docker 的优点 5. Docker 的使用场景 Containerd 简介 1. 什么是 Containerd&#xff1f; 2. Containerd 的核心特性 3. Containerd 的架构 4. Containerd 与 Docker 的…

LNMP+discuz论坛

0.准备 文章目录 0.准备1.nginx2.mysql2.1 mysql82.2 mysql5.7 3.php4.测试php访问mysql5.部署 Discuz6.其他 yum源&#xff1a; # 没有wget&#xff0c;用这个 # curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-7.repo[rootlocalhost ~]#…

Android Studio的笔记--BusyBox相关

BusyBox 相关 BusyBoxandroid上安装busybox和使用示例一、下载二、移动三、安装和设置环境变量四、使用 busybox源码下载和查看 BusyBox BUSYBOX BUSYBOX链接https://busybox.net/ 点击链接后如图 点击左边菜单栏的Get BusyBix中的Download Source 跳转到busybox 的下载源码…

LabVIEW与PLC点位控制及OPC通讯

在工业自动化中&#xff0c;PLC通过标准协议&#xff08;如Modbus、Ethernet/IP等&#xff09;与OPC Server进行数据交换&#xff0c;LabVIEW作为上位机通过OPC客户端读取PLC的数据并进行监控、控制与处理。通过这种方式&#xff0c;LabVIEW能够实现与PLC的实时通信&#xff0c…

C++ OpenGL学习笔记(1、Hello World空窗口程序)

终于抽出时间系统学习OpenGL 教程&#xff0c;同时也一步一步记录怎样利用openGL进行加速计算。 目录 1、环境准备1.1、库的下载1.2、库的选择及安装 2、OpenGL第一个项目&#xff0c;Hello World!2.1、新建hello world控制台项目2.2、配置openGL环境2.2.1 包含目录配置2.2.2 …

系统移植——Linux 内核顶层 Makefile 详解

一、概述 Linux Kernel网上下载的版本很多NXP等有自己对应的版本。需要从网上直接下载就可以。 二、Linux内核初次编译 编译内核之前需要先在 ubuntu 上安装 lzop 库 sudo apt-get install lzop 在 Ubuntu 中 新 建 名 为 “ alientek_linux ” 的 文 件夹 &#xff0c; …

ubuntu16.04ros-用海龟机器人仿真循线系统

下载安装sudo apt-get install ros-kinetic-turtlebot ros-kinetic-turtlebot-apps ros-kinetic-turtlebot-interactions ros-kinetic-turtlebot-simulator ros-kinetic-kobuki-ftdi sudo apt-get install ros-kinetic-rocon-*echo "source /opt/ros/kinetic/setup.bash…

Connection lease request time out 问题分析

Connection lease request time out 问题分析 问题背景 使用apache的HttpClient&#xff0c;我们知道可以通过setConnectionRequestTimeout()配置从连接池获取链接的超时时间&#xff0c;而Connection lease request time out正是从连接池获取链接超时的报错&#xff0c;这通常…

【文档搜索引擎】在内存中构造出索引结构(上)

文章目录 主要思路正排索引和倒排索引的表示1. 正排索引查询文档详细信息2. 倒排索引中查找关联词3. 新增文档正排索引倒排索引实现词频统计 主要思路 通过 Index 类&#xff0c;在内存中构造出索引结构。这个类要提供的方法&#xff1a; 给定一个 docId&#xff0c;在正排索…

单节点calico性能优化

在单节点上部署calicov3273后&#xff0c;发现资源占用 修改calico以下配置是资源消耗降低 1、因为是单节点&#xff0c;没有跨节点pod网段组网需要&#xff0c;禁用overlay方式网络(ipip&#xff0c;vxlan),使用route方式网络 配置calico-node的环境变量 CALICO_IPV4POOL_I…

tryhackme-Pre Security-HTTP in Detail(HTTP的详细内容)

任务一&#xff1a;What is HTTP(S)?&#xff08;什么是http&#xff08;s&#xff09;&#xff09; 1.What is HTTP? (HyperText Transfer Protocol)&#xff08;什么是 HTTP&#xff1f;&#xff08;超文本传输协议&#xff09;&#xff09; http是你查看网站的时候遵循的…

Javascript面试手撕常见题目(回顾一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词&#xff0c;你可以按照以下步骤进行操作&#xff1a; 将文章转换为小写&#xff1a;这可以确保单词的比较是大小写不敏感的。移除标点符号&#xff1a;标点符号会干扰单词的计数。将文章拆…