【问题总结+备忘录】上传一个shp文件能够读取其中的空间矢量字段,代码+采坑总结

需求描述

要求上传一个shp文件能够读取其中的空间矢量字段。

简单分析

  • SHP上传格式应该有两种(zip格式和.shp的格式
  • 文件内部可能存在多个空间矢量,结果以列表形式返回
  • 文件不大,使用MultipartFile上传上传即可
  • 结合geo-tools读取空间字段,并转换为WKT格式(由于geo-tools版本较多,同一个方法在不同的版本下不一定可行,这里使用的geotools版本是25-SNAPSHOT

代码

先上可行代码

@Value("${huicoo.temp_path}")
private  String FILE_UPLOAD_DIR;@Override
public RestResult transShpToWkt(MultipartFile file) throws IOException {// 先获取文件类型,判断是否符合预期String fileType = Objects.requireNonNull(file.getOriginalFilename(), "文件名不能为空").substring(file.getOriginalFilename().lastIndexOf(".") + 1);if (!"shp".equals(fileType)){ExceptionFactory.throwException(ResultCode.PARAM_ERROR , "文件类型错误");}File shapeFile = new File(FILE_UPLOAD_DIR+"/temp.shp");if (shapeFile.exists()) {shapeFile.delete();log.error("文件残留,已删除");}//        file.transferTo(shapeFile.getAbsoluteFile());log.info("开始拷贝文件 {}  ————> {}" , file.getName() , shapeFile.getAbsolutePath());FileUtils.copyInputStreamToFile(file.getInputStream() , shapeFile);ShapefileDataStoreFactory dataStoreFactory = new ShapefileDataStoreFactory();ShapefileDataStore dataStore = (ShapefileDataStore) dataStoreFactory.createDataStore(shapeFile.toURI().toURL());dataStore.setCharset(Charset.forName("UTF-8"));SimpleFeatureSource featureSource = dataStore.getFeatureSource();SimpleFeatureIterator featureIterator = featureSource.getFeatures().features();List<String> wktList = new ArrayList<>();while (featureIterator.hasNext()) {SimpleFeature feature = featureIterator.next();Collection<Property> properties = feature.getProperties();//遍历feature的propertiesfor (Property property : properties) {String value = "";if (null != property.getValue()) {value = property.getValue().toString();}if (StringUtils.hasText(value)){wktList.add(value);}}}featureIterator.close();dataStore.dispose();if (shapeFile.exists()) {shapeFile.delete();log.error("文件残留,已删除");}log.info("转换完成,长度{}",wktList.size());return RestResultUtils.success(wktList);
}

思路整理

  1. 判断文件类型
  2. 提取文件 or 提取流 (能力有限 ShapefileDataStore只找到从文件url创建的方法,选择提取文件
  3. 获取迭代器遍历数据,获取结果列表
  4. 关闭迭代器和流,返回结果

采坑总结

一、geotools版本不同,读取数据的写法也不相同

在设计之初,尝试用网上找到的遍历方法区读取数据,结果发现各种报错,最后是研究了之前同事的可行代码最终实现,可见geotools的版本对代码的兼容性不高,copy代码时也要仔细检查测试。

二、文件上传的中,transferTo方法的坑:部署后报错FileNotFoundException

解决的方法来源http://t.csdn.cn/7XXzL

使用transferTo在本地会报错,但是在linux部署环境下会报错如下

java.io.FileNotFoundException: /home/attachment/temp-file/temp.shx (No such file or directory)

image-20230828093056981

解决方法:

使用外置工具提供的流拷贝方法,而不是用MultipartFile自带的方法

FileUtils.copyInputStreamToFile(file.getInputStream() , shapeFile);

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上门服务系统|上门服务小程序如何提升生活质量?

上门服务其实就是本地生活服务的升级&#xff0c;上门服务包含很多行业可以做的。例如&#xff1a;厨师上门、上门家电维修、跑腿等等。如今各类本地化生活服务越来越受大家的喜爱。基于此市场愿景&#xff0c;我们来谈谈上门服务系统功能。 一、上门服务系统功能 1、预约服务…

springboot整合rabbitmq死信队列

springboot整合rabbitmq死信队列 什么是死信 说道死信&#xff0c;可能大部分观众大姥爷会有懵逼的想法&#xff0c;什么是死信&#xff1f;死信队列&#xff0c;俗称DLX&#xff0c;翻译过来的名称为Dead Letter Exchange 死信交换机。当消息限定时间内未被消费&#xff0c;…

算法通关村十三关 | 数组字符串加法专题

1. 数组实现整数加法 题目&#xff1a;LeetCode66&#xff0c;66. 加一 - 力扣&#xff08;LeetCode&#xff09; 思路 我们只需要从头到尾依次运算&#xff0c;用常量标记是否进位&#xff0c;需要考虑的特殊情况是digits [9,9,9]的时候进位&#xff0c;我们组要创建长度加1…

CNN 02(CNN原理)

一、卷积神经网络(CNN)原理 1.1 卷积神经网络的组成 定义 卷积神经网络由一个或多个卷积层、池化层以及全连接层等组成。与其他深度学习结构相比&#xff0c;卷积神经网络在图像等方面能够给出更好的结果。这一模型也可以使用反向传播算法进行训练。相比较其他浅层或深度神经…

二、数学建模之整数规划篇

1.定义 2.例题 3.使用软件及解题 一、定义 1.整数规划&#xff08;Integer Programming&#xff0c;简称IP&#xff09;&#xff1a;是一种数学优化问题&#xff0c;它是线性规划&#xff08;Linear Programming&#xff0c;简称LP&#xff09;的一个扩展形式。在线性规划中&…

格子游戏——并查集

Alice和Bob玩了一个古老的游戏&#xff1a;首先画一个 nn 的点阵&#xff08;下图 n3 &#xff09;。 接着&#xff0c;他们两个轮流在相邻的点之间画上红边和蓝边&#xff1a; 直到围成一个封闭的圈&#xff08;面积不必为 1&#xff09;为止&#xff0c;“封圈”的那个人就是…

53 个 CSS 特效 2

53 个 CSS 特效 2 这里是第 17 到 32 个&#xff0c;跟上一部分比起来多了两个稍微大一点的首页布局&#xff0c;上篇&#xff1a;53 个 CSS 特效 1&#xff0c;依旧&#xff0c;预览地址在 http://www.goldenaarcher.com/html-css-js-proj/&#xff0c;git 地址&#xff1a; …

Qt --- 自定义提示框 类似QMessagebox

QMessageBox::information(NULL, QString("title"), QString("I am information")); 以下是自定义提示框的代码&#xff0c;有图有真相&#xff01;提示框大部分都采用模态的形式&#xff0c;关于模态也不再多提&#xff01;所以父类为QDialog&#xff0c;…

IDEA启动两个Tomcat服务的方式 使用nginx进行反向代理 JMeter测试分布式情况下synchronized锁失效

目录 引出IDEA启动Tomcat两个端口的方式1.编辑配置2.添加新的端口-Dserver.port80833.service里面管理4.启动后进行测试 使用nginx进行反向代理反向代理多个端口运行日志查看启动关闭重启 分布式情况下synchronized失效synchronized锁代码启动tomcat两个端口nginx反向代理JMete…

Python3 字典

Python3 字典 字典是另一种可变容器模型&#xff0c;且可存储任意类型对象。 字典的每个键值 key>value 对用冒号 : 分割&#xff0c;每个对之间用逗号(,)分割&#xff0c;整个字典包括在花括号 {} 中 ,格式如下所示&#xff1a; d {key1 : value1, key2 : value2, key3…

列式存储引擎-内核机制-Parquet格式

列式存储引擎-内核机制-Parquet格式 Parquet是一种开源的列式存储结构&#xff0c;广泛应用于大数据领域。 1、数据模型和schema Parquet继承了Protocol Buffer的数据模型。每个记录由一个或多个字段组成。每个字段可以是atomic字段或者group字段。Group字段包含嵌套的字段&…

开源与专有软件:比较与对比

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…