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

news2024/11/25 7:11:34

概述

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/507616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Android 引入hunter-debug监测代码运行时函数耗时和参数及返回值,Java(1)

Android 引入hunter-debug监测代码运行时函数耗时和参数及返回值&#xff0c;Java&#xff08;1&#xff09; &#xff08;1&#xff09;在工程的根build.gradle文件里面添加cn.quinnchen.hunter:hunter-debug-plugin引用&#xff1a; buildscript {repositories {mavenCentra…

SAP CAP篇三:定义Model

SAP CAP篇一:快速创建一个Service&#xff0c;基于Java的实现 SAP CAP篇二&#xff1a;为Service加上数据库支持 文章目录 理解CAP的ModelDomain-Driven DesignKISSBasic TypesCommon Reuse TypecuidmanagedtemporalCountry, Currency, LanguagecodeList Assocation & Comp…

匹配算法之 匈牙利算法详解

参考&#xff1a; 算法学习笔记(5)&#xff1a;匈牙利算法漫谈匈牙利算法匈牙利算法、KM算法匈牙利算法&#xff08;二分图&#xff09;通俗易懂小白入门&#xff09;二分图最大匹配——匈牙利算法多目标跟踪之数据关联&#xff08;匈牙利匹配算法和KM算法&#xff09;【小白学…

手把手教你使用gtest写单元测试

开源框架&#xff1a;gtest&#xff0c;它主要用于写单元测试&#xff0c;检查真自己的程序是否符合预期行为。这不是QA&#xff08;测试工程师&#xff09;才学的&#xff0c;也是每个优秀后端开发codoer的必备技能。 本期博文内容及使用的demo&#xff0c;参考&#xff1a; …

40、Java 并发编程基础 ①

目录 一、进程&#xff08;Process&#xff09;二、线程&#xff08;Thread&#xff09;三、线程的串行四、多线程五、多线程原理六、多线程优缺点七、Java 的默认线程八、开启新线程(1) new Thread()(2) 继承 Thread&#xff0c;重写 run 方法(3) run() 和 start() 九、多线程…

AutoCV第八课:3D基础

目录 3D基础前言1. nuScenes数据集2. nuScenes数据格式3. 点云可视化总结 3D基础 前言 手写 AI 推出的全新保姆级从零手写自动驾驶 CV 课程&#xff0c;链接。记录下个人学习笔记&#xff0c;仅供自己参考。 本次课程主要学习点云数据的可视化。 课程大纲可看下面的思维导图。…

【Shiro】SimpleAuthenticationInfo如何验证password

一、前言 通篇的关键就是知道ShiroRealm类重写的doGetAuthenticationInfo这个方法&#xff0c;到底是谁的方法。 从上图我们可以知道&#xff0c;ShiroRealm最终继承到了AuthenticatingRealm这个方法。 二、自定义的ShiroRealm类 ps&#xff1a;该图中①上的注释是没看过底…

Jetpack之livedata原理

1.LiveData是什么&#xff1f; 只有在生命周期处于started和resumed时。livedata才会更新观察者 2.Livedata的各种使用方式 1.更新数据 class MainActivity : AppCompatActivity() {override fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceSta…

c++之函数对象和谓词

目录 函数对象&#xff1a; 谓词&#xff1a; 一元谓词函数举例如下 二元谓词举例如下 函数对象和函数的区别 一元谓词的案例 二元函数对象案例 二元谓词案例 函数对象&#xff1a; 重载函数调用操作符的类&#xff0c;其对象常称为函数对象&#xff08;function obj…

内网渗透之linux到linux横向移动-ssh

0x01 一般情况下SSH密钥存放在~/.ssh/目录下&#xff0c;也可以文件中搜索已保存的SSH凭证 ~/.ssh/config ~/.ssh/known_hosts ~/.bash_history grep -ir "BEGIN RSA PRIVATE KEY" /* grep -ir "BEGIN DSA PRIVATE KEY" /* grep -ir "BEGIN OPENSSH…

