前提:
1、准备工具:shapefile,jszip
2、我用的el自带的上传组件,当然其实主要还是js,所以就算你用的其他也可以
3、因为我项目中有把 that 指向 this ,所以文中that请自行改为this或者你定义的其他,以免出现指向问题
总结思路:
1、判断:获取上传的文件判断是zip还是shp
2、上传Zip时: 通过JsZip读取文件,寻找内部shp文件,转化为arraybuffer,再进行转geo
3、上传shp时:利用FileReader转为arraybuffer
4、转geo:利用shapefile插件(但是有多个面时他就会输出很多个。对不起,这里我文档一直没看懂,如果有大哥会更简便的方法可以告诉我)
好了,上代码
一、组件代码(对你来说作用不大,可看可不看)
<el-upload class="upload-demo" ref="upload" drag :http-request="uploadSectionFile" action="#" :limit="1" :show-file-list="false" accept=".zip,.shp">
<i class="el-icon-upload"></i>
<div class="el-upload__text">将文件拖到此处,或<em>点击上传</em></div>
</el-upload>
二、引入插件
import { open } from 'shapefile'
import JsZip from 'jszip'
三、方法
// 上传判断
uploadSectionFile (params) {
const file = params.file
const fileName = file.name
const isZip = fileName.indexOf('zip') !== -1
const isShp = fileName.indexOf('shp') !== -1
that.upName = fileName //我项目中需要传文件名字,所以这里保存下来
if (!(isZip || isShp)) {
that.$message.error('只能上传zip、shp格式!')
that.abortLoad() //因为手动上传,所以这里是取消上传
return false
} else {
isZip ? that.openZip(file) : that.toGeo(file)
}
},
// 为zip时,读取压缩包,选取shp文件
openZip (data) {
var newZip = new JsZip()
newZip.loadAsync(data).then(function (file) {
// 压缩包里的内容file.files
const fileList = Object.keys(file.files)
const pattern = new RegExp(/\S\.shp$/)
that.shpFile = fileList.find(i => pattern.test(i))
newZip.file(that.shpFile).async('arraybuffer') // 此处是压缩包中的shp文件,arraybuffer(此时在回调的参数中已经可以获取到上传的zip压缩包下的所有文件)
.then(function (content) { // 这个就是文件中的内容
that.shapefileOpen(content)
})
}).catch(err => {
// 是否是合法的zip包,解决rar包改后缀zip
console.log(err)
that.$message.error('请上传正确格式的文件')
})
},
// 转ArrayBuffer
toGeo (data) {
const reader = new FileReader()
reader.readAsArrayBuffer(data)
reader.onload = function (e) {
that.shapefileOpen(this.result)
}
},
// shapefile插件 shp转geo
shapefileOpen (content) {
open(content).then(source => source.read().then(function log (result) {
if (result.done) {
if (that.upList.length > 1) {
//这部分纯粹为了把很多平面拼在一起,你也可以根据自己的需求拼接
const cList = that.upList.map(ele => {
return ele.geometry.coordinates
})
const geojson = {
type: 'Feature',
properties: {},
geometry: {
type: 'MultiPolygon',
coordinates: cList
}
}
//上传接口
} else {
//上传接口
}
return
}
that.upList.push(result.value) //多个面时,会打印每一个,这样就先把他们放在一个集合里
return source.read().then(log)
})
).catch(error => console.error(error.stack))
},
最后总结:网上有很多shp转geo的帖子,感觉都比较简单,但是既有shp又有zip就比较少了,找了很多文章,然后根据我这边的要求,才得到最后这个结果
好像也能用shpjs,读取zip内容还要全一些,但是只能用于一个面的(反正最后我没用这个)