美文网首页GIS加油站
shapefile.js实现shp数据的上传与展示

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

作者: 牛老师讲webgis | 来源:发表于2023-05-08 22:59 被阅读0次

    概述

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

    实现效果

    image.png

    实现代码

    1. 后端实现

    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.前端实现

    页面代码如下:

    <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实现代码如下:

    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}'
        })
      })
    }
    

    相关文章

      网友评论

        本文标题:shapefile.js实现shp数据的上传与展示

        本文链接:https://www.haomeiwen.com/subject/wvnlsdtx.html