shapefile(.shp,.dbf,.prj)导入导出
文章目录
- 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
- 获取源码
- 使用
shapefile
导入git clone https://gitee.com/liushuai1125/shapefile-import-export.git
- 使用
mapshaper
导入导出git clone -b mapshaper https://gitee.com/liushuai1125/shapefile-import-export.git
安装依赖
npm install # cnpm install
启动项目
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);
}
shp
和 dbf
的参数类型可以是 ArrayBuffer、Uint8Array、shp 等类型,这样我们可以使用网页里的 FileReader
的 readAsArrayBuffer
方法获取选择上传的文件数据,再传给 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
里导入的数据被抽象为一个 dataset
,dataset
里存放到处解析的数据,后续的操作都是在此基础上。
由 GeoJSON
文件生成的dataset
的格式如下图所示。
获取 dataset
需要用到 importContent
方法,该方法可以导出 .json
和 .shp
类型的文件。
由源码上的说明可知,参数 obj
是一个对象,具有 filename
和 content
属性,content
属性的类型可以是 Buffer
、ArrayBuffer
、String
、Object
。
// 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)导入导出相关推荐
- arcgis中如何导出奥维可识别的图_如何将ArcGIS(SHP)文件导入到奥维中
奥维支持导入北京54.西安80.CGCS2000等分带投影坐标系以及WGS-84经纬度坐标系以及自定义坐标系的SHP文件,可实现与ArcGIS的协同设计. 下面分别对奥维PC端和手机端导入SHP文件进 ...
- postgis导入导出shp文件
postgis导入导出shp文件,主要有两种方式: 一.借助PostGIS shapefile工具 具体操作可参考 PostGIS教程四:加载空间数据 https://blog.csdn.ne ...
- 如何在地图上标注,并且导入导出kmz、kml、shp等格式
官方网站:http://www.wolfmap.cn/ 打开WOLFMAP地图下载器,这里以百度地图为例.通过侧边栏切换到地图标注,新建一个文件夹.右键"我的标注"弹出菜单在选择& ...
- 【arcgis打开】中国幼儿园数据(cpg+dbf+prj+shp+shx+数据)
[arcgis打开]中国幼儿园数据(cpg+dbf+prj+shp+shx+数据) 幼儿园(英文/德文:kindergarten),原称勘儿园,是几百年前从普鲁士引进的体制.旧称蒙养园.幼稚园.根据& ...
- PostGis基本操作-新建空间数据库与shp数据的导入
场景 PostGresSQL简介与Windows上的安装教程: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/113981563 ...
- bcp 导入导出大全
******* 导出到excel EXEC master..xp_cmdshell 'bcp SettleDB.dbo.shanghu out c:/temp1.xls -c -q -S"G ...
- [转载]在SQL Server数据库之间进行数据导入导出,OPENDATASOURCE
需要在c盘下先建立一个data.txt文件,然后在文件的第一行写上你要导出的列,不如说要导出id和name这两列,就在第一行写上 id,name 然后保存,使用下列SQL就可以了,你如果要保持原有的I ...
- SQL语句导入导出大全
SQL语句导入导出大全 /******* 导出到excel EXEC master..xp_cmdshell ''bcp SettleDB.dbo.shanghu out c:\temp1.xls - ...
- Oracle 数据泵(IMPDP/EXPDP)导入导出总结
Oracle数据泵导入导出是日常工作中常用的基本技术之一,它相对传统的逻辑导入导出要高效,这种特性更适合数据库对象数量巨大的情形,因为我日常运维的数据库对象少则几千,多则几万甚至几十万,所以传统exp ...
- Oracle创建用户、表空间、导入导出、...命令
//创建临时表空间 create temporary tablespace test_temp tempfile 'E:\oracle\product\10.2.0\oradata\testserve ...
最新文章
- java和内存交互,java内存模型-内存间交互操作
- 印度太阳能企业争取对中、台、马实施反倾销税
- oracle删除数据文件
- appium+python 操作APP
- 《剑指offer》和为s的连续正数序列
- Swagger2 @ApiImplicitParam中dataType和paramType的区别?
- 基于深度极限学习机DELM的分类
- mysql not regexp_Mysql必知必会——使用正则表达式搜索(REGEXP)
- 微搭低代码入门教程02
- python如何下载pdfminer_在python中使用PDFMiner从PDF文件中提取文本?
- 中国医药中间体行业盈利状况与竞争趋势预测报告(新版)2022-2027年
- 微信、QQ上线国产系统UOS:界面曝光
- 成功解决无法写入输出文件,此实现不是Windows平台FIPS验证加密算法的一部分
- 三、Android网络开发
- 湖北武汉劳务员培训劳务管理五条新举措建筑七大员培训
- Excel 函数Min求最小值值为空时为零的情况如何处理,或者排除0怎么做
- 【系统架构】-如何评估软件架构
- Haiku将通过GSoC获得对x86_64的支持
- 使用Python控制手机(一)
- 【JavaSE基础】学会区分和使用重载和重写
热门文章
- cocos creator 微信小游戏 世界排行榜制作教程(云数据库)
- html英雄联盟网页,Html+Css+JQuery实现简易英雄联盟官网
- 英雄联盟游戏语音无法连接服务器,英雄联盟语音连不上是电脑哪里出问题了
- win10 如何设置绿色保护色?
- ***YZJ的牛肉干***
- Win 10 版NVIDIA GeForce GTX 1060显卡驱动的下载及飞桨(Paddle)的安装
- java 泛型 参数传递子类_超类的Java泛型,但并非所有子类都想定义类型参数
- 超详细3D建模教学他来了
- 二级域名间相互请求 ajax跨域请求
- php 判断是否是拼音,php汉字转拼音的示例