前端怎么完成从 SHP文件 到 GeoJSON 的转化?

GeoJSON & SHP文件 是什么

什么是 GeoJSON

GeoJSON是一种基于JSON(JavaScript Object Notation)的格式,用于表示地理空间数据。

一般来说,渲染地图时,我们直接拿到 GeoJSON ,按照其格式解析成地图需要的数据即可。

但是,现在有一种情况是,不提供 GeoJSON ,而是提供 ArcGIS 编辑的 SHP文件 ,来渲染地图。

什么又是 SHP 文件

SHP文件(Shapefile)是一种常用的地理信息系统(GIS)矢量数据格式,它广泛应用于各种GIS软件中。SHP并不是指的单个文件,而是由多个文件组成的一个文件集,这些文件共同描述了地理数据及其属性。

SHP文件包括:shp、prj、shx、cpg

这中间其实就是多了一个 shp文件------GeoJSON 的转化。

怎么转化

完成这个转化,有很多方法:

  • 方法一:专门的转化工具软件
  • 方法二:pythonjava 等对应的后端库
  • 方法三:js 前端库

一般来说,在程序开发中,方法一和软件系统结合性较低,一般不用。我们通常使用的方法是由后端来转化,速度相对较快。当然,前端也有转化的方法,而这正是本文的主题:使用shpjs进行转化。

先贴下仓库地址:shp2geojson: 本项目使用shpjs将SHP文件转化为GeoJSON (gitee.com)

上传 SHP文件集压缩包 即可解析为 GeoJSON ,如果对你有帮助,欢迎 start

下面来讲讲几个关键步骤的实现

实现方法

首先安装需要的npm包

cmd 复制代码
pnpm i jszip shpjs -d

这里jszip是为了将zip文件解析为二进制数据,直接使用zip文件File对象是会报错的

转化函数

js 复制代码
import JSZip from 'jszip'
import shp from 'shpjs'

/**
 * 将 shp 转化为 json
 * @param zip
 * @returns {Promise<*>}
 */
export const parseZip = async(zip) => {
  const jsZip = new JSZip()
  const zipData = await jsZip.loadAsync(zip)
  // 将zip文件转化为二进制流
  const data = await zipData.generateAsync({ type: 'arraybuffer' })
  return await shp(data)
}

调用时,将 File 对象传入即可

js 复制代码
const handleUpload = (file) => {
  // 判断文件是否为合规
  if(!fileValid(file)) {
    return false
  }
  // 转化
  parseZip(file).then(res => {
    jsonData.value = res
  })
  // 阻止 upload 组件默认上传事件
  return false
}

如果你的 SHP文件 当中需要解析中文,关注 cpg文件 即可

cpg文件 异常或者缺少 cpg文件 ,导致中文乱码,可以先做一个预处理

添加以下函数

js 复制代码
/**
 * 该函数可以重置 cpg文件编码格式
 * @param zip
 * @param format
 * @returns {Promise<*>}
 */
export const initCpg = async(zip, format) => {
  const jsZip = new JSZip()

  const zipData = await jsZip.loadAsync(zip)
  const fileNames = Object.keys(zipData.files)

  let hasCpg = false;
  // 遍历文件列表,删除后缀为 .cpg 的文件
  fileNames.forEach((fileName) => {
    // 检查文件扩展名是否为 .cpg
    if (fileName.endsWith('.cpg')) {
      hasCpg = true;
      // 删除原有的文件,插件新的编码格式的文件
      delete zipData.files[fileName]
      zipData.file(fileName, format)
    }
  })
  
  if(!hasCpg) {
    zipData.file(fileName, format)
  }

  return await zipData.generateAsync({ type: 'arraybuffer' })
}

更改转化函数

js 复制代码
/**
 * 将 shp 转化为 json
 * @param zip
 * @returns {Promise<*>}
 */
export const parseZip = async(zip) => {
  // 如果遇到实际编码格式与 cpg文件不符合的情况,可以使用下面注释的这段代码
  // format 取实际编码格式:'gb2312'或者'utf-8',或者其他编码类型
  const format = 'gb2312'
  const data = await initCpg(zip, format)
  return await shp(data)
}

资源

  1. shpjs - shpjs - npm (npmjs.com)
  2. jszip - jszip - npm (npmjs.com)
  3. 前端往读取到的压缩文件里添加文件,针对了shapefile(shp)压缩文件里没有.cfg导致中文乱码的情况 - doraemon22333 - 博客园 (cnblogs.com)
相关推荐
正小安14 分钟前
URL.createObjectURL 与 FileReader:Web 文件处理两大法宝的对比
前端·javascript
A黄俊辉A1 小时前
vue3中把封装svg图标为全局组件
前端·javascript·vue.js
老贾爱编程1 小时前
VUE实现刻度尺进度条
前端·javascript·vue.js
F2E_Zhangmo1 小时前
vue如何做到计算属性传参?
前端·javascript·vue.js
叫我小鹏呀2 小时前
vue3中el-table中点击图片放大时,被表格覆盖
前端·javascript·vue.js
我命由我123452 小时前
2.使用 VSCode 过程中的英语积累 - Edit 菜单(每一次重点积累 5 个单词)
前端·javascript·ide·vscode·学习·编辑器·学习方法
四季予你663 小时前
vue2 和 vue3 的区别
前端·javascript·vue.js
炒毛豆3 小时前
vue3+ant design vue实现可编辑表格弹出气泡弹出窗~
前端·javascript·vue.js
寰宇软件3 小时前
vue组件注册
前端·javascript·vue.js
林一怂儿3 小时前
H5 three.js 实现六年级观察物体
开发语言·javascript