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

OpenLayers 上传Shapefile文件

前言

Shapefile是一种矢量数据文件,使用起来简单、方便。作为数据交换文件,在WebGIS开发中,经常需要实现实现上传shp文件。比如用户需要上传选址范围线或者叠加分析范围,都会选择上传shp文件。本文实现用户即可上传一个单独的shp文件,也可以上传包含所有shp文件的压缩包。

在开始之前,请提前下载好所需引用文件:jszip:https://cdn.jsdelivr.net/npm/jszip@3.10.1/dist/jszip.min.js

shapefile:https://cdn.jsdelivr.net/npm/shapefile@0.6.6/dist/shapefile.min.js

1. 上传Shp文件

使用input元素,设置type属性为file,通过accept属性过滤上传文件格式。

<div class="upload-shp"><input type="file" class="select-file" accept=".zip,.shp">
</div>

2. 监听上传文件事件

获取input元素,监听change事件,在事件参数对象中有个属性files,在其中包含上传文件的信息,文件名、上传文件和上传时间戳等。通过截取文件后缀判断文件类型,因为需要识别用户上传的是单独的shp文件还是包含完整shp文件的压缩包。

const inputEle = document.querySelector(".select-file")
// 监听文件上传事件
inputEle.addEventListener('change', evt => {console.log("change事件参数:", evt.target.files)const file = evt.target.files[0]const fileName = file.nameconst isZip = fileName.indexOf('.zip') > -1isZip ? uploadZip(file) : uploadShp(file)
})

3. 上传压缩包

请先确保已经引入了jszip文件。通过loadAsync方法加载文件数据,然后使用file方法将文件数据转换为**‘arraybuffer’**,最后再读取shp数据并将其添加到地图上。

