文章目录

  • shapefile(.shp,.dbf,.prj)导入导出
    • 说明
    • 获取示例源码
    • 使用 `Shapefile` 导入
      • 文档
      • 说明
      • 代码示例
    • 使用 `mapshaper` 导入导出
      • 文档
      • 说明
      • 导入代码示例
      • 导出 shapefile 代码示例

shapefile(.shp,.dbf,.prj)导入导出

网页应用(Vue) 导入导出 shapefile(.shp,.dbf,.prj)

说明

如果网页应用只需要导入功能,只需使用 shapefile 库即可,但是 shapefile 库是无法实现导出功能的。
如果同时需导入导出功能,则需要使用 mapshaper 库。

shapefile-import

shapefile-export


获取示例源码

https://gitee.com/liushuai1125/shapefile-import-export

  1. 获取源码
  • 使用 shapefile 导入

    git clone https://gitee.com/liushuai1125/shapefile-import-export.git
    
  • 使用 mapshaper 导入导出
    git clone -b mapshaper https://gitee.com/liushuai1125/shapefile-import-export.git
    
  1. 安装依赖

    npm install # cnpm install
    
  2. 启动项目

    npm run serve
    

预览地址: http://localhost:9566/


使用 Shapefile 导入

流式 Shapefile 解析器

文档

  • npm仓库:https://www.npmjs.com/package/shapefile
  • Repository:github.com/mbostock/shapefile
  • Homepage:github.com/mbostock/shapefile

说明

在网页应用中,我们使用文档里面的解析示例解析时,发现是无法读取选上传的文件的。观察 shapefile 的源码可知

export function openShp(source, options) {if (typeof source === "string") {if (!/\.shp$/.test(source)) source += ".shp";source = path(source, options);} else if (source instanceof ArrayBuffer || source instanceof Uint8Array) {source = array(source);} else {source = stream(source);}return Promise.resolve(source).then(shp);
}

shpdbf 的参数类型可以是 ArrayBuffer、Uint8Array、shp 等类型,这样我们可以使用网页里的 FileReaderreadAsArrayBuffer 方法获取选择上传的文件数据,再传给 shapefile 进行解析。

代码示例