SpringBoot入门学习笔记-快速认识

SpringBoot入门学习笔记-快速认识 快速案例入门案例解析parentstarter引导类内嵌tomcat ) 快速案例 在controller定义一个类 package com.ustc.sp5.controller;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.…

redis 数据类型简介

redis 数据类型 redis的五种数据类型是&#xff1a;1、string&#xff08;字符串&#xff09;&#xff1b;2、hash&#xff08;哈希&#xff09;&#xff1b;3、list&#xff08;列表&#xff09;&#xff1b;4、set&#xff08;集合&#xff09;&#xff1b;5、sort set &…

QT初体验:手把手带你写一个自己的串口助手

前言 本文记录一下用QT Creator 写一个基本功能齐全的串口助手的过程&#xff0c;整个工程只有几百行代码&#xff0c;跟着做下来对新手来说可以更快了解整个QT项目的开发过程和一些常用控件的使用方法。对新手学习QT能增强信心&#xff0c;话不多说&#xff0c;正文开始 先看…

Mysql日志redo log、bin log、undo log 区别与作用及二阶段提交

一、redo log 重做日志 作用&#xff1a;确保事务的持久性。防止在发生故障的时间点&#xff0c;尚有脏页未写入磁盘&#xff0c;在重启mysql服务的时候&#xff0c;根据redo log进行重做&#xff0c;从而达到事务的持久性这一特性。 内容&#xff1a;物理格式的日志&#x…

46-Dockerfile-USER/WORKDIR指令

USER/WORKDIR指令 前言USER作用格式使用示例 WORKDIR作用格式说明使用示例 前言 本篇来学习下Dockerfile中的USER/WORKDIR指令 USER 作用 指定运行容器时的用户名或 UID&#xff0c;后续的RUN等指令也会使用指定的用户身份 说明&#xff1a; USER 只是帮助我们切换到指定的…

12_Uboot启动流程_4

目录 images全局变量 do_bootz函数 bootz_start函数 do_bootm_states函数 bootm_os_get_boot_func函数 do_bootm_linux函数 images全局变量 不管是bootz还是bootm命令,在启动Linux内核的时候都会用到一个重要的全局变量:images, images在文件cmd/bootm.c中有如下定义: i…

【2023/05/09】Scratch

Hello&#xff01;大家好&#xff0c;我是霜淮子&#xff0c;2023倒计时第4天。 Share The mighty desert is burning for the love of a blade of grass who shaks her head and laughs and flies away. 译文&#xff1a; 无垠的沙漠热烈追求一叶绿草的爱&#xff0c;她摇摇…

PCL中点云分割算法简析

文章目录 前言一、点云分割算法简介1.1 基于RANSAC的点云分割1.2 基于聚类的点云分割1.2.1 欧式聚类分割 1.3 基于深度学习的点云分割 二、算法示例2.1 基于RANSAC的平面分割2.2 欧式聚类2.3 基于PointNet的点云分割 总结 前言 点云分割算法广泛应用于激光遥感、无人驾驶、工业…

centos安装nginx教程

安装所需环境 Nginx 是 C语言 开发&#xff0c;建议在 Linux 上运行&#xff0c;当然&#xff0c;也可以安装 Windows 版本&#xff0c;本篇则使用 CentOS 7 作为安装环境。 一. gcc 安装 安装 nginx 需要先将官网下载的源码进行编译&#xff0c;编译依赖 gcc 环境&#xff0c…

【ESD专题】案例:TVS管钳位电压能不能通过TLP测试数据表征?

这几天遇到一个问题,就是还是想说TVS管导入的时候需要进行IEC61000-4-2 8kV接触静电的钳位波形测试。 比如有时可以看到规格书中给出对应的在IEC61000-4-2 8kV接触时的真实钳位波形: 根据我们文章【ESD专题】TVS管的选择的误区及钳位电压测试方法和一些参考手册所说…