news 2026/6/12 6:38:08

GDB 文件导入流程分析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
GDB 文件导入流程分析

接口概述

基本信息

  • 接口功能: 导入 ZIP 文件(包含地理空间数据 GBD 格式文件)
  • 接口说明: 导入包含水储存量元数据的 ZIP 文件,支持多图层 GDB 格式解析

请求参数

{"file":MultipartFile,// ZIP 格式文件(必填)"overwriteMode":Boolean// 覆盖模式(可选,默认 false)}

依赖关系

Controller → Service → Utils → GDAL/GeoTools → Database ↓ ↓ ↓ ↓ Swagger ServiceImpl FileParser Entity ↑ ↑ ↑ Mapper FileHandleMapper

详细流程分析

第1步:文件接收与验证

控制器处理
@PostMapping("/biz/skscclysj/importZip")publicCommonResult<Map<String,Object>>importZip(@RequestParam("file")MultipartFilefile,@RequestParam(value="overwriteMode",defaultValue="false")BooleanoverwriteMode){returnCommonResult.data(dbSkscclysjService.importZipFile(file,overwriteMode));}

处理逻辑:

  1. 接收 MultipartFile 参数(ZIP 格式)
  2. 调用服务层处理文件
  3. 返回处理结果

第2步:服务层处理

核心流程
@Transactional(rollbackFor=Exception.class)publicMap<String,Object>importZipFile(MultipartFilefile,BooleanoverwriteMode){Map<String,Object>result=newHashMap<>();List<String>errorList=newArrayList<>();Map<String,Integer>layerCounts=newHashMap<>();inttotalCount=0;intsuccessCount=0;interrorCount=0;// 1. 创建临时目录StringtempDir=System.getProperty("java.io.tmpdir")+File.separator+"dbyts_import_"+IdUtil.simpleUUID();PathtempPath=Paths.get(tempDir);// 2. 文件格式校验StringoriginalFilename=file.getOriginalFilename();if(ObjectUtil.isEmpty(originalFilename)||!originalFilename.toLowerCase().endsWith(".zip")){thrownewCommonException("文件格式错误,仅支持ZIP格式文件");}// 3. 解压ZIP文件FileHandleUtils.unzipFile(file,tempPath);// 4. 查找GDB文件List<File>gdbFiles=FileHandleUtils.findGdbFiles(tempPath.toFile());if(gdbFiles.isEmpty()){thrownewCommonException("ZIP文件中未找到GDB格式文件");}// 5. 解析每个GDB文件for(FilegdbFile:gdbFiles){GbdFileParser.MultiLayerGdbResultgdbResult=GbdFileParser.parseMultiLayerGdbWithGdal(gdbFile,"dbyts");// 6. 处理每个图层的数据for(StringlayerName:gdbResult.getLayerNames()){List<?>layerData=gdbResult.getLayerDataMap().get(layerName);intlayerSuccess=processLayerData(layerName,layerData,overwriteMode,errorList);layerCounts.put(layerName,layerSuccess);totalCount+=layerData.size();successCount+=layerSuccess;errorCount+=(layerData.size()-layerSuccess);}}// 7. 返回结果result.put("totalCount",totalCount);result.put("successCount",successCount);result.put("errorCount",errorCount);result.put("layerCounts",layerCounts);result.put("errorDetail",errorList);returnresult;}

第3步:文件处理工具 (FileHandleUtils)

文件解压功能
publicstaticvoidunzipFile(MultipartFilefile,PathdestPath)throwsIOException{try(ZipInputStreamzipInputStream=newZipInputStream(file.getInputStream(),StandardCharsets.UTF_8)){ZipEntryentry;while((entry=zipInputStream.getNextEntry())!=null){if(!entry.isDirectory()){PathfilePath=destPath.resolve(entry.getName());Files.createDirectories(filePath.getParent());try(FileOutputStreamfos=newFileOutputStream(filePath.toFile())){IoUtil.copy(zipInputStream,fos);}}zipInputStream.closeEntry();}}}
GDB 文件查找
publicstaticList<File>findGdbFiles(Filedirectory){List<File>gdbFiles=newArrayList<>();File[]files=directory.listFiles();if(files!=null){for(Filefile:files){if(file.isDirectory()){// 检查是否为GDB目录(.gdb扩展名的目录)if(file.getName().toLowerCase().endsWith(".gdb")){gdbFiles.add(file);}else{// 递归查找子目录gdbFiles.addAll(findGdbFiles(file));}}elseif(isGdbFile(file.getName())){gdbFiles.add(file);}}}returngdbFiles;}

第4步:GDB 文件解析 (GbdFileParser)

多图层 GDB 解析
publicstaticMultiLayerGdbResultparseMultiLayerGdbWithGdal(FilegdbFile,StringdataType){MultiLayerGdbResultresult=newMultiLayerGdbResult();Map<String,List<?>>layerDataMap=newHashMap<>();try{// 使用 GDAL 解析 GDB 文件gdal.AllRegister();DataSourcedataSource=ogr.Open(gdbFile.getAbsolutePath());if(dataSource==null){thrownewRuntimeException("无法打开 GDB 文件: "+gdbFile.getAbsolutePath());}intlayerCount=dataSource.GetLayerCount();for(inti=0;i<layerCount;i++){Layerlayer=dataSource.GetLayer(i);StringlayerName=layer.GetName();// 根据数据类型过滤图层if(isValidLayer(layerName,dataType)){List<?>layerData=parseLayerData(layer,dataType);layerDataMap.put(layerName,layerData);}}result.setLayerDataMap(layerDataMap);result.setLayerNames(newArrayList<>(layerDataMap.keySet()));}catch(Exceptione){log.error("解析 GDB 文件失败: {}",gdbFile.getName(),e);thrownewRuntimeException("解析 GDB 文件失败: "+e.getMessage());}returnresult;}

第5步:图层数据处理

图层分发处理
privateintprocessLayerData(StringlayerName,List<?>layerData,booleanoverwriteMode,List<String>errorList){intsuccessCount=0;try{switch(layerName.toLowerCase()){case"hlscclysj":successCount=processHlData((List<DbHlscclysj>)layerData,overwriteMode,errorList);break;case"hpscclysj":successCount=processHpData((List<DbHpscclysj>)layerData,overwriteMode,errorList);break;}}catch(Exceptione){log.error("处理图层 {} 数据时发生异常: {}",layerName,e.getMessage(),e);errorList.add("图层 "+layerName+" 处理异常: "+e.getMessage());}returnsuccessCount;}

第6步:数据库操作

水库数据处理 (processSkData)
privateintprocessSkData(List<DbSkscclysj>layerData,booleanoverwriteMode,List<String>errorList){intsuccessCount=0;for(DbSkscclysjxzq:layerData){try{// 检查是否存在重复数据QueryWrapper<DbSkscclysj>queryWrapper=newQueryWrapper<>();queryWrapper.lambda().eq(DbSkscclysj::getSkbm,xzq.getSkbm());queryWrapper.lambda().eq(DbSkscclysj::getXjxzqdm,xzq.getXjxzqdm());queryWrapper.lambda().eq(DbSkscclysj::getSjclsj,xzq.getSjclsj());DbSkscclysjexistingXzq=this.getOne(queryWrapper);if(existingXzq!=null){if(overwriteMode){// 覆盖模式:更新现有数据xzq.setId(existingXzq.getId());this.baseMapper.updateWithGeometry(xzq);successCount++;}else{// 跳过模式:跳过重复数据errorList.add("水库代码 "+xzq.getSkbm()+" 已存在,跳过导入");}}else{// 新增数据,使用自定义方法处理几何数据xzq.setId(IdUtil.simpleUUID());this.baseMapper.insertWithGeometry(xzq);successCount++;}}catch(Exceptione){log.error("导入水库数据失败: {}",e.getMessage(),e);errorList.add("水库数据导入失败: "+e.getMessage());}}returnsuccessCount;}
数据库映射
<!-- 自定义插入方法,处理几何数据 --><insertid="insertWithGeometry"parameterType="vip.biz.db.skscclysj.entity.DbSkscclysj">insert into db_skscclysj ( id, delete_flag, create_user, create_time,update_time, update_user, ysdm, skbm, skmc, xjxzqmc, xjxzqdm, ssl, sslxdm, sxdxsjly, zkr, fsqsyxj, ksqsyxj, npjsymj, ksqccyl, fsqccyl, npjsccyl, sccljsff, ytlx, kjlx, bz, sjclr, sjclsj, jcr, jcsj, shhr, shsj, sxdxsj, jgdysj, sjsx, gxpl, sjnf ) values ( #{id}, #{deleteFlag}, #{createUser}, #{createTime}, #{updateTime}, #{updateUser}, #{ysdm},#{skbm}, #{skmc}, #{xjxzqmc}, #{xjxzqdm}, #{ssl}, #{sslxdm}, #{sxdxsjly}, #{zkr}, #{fsqsyxj}, #{ksqsyxj}, #{npjsymj}, #{ksqccyl}, #{fsqccyl}, #{npjsccyl}, #{sccljsff}, #{ytlx}, #{kjlx}, #{bz}, #{sjclr}, #{sjclsj}, #{jcr}, #{jcsj}, #{shhr}, #{shsj}, #{sxdxsj}, #{jgdysj}, #{sjsx}, #{gxpl}, #{sjnf} )</insert><!-- 自定义更新方法 --><updateid="updateWithGeometry"parameterType="vip.xxx.DbSkscclysj">UPDATE db_skscclysj<set><!-- 更新字段 --></set>WHERE id = #{id}</update>

技术依赖

关键依赖库

<!-- MyBatis-Plus --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency><!-- GeoTools(地理空间数据处理) --><dependency><groupId>org.geotools</groupId><artifactId>gt-main</artifactId><version>25.0</version></dependency><!-- GDAL(地理空间数据库) --><dependency><groupId>org.gdal</groupId><artifactId>gdal</artifactId><version>3.6.0</version></dependency><!-- Hutool(工具类) --><dependency><groupId>cn.hutool</groupId><artifactId>hutool-all</artifactId><version>5.8.16</version></dependency><!-- EasyExcel(Excel 处理) --><dependency><groupId>com.alibaba</groupId><artifactId>easyexcel</artifactId><version>3.3.2</version></dependency>

GDAL 环境配置

# Windows 环境变量配置PATH:C:\OSGeo4W64\bin GDAL_DATA: C:\OSGeo4W64\share\gdal PROJ_LIB: C:\OSGeo4W64\share\proj# JVM 参数配置-Djava.library.path=C:\OSGeo4W64\bin-Dgdal.data=C:\OSGeo4W64\share\gdal

错误处理

常见异常类型

  1. 文件格式错误: 文件不是 ZIP 格式
  2. 未找到 GDB 文件: ZIP 文件中没有 GDB 格式文件
  3. 图层解析失败: GDAL 解析 GDB 文件失败
  4. 数据重复: 根据唯一标识字段检查重复
  5. 数据库操作失败: 数据库插入或更新失败

异常处理策略

  • 事务回滚: 使用@Transactional确保数据一致性
  • 错误收集: 收集所有错误信息,不因单个错误中断
  • 日志记录: 详细记录处理过程和错误信息
  • 结果统计: 返回成功和失败的统计信息

总结

这个接口是一个复杂的多功能地理空间数据导入接口,通过分层架构实现了从文件接收到数据库存储的完整流程。该接口支持多种水体类型的导入,具有良好的错误处理和性能优化,为水体数据管理提供了强大的数据导入能力。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/12 6:32:51

XUnity游戏翻译神器:终极快速上手指南

XUnity游戏翻译神器&#xff1a;终极快速上手指南 【免费下载链接】XUnity.AutoTranslator 项目地址: https://gitcode.com/gh_mirrors/xu/XUnity.AutoTranslator 你是否曾经因为语言障碍而错过精彩的游戏内容&#xff1f;XUnity.AutoTranslator正是为解决这一痛点而生…

作者头像 李华
网站建设 2026/6/12 6:28:53

Matlab线性方程组求解工具包:四种高斯消元策略实现与自动对比

本文还有配套的精品资源&#xff0c;点击获取 简介&#xff1a;一套开箱即用的Matlab线性方程组求解工具&#xff0c;内置基础高斯消去、列主元、全主元和加权平衡四种实现方式&#xff0c;对应文件分别为gasuss.m、gasuss_colmax.m、gasuss_allmax.m和gasuss_weightmax.m。…

作者头像 李华
网站建设 2026/6/12 6:26:22

HPM6750 DMA+UART实战:手把手教你配置串口数据零拷贝传输(附完整代码)

HPM6750 DMAUART高效通信实战&#xff1a;从原理到零拷贝优化的完整实现在嵌入式系统开发中&#xff0c;UART串口通信是最基础也最常用的外设接口之一。然而当面对高速数据流或大吞吐量场景时&#xff0c;传统的基于中断的UART通信方式会暴露出明显的性能瓶颈——每个字节的收发…

作者头像 李华
网站建设 2026/6/12 6:24:57

计算机毕业设计之基于随机森林的医疗就诊系统

随着信息技术的飞速发展和互联网的普及&#xff0c;线上管理平台已成为当今社会经济发展的重要驱动力之一。本研究旨在设计并实现一个基于python的医疗就诊系统&#xff0c;在技术选择上&#xff0c;本项目采用了Python语言&#xff0c;MySQL数据库编程&#xff0c;使用django框…

作者头像 李华