前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >shapefile.js实现shp数据的上传与展示

shapefile.js实现shp数据的上传与展示

作者头像
lzugis
发布2023-05-11 09:13:44
1.4K0
发布2023-05-11 09:13:44
举报
文章被收录于专栏:跟牛老师一起学WEBGIS

概述

shapefile是常见的矢量数据格式,但是由于其文件组成结构很难在webgis上直接展示。本文通过expresscompressing实现打包后shapefile文件的上传,并结合shapefile.js实现shapefile数据的转换展示。

实现效果

image.png
image.png

实现代码

1. 后端实现

代码语言:javascript
复制
router.post('/upload/shp', function (req, res) {
  const filePath = path.resolve(__dirname, '../')
  const basePath = `${filePath}/${config.root}/shape/`
  fileUtils.dirExists(basePath).then(() => {
    fs.readFile(req.files[0].path, function (err, data) {
      const timestamp = Date.now()
      const des_file = basePath + timestamp + '.zip' ;
      const des_path = basePath + timestamp
      fs.writeFile(des_file, data, function (err) {
        compressing.zip.uncompress(des_file, des_path).then(() => {
          const file = fs.readdirSync(des_path)[0]
          const {ext, name} = path.parse(file);
          let fileName = ''
          if(ext) { // 文件
            fileName = `${name}.shp`
          } else { // 文件夹
            const _path = des_path + '/' + name
            const _file = fs.readdirSync(_path)[0]
            fileName = `${name}/${path.parse(_file).name}.shp`;
          }
          const response = {
            code: 200,
            url: `//${config.url}/shape/${timestamp}/${fileName}`
          };
          res.end(JSON.stringify(response));
        }).catch(() => {
          console.log('解压失败')
        })
      });
    });
  })
})

2.前端实现

页面代码如下:

代码语言:javascript
复制
<div id="app" class="container">
  <div class="map-tools">
    <el-upload
      ref="upload"
      :action="uploadAction"
      :multiple="false"
      :limit="1"
      :auto-upload="false"
      :before-upload="beforeUpload"
      :on-change="changeMethod"
      accept=".zip"
      :on-success="successMethod"
      :file-list="fileList"
      drag
      class="upload-demo">
      <i class="el-icon-upload"></i>
      <div class="el-upload__text">
        将文件拖到此处,或<em>点击上传</em><br>
        <b>只允许上传zip文件</b>
      </div>
    </el-upload>
    <el-button class="my-button" size="small" type="primary" @click="clearShow()">清除展示</el-button>
  </div>
  <div id="map" class="map"></div>
</div>

js实现代码如下:

代码语言:javascript
复制
let jsonformat = new ol.format.GeoJSON();

let vectorSource = new ol.source.Vector({
  features: []
})
let styleFunction = (feat) => {
  return new ol.style.Style({
    image: new ol.style.Circle({
      radius: 10,
      fill: new ol.style.Fill({color: 'rgba(0, 0, 255, 0.5)'}),
      stroke: new ol.style.Stroke({color: 'rgba(0, 0, 255, 1)', width: 6})
    }),
    stroke: new ol.style.Stroke({
      color: 'rgba(0, 0, 255, 1)',
      width: 3
    }),
    fill: new ol.style.Fill({color: 'rgba(0, 0, 255, 0.1)'}),
  })
}
let vectorLayer = new ol.layer.Vector({
  source: vectorSource,
  style: styleFunction,
  zIndex: 9
});

const app = new Vue({
  el: '#app',
  mounted() {
    this.initMap()
  },
  computed: {
    uploadAction() {
      return `//${window.location.hostname}/file/upload/shp`
    }
  },
  data() {
    return {
      fileList: []
    }
  },
  methods: {
    initMap() {
      window.map = new ol.Map({
        controls: ol.control.defaults({
          attribution: false
        }),
        target: 'map',
        layers: [getBaseLayer(), vectorLayer],
        view: new ol.View({
          center: [11598420.046414003, 4059611.6231072573],
          zoom: 4
        })
      });
    },
    beforeUpload(file) {
      const that = this
      if(!file.type === 'application/zip') {
        that.$message("只能上传*.zip格式压缩包", "error");
        return false;
      }
    },
    changeMethod() {
      const that = this
      that.$refs.upload.submit();
    },
    successMethod({code, url}) {
      if(code === 200) {
        this.$message('文件上传成功!')
        this.fileList = []
        shapefile.open(url)
          .then(source => source.read()
            .then(function log(result) {
              if (result.done) return;
              let features = jsonformat.readFeatures(result.value, {
                dataProjection: 'EPSG:4326',
                featureProjection: 'EPSG:3857',
              })
              vectorSource.clear()
              vectorSource.addFeatures(features);
              map.getView().fit(vectorSource.getExtent(), {
                padding: [100,100,100,100]
              })
            }))
          .catch(error => console.error(error.stack));
      }
    },
    clearShow() {
      vectorSource.clear()
    }
  }
})

function getBaseLayer(){
  return new ol.layer.Tile({
    source: new ol.source.XYZ({
      url: 'https://gac-geo.googlecnapps.cn/maps/vt?lyrs=m&x={x}&y={y}&z={z}'
    })
  })
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-05-09,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 概述
  • 实现效果
  • 实现代码
    • 1. 后端实现
      • 2.前端实现
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档