function uploadZip(data) {const zip = new JSZip()zip.loadAsync(data).then(file => {const fileList = Object.keys(file.files)const regExp = new RegExp(/S.shp$/)const shpFile = fileList.find(file => regExp.test(file))zip.file(shpFile).async('arraybuffer').then(content => {openShapefile(content)})}).catch(err => {// 请上传正确格式的文件!console.error(err)})
}

4. 上传Shp文件

对于单独的shp文件,只需使用FileReader对象,调用readAsArrayBuffer方法将文件数据转换为**‘arraybuffer’**,然后再读取shp数据并将其添加到地图上。

// 上传Shp文件
function uploadShp(file) {const reader = new FileReader()reader.readAsArrayBuffer(file)reader.onload = (e) => {openShapefile(e.target.result)}
}

5. 读取Shp数据

通过引入shapefile文件,然后调用read方法读取数据并将**'arraybuffer’转换为GeoJSON数据格式。不过注意的是,read方法在读取数据时是一个异步操作,所以需要将其改为同步操作,例子中使用的是asyncawait方法。如果用户需要限制上传的文件类型的话,可以通过判断GeoJSON**对象type属性进行限制,如限制只能上传面文件数据。更多GeoJSON数据格式请参考:GeoJSONshujujainjian。如何添加GeoJSON数据请参考:添加GeoJSONshuju1。

// 读取shp文件
async function openShapefile(content) {// GeoJSON 对象const featureCollection = await shapefile.read(content)console.log("featureCollection:", featureCollection);const geoType = featureCollection.features[0].geometry.type// 限制上传文件类型// const isPolygon = geoType === 'Polygon' || geoType === 'MultiPolygon'// if (!isPolygon) {//     if (geoType === 'Point') {// 				 console.error('当前上传的文件类型为 "Point",请上传面对象!')//     } else if (geoType === 'LineString') {//         console.error('当前上传的文件类型为 "LineString",请上传面对象!')//     }//     return// }const geoJson = new ol.format.GeoJSON()const features = geoJson.readFeatures(featureCollection)// 添加对象addGeoJSON2Map(featureCollection, "", map)
}

6. 完整代码

其中libs文件夹下的包需要更换为自己下载的本地包或者引用在线资源。

<!DOCTYPE html>
<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /><title>OpenLayers 上传Shapefile文件</title><meta charset="utf-8" /><link rel="stylesheet" href="../../libs/css/ol9.2.4.css"><script src="../../js/config.js"></script><script src="../../js/util.js"></script><script src="../../libs/js/ol9.2.4.js"></script><script src="../../libs/js/jszip.min.js"></script><script src="../../libs/js/shapefile.min.js"></script><style>* {padding: 0;margin: 0;font-size: 14px;font-family: '微软雅黑';}html,body {width: 100%;height: 100%;}#map {position: absolute;top: 50px;bottom: 0;width: 100%;}#top-content {position: absolute;width: 100%;height: 50px;line-height: 50px;background: linear-gradient(135deg, #ff00cc, #ffcc00, #00ffcc, #ff0066);color: #fff;text-align: center;font-size: 32px;}#top-content span {font-size: 32px;}.upload-shp {position: absolute;right: 50px;top: 80px;padding: 10px 20px;color: #fff;border-radius: 5px;border: 1px solid #50505040;background: linear-gradient(135deg, #c850c0, #4158d0);}.upload-shp:hover {cursor: pointer;filter: brightness(120%);background: linear-gradient(135deg, #eb3ddf, #0931fb);}.select-file {width: 180px;}</style>
</head><body><div id="top-content"><span>OpenLayers 上传Shapefile文件</span></div><div id="map" title="地图显示"></div><div class="upload-shp"><input type="file" class="select-file" accept=".zip,.shp"></div>
</body></html><script>//地图投影坐标系const projection = ol.proj.get('EPSG:3857');//==============================================================================////============================天地图服务参数简单介绍==============================////================================vec:矢量图层==================================////================================img:影像图层==================================////================================cva:注记图层==================================////======================其中:_c表示经纬度投影,_w表示球面墨卡托投影================////==============================================================================//const TDTImgLayer = new ol.layer.Tile({title: "天地图影像图层",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + TDTTOKEN,attibutions: "天地图影像描述",crossOrigin: "anoymous",wrapX: false})})const TDTImgCvaLayer = new ol.layer.Tile({title: "天地图影像注记图层",source: new ol.source.XYZ({url: "http://t0.tianditu.com/DataServer?T=cia_w&x={x}&y={y}&l={z}&tk=" + TDTTOKEN,attibutions: "天地图注记描述",crossOrigin: "anoymous",wrapX: false})})const map = new ol.Map({target: "map",loadTilesWhileInteracting: true,view: new ol.View({center: [102.845864, 25.421639],zoom: 6.5,worldsWrap: false,minZoom: 1,maxZoom: 20,projection: 'EPSG:4326',}),layers: [TDTImgLayer],// 地图默认控件controls: ol.control.defaults.defaults({zoom: false,attribution: false,rotate: false})})map.on('click', evt => {console.log("获取地图坐标:", evt.coordinate)})const inputEle = document.querySelector(".select-file")// 监听文件上传事件inputEle.addEventListener('change', evt => {// console.log("change事件参数:", evt.target.files)const file = evt.target.files[0]const fileName = file.nameconst isZip = fileName.indexOf('.zip') > -1isZip ? uploadZip(file) : uploadShp(file)})// 监听上传完成事件inputEle.addEventListener('load', evt => {console.log("load事件参数:", evt)})// 监听上传错误事件inputEle.addEventListener('error', evt => {console.log("error事件参数:", evt)})// 上传Shp压缩包function uploadZip(data) {const zip = new JSZip()zip.loadAsync(data).then(file => {const fileList = Object.keys(file.files)const regExp = new RegExp(/\S\.shp$/)const shpFile = fileList.find(file => regExp.test(file))zip.file(shpFile).async('arraybuffer').then(content => {openShapefile(content)})}).catch(err => {// '请上传正确格式的文件!'console.error(err)       })}// 上传Shp文件function uploadShp(file) {const reader = new FileReader()reader.readAsArrayBuffer(file)reader.onload = (e) => {openShapefile(e.target.result)}}// 读取shp文件async function openShapefile(content) {const featureCollection = await shapefile.read(content)// console.log("featureCollection:", featureCollection);const geoType = featureCollection.features[0].geometry.type// const isPolygon = geoType === 'Polygon' || geoType === 'MultiPolygon'// if (!isPolygon) {//     if (geoType === 'Point') {// this.$message.error('当前上传的文件类型为 "Point",请上传面对象!')// console.error('当前上传的文件类型为 "Point",请上传面对象!')//     } else if (geoType === 'LineString') {//         this.$message.error('当前上传的文件类型为 "LineString",请上传面对象!')//         console.error('当前上传的文件类型为 "LineString",请上传面对象!')//     }//     return// }const geoJson = new ol.format.GeoJSON()const features = geoJson.readFeatures(featureCollection)// 添加对象addGeoJSON2Map(featureCollection, "", map)}
</script>

OpenLayers示例数据下载,请回复关键字:ol数据

全国信息化工程师-GIS 应用水平考试资料,请回复关键字:GIS考试

【GIS之路】 已经接入了智能助手,欢迎关注,欢迎提问。

欢迎访问我的博客网站-长谈GIShttp://shanhaitalk.com

都看到这了,不要忘记点赞、收藏 + 关注

本号不定时更新有关 GIS开发 相关内容,欢迎关注 !

http://www.lqws.cn/news/518113.html

相关文章:

  • 基于 Python 的批量文件重命名软件设计与实现
  • 智哪儿专访 | Matter中国提速:开放标准如何破局智能家居“生态孤岛”?
  • 舵机在智能家居里的应用
  • 第k个数字
  • 归并排序算法
  • 企业内部安全组网技术解析:安全通道选型、零信任架构与数据合规加密防护
  • 计算机网络-----详解HTTP协议
  • 基于springboot+vue的智慧农业专家远程指导系统
  • 苹果签名应用掉签频繁原因排查,以及如何避免
  • Mysql使用窗口函数查询
  • 左神算法之有序二维矩阵中的目标值查找
  • vscode管理go多个版本
  • 英飞凌高性能BMS解决方案助力汽车电动化
  • 【世纪龙科技】新能源汽车VR虚拟体验展示馆-解锁认知新维度
  • 灰度发布怎么保证数据库一致的
  • AES加密:为你的PDF文档加上一道钢铁防线
  • Kubernetes、Docker Swarm 与 Nomad 容器编排方案深度对比与选型指导
  • 论文阅读:A Survey on Large Language Models for Code Generation
  • 不用vue,只用html,即可简单实现electron项目
  • 鸿蒙OpenHarmony[Disassembler反汇编工具]ArkTS运编译工具链
  • IntelliJ IDEA 社区版安装终极教程(2025 最新图文详解)
  • 微信小程序中scss、ts、wxml
  • React19源码系列之 API (react)
  • 惠普HP Laser MFP 116w 打印机信息
  • 深度解析Lucene IndexWriter 性能优化
  • 银河麒麟高级服务器操作系统(全架构)OpenGauss 数据库部署手册
  • Fisco Bcos学习 - 控制台搭建和基本使用
  • SpringBoot中5种拦截器使用场景
  • Odoo OWL 前端开发:ORM 与 RPC 服务的选择
  • HarmonyOS 5分布式数据库有哪些性能指标?