<template><div class="shapefile-parser"><div class="panel"><input ref="file" type="file" multiple accept=".shp,.dbf"><button @click="handleSelect">确认</button></div></div>
</template><script>
// eslint-disable-next-line no-unused-vars
import { open as shapeOpen, read as shapeRead } from 'shapefile'export default {name: 'ShapefileParser',data() {return {}},methods: {handleSelect() {let files = this.$refs.file.filesconsole.log(files, typeof files, 'files FileList')// files = Array.from(new Array(files.length), (i, idx) => files[idx]) // 等效下面写法files = Array.from(files) // FileList => Array, 方便使用 Array 方法console.log(files, typeof files, 'files Array')this.parseShapefile(files) // 解析选择的 shp 并绘制显示},parseShapefile(files) {const shpFile = files.find(f => f.name.endsWith('.shp'))const dbfFile = files.find(f => f.name.endsWith('.dbf'))// 可使用 Promise.all 优化为下面写法// this.readInputFile(shpFile, 'ArrayBuffer').then(async(fileData) => {//   const featureJsons = []////   await shapeOpen(fileData).then(async(source) => {//     await source.read().then(function log(result) {//       if (result.done) {//         return//       }//       featureJsons.push(result.value)//       console.log(result.value)//       return source.read().then(log)//     })//   }).catch(error => console.error(error.stack))////   console.log(featureJsons, typeof featureJsons, 'featureJsons')// }).catch(e => {//   console.log(e, typeof e, 'l e')// })const promises = [shpFile, dbfFile].map(i => this.readInputFile(i))Promise.all(promises).then(([shp, dbf]) => {// return shapeOpen(shp, dbf)//  `shapefile` 提供了 read 方法直接返回一个 FeatureCollection geojson,封装了类似于下面注释掉的代码return shapeRead(shp, dbf) }).then(async(source) => {// const featureJsons = []// await source.read().then(function log(result) {//   if (result.done) {//     return//   }//   featureJsons.push(result.value)//   console.log(result.value)//   return source.read().then(log)// })// console.log(featureJsons, typeof featureJsons, 'shapeOpen featureJsons')console.log(source, typeof source, 'shapeRead source')// do something}).catch(error => console.error(error.stack))},async readInputFile(file, type = 'ArrayBuffer') {// 读取文件return new Promise((resolve, reject) => {const reader = new FileReader()switch (type) {case 'ArrayBuffer':reader.readAsArrayBuffer(file)breakcase 'Text':reader.readAsText(file)breakcase 'BinaryString':reader.readAsBinaryString(file)breakcase 'DataURL':reader.readAsDataURL(file)break}reader.onload = function() {// this.result 就是读取到的文件的数据resolve(this.result)}reader.onerror = function() {reject(this)}})}}
}
</script><style scoped lang="scss">
.shapefile-parser {width: 1000px;height: 700px;margin: 0 auto;display: flex;flex-direction: column;.panel {padding: 10px 0;}
}
</style>

使用 mapshaper 导入导出

作为一个 WebGISer ,你如果不知道 mapshaper,那你一定是一个不合格的 WebGISer

mapshaper官网传送门

文档

  • npm仓库 https://www.npmjs.com/package/mapshaper
  • wiki github.com/mbostock/shapefile

说明

阅读 mapshaper.js 主要源码部分添加了以下一些 书签

有兴趣者可自行查看。

简而言之,在 mapshaper 里导入的数据被抽象为一个 datasetdataset里存放到处解析的数据,后续的操作都是在此基础上。
GeoJSON 文件生成的dataset 的格式如下图所示。

获取 dataset 需要用到 importContent 方法,该方法可以导出 .json.shp 类型的文件。
由源码上的说明可知,参数 obj 是一个对象,具有 filenamecontent 属性,content 属性的类型可以是 BufferArrayBufferStringObject

  // Parse content of one or more input files and return a dataset// @obj: file data, indexed by file type// File data objects have two properties://    content: Buffer, ArrayBuffer, String or Object//    filename: String or null//function importContent(obj, opts) {// ...}

导入代码示例

主要代码如下:

<script>
import mapshaper from 'mapshaper'
import { GeoJSON } from 'ol/format'
import GEOJSON from '@/assets/411600.json'const {importContent,guessInputType,exportDatasetAsGeoJSON
} = mapshaper.internalexport default {created() {// 直接 解析 geojson 字符串const content = this.analyze({ json: { filename: '411600.json', content: JSON.stringify(GEOJSON) }})console.log(content, typeof content, 'content')},methods: {handleSelect() {let files = this.$refs.file.filesconsole.log(files, typeof files, 'files FileList')// files = Array.from(new Array(files.length), (i, idx) => files[idx]) // 等效下面写法files = Array.from(files) // FileList => Array, 方便使用 Array 方法console.log(files, typeof files, 'files Array')// 解析 shpconst promises = files.map(i => this.readInputFileByType(i))Promise.all(promises).then((res) => {console.log(res, typeof res, 'readInputFileByType res')// 将选取的多个文件作为一个数据集return Object.fromEntries(res.map((i, idx) => {const filename = files[idx].name// 推断文件的解析类型return [guessInputType(filename, i), { filename: filename, content: i }]}))}).then((res) => {console.log(res, typeof res, 'merge res')const content = this.analyze(res)const readFeatures = new GeoJSON().readFeatures(content)console.log(readFeatures, typeof readFeatures, 'readFeatures')}).catch(error => console.error(error.stack))},analyze(obj) {// @obj: file data, indexed by file type// File data objects have two properties://    content: Buffer, ArrayBuffer, String or Object//    filename: String or null// obj: {json:{filename:'',content:''}}const dataset = importContent(obj)console.log(dataset, typeof dataset, 'dataset')const content = exportDatasetAsGeoJSON(dataset, {})console.log(content, typeof content, 'exportDatasetAsGeoJSON content')return content},readInputFileByType(file) {// 以 以下 后缀名结尾的文件 读取成文本内容const asTest = ['.prj', '.cpg', '.json'].map(i => file.name.endsWith(i)).includes(true)return this.readInputFile(file, asTest ? 'Text' : 'ArrayBuffer')},async readInputFile(file, type = 'ArrayBuffer') {// 读取文件return new Promise((resolve, reject) => {const reader = new FileReader()switch (type) {case 'ArrayBuffer':reader.readAsArrayBuffer(file)breakcase 'Text':reader.readAsText(file)breakcase 'BinaryString':reader.readAsBinaryString(file)breakcase 'DataURL':reader.readAsDataURL(file)break}reader.onload = function() {// this.result 就是读取到的文件的数据resolve(this.result)}reader.onerror = function() {reject(this)}})}}
}
</script>

导出 shapefile 代码示例

主要代码如下:

<script>
import mapshaper from 'mapshaper'
import GEOJSON from '@/assets/411600.json'
import JSZip from 'jszip'
import { saveAs } from 'file-saver'const {importContent,setDatasetCRS,exportFileContent
} = mapshaper.internalexport default {methods: {handleExport() {const dataset = importContent({ json: { filename: '411600.json', content: JSON.stringify(GEOJSON) }})// https://epsg.io/4326.esriwktsetDatasetCRS(dataset, { prj: 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137,298.257223563]],PRIMEM["Greenwich",0],UNIT["Degree",0.017453292519943295]]' })console.log(dataset, typeof dataset, 'dataset')this.saveDataset(dataset)},saveDataset(dataset, type = 'shapefile') {// format=shapefile|geojson|topojson|json|dbf|csv|tsv|svgconst fileContent = exportFileContent(dataset, { format: type })console.log(fileContent, typeof fileContent, 'fileContent')this.saveFileContent(fileContent)},saveFileContent(fileContent) {var zip = new JSZip()fileContent.forEach(i => {zip.file(i.filename, i.content)})zip.generateAsync({ type: 'blob' }, function updateCallback(metadata) {var msg = 'progression : ' + metadata.percent.toFixed(2) + ' %'if (metadata.currentFile) {msg += ', current file = ' + metadata.currentFile}console.log(msg)}).then((blob) => {// see FileSaver.jssaveAs(blob, 'example.zip')console.log('done !')}).catch(error => console.error(error.stack))}}
}
</script>

shapefile(.shp,.dbf,.prj)导入导出相关推荐

  1. arcgis中如何导出奥维可识别的图_如何将ArcGIS(SHP)文件导入到奥维中

    奥维支持导入北京54.西安80.CGCS2000等分带投影坐标系以及WGS-84经纬度坐标系以及自定义坐标系的SHP文件,可实现与ArcGIS的协同设计. 下面分别对奥维PC端和手机端导入SHP文件进 ...

  2. postgis导入导出shp文件

    postgis导入导出shp文件,主要有两种方式: 一.借助PostGIS shapefile工具 具体操作可参考     PostGIS教程四:加载空间数据 https://blog.csdn.ne ...

  3. 如何在地图上标注,并且导入导出kmz、kml、shp等格式

    官方网站:http://www.wolfmap.cn/ 打开WOLFMAP地图下载器,这里以百度地图为例.通过侧边栏切换到地图标注,新建一个文件夹.右键"我的标注"弹出菜单在选择& ...

  4. 【arcgis打开】中国幼儿园数据(cpg+dbf+prj+shp+shx+数据)

    [arcgis打开]中国幼儿园数据(cpg+dbf+prj+shp+shx+数据) 幼儿园(英文/德文:kindergarten),原称勘儿园,是几百年前从普鲁士引进的体制.旧称蒙养园.幼稚园.根据& ...

  5. PostGis基本操作-新建空间数据库与shp数据的导入

    场景 PostGresSQL简介与Windows上的安装教程: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/113981563 ...

  6. bcp 导入导出大全

    ******* 导出到excel EXEC master..xp_cmdshell 'bcp SettleDB.dbo.shanghu out c:/temp1.xls -c -q -S"G ...

  7. [转载]在SQL Server数据库之间进行数据导入导出,OPENDATASOURCE

    需要在c盘下先建立一个data.txt文件,然后在文件的第一行写上你要导出的列,不如说要导出id和name这两列,就在第一行写上 id,name 然后保存,使用下列SQL就可以了,你如果要保持原有的I ...

  8. SQL语句导入导出大全

    SQL语句导入导出大全 /******* 导出到excel EXEC master..xp_cmdshell ''bcp SettleDB.dbo.shanghu out c:\temp1.xls - ...

  9. Oracle 数据泵(IMPDP/EXPDP)导入导出总结

    Oracle数据泵导入导出是日常工作中常用的基本技术之一,它相对传统的逻辑导入导出要高效,这种特性更适合数据库对象数量巨大的情形,因为我日常运维的数据库对象少则几千,多则几万甚至几十万,所以传统exp ...

  10. Oracle创建用户、表空间、导入导出、...命令

    //创建临时表空间 create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserve ...

最新文章

  1. java和内存交互,java内存模型-内存间交互操作
  2. 印度太阳能企业争取对中、台、马实施反倾销税
  3. oracle删除数据文件
  4. appium+python 操作APP
  5. 《剑指offer》和为s的连续正数序列
  6. Swagger2 @ApiImplicitParam中dataType和paramType的区别?
  7. 基于深度极限学习机DELM的分类
  8. mysql not regexp_Mysql必知必会——使用正则表达式搜索(REGEXP)
  9. 微搭低代码入门教程02
  10. python如何下载pdfminer_在python中使用PDFMiner从PDF文件中提取文本?
  11. 中国医药中间体行业盈利状况与竞争趋势预测报告(新版)2022-2027年
  12. 微信、QQ上线国产系统UOS:界面曝光
  13. 成功解决无法写入输出文件,此实现不是Windows平台FIPS验证加密算法的一部分
  14. 三、Android网络开发
  15. 湖北武汉劳务员培训劳务管理五条新举措建筑七大员培训
  16. Excel 函数Min求最小值值为空时为零的情况如何处理,或者排除0怎么做
  17. 【系统架构】-如何评估软件架构
  18. Haiku将通过GSoC获得对x86_64的支持
  19. 使用Python控制手机(一)
  20. 【JavaSE基础】学会区分和使用重载和重写

热门文章

  1. cocos creator 微信小游戏 世界排行榜制作教程(云数据库)
  2. html英雄联盟网页,Html+Css+JQuery实现简易英雄联盟官网
  3. 英雄联盟游戏语音无法连接服务器,英雄联盟语音连不上是电脑哪里出问题了
  4. win10 如何设置绿色保护色?
  5. ***YZJ的牛肉干***
  6. Win 10 版NVIDIA GeForce GTX 1060显卡驱动的下载及飞桨(Paddle)的安装
  7. java 泛型 参数传递子类_超类的Java泛型,但并非所有子类都想定义类型参数
  8. 超详细3D建模教学他来了
  9. 二级域名间相互请求 ajax跨域请求
  10. php 判断是否是拼音,php汉字转拼音的示例