【GIS系列】多源异构原始影像解析:策略模式与规则引擎的应用

news/2024/9/18 20:59:06/ 标签: 算法, spring boot, spring cloud, java

作者:后端小肥肠

🍇 我写过的文章中的相关代码放到了gitee,地址:xfc-fdw-cloud: 公共解决方案

🍊 有疑问可私信或评论区联系我。

🥑  创作不易未经允许严禁转载。

1. 前言

在遥感技术和地球观测领域,处理多源异构原始影像数据是一个关键挑战。随着卫星和传感器技术的进步,我们获得了前所未有的数据多样性。本文将介绍一个为这些数据量身定制的解析系统,该系统结合了策略模式和规则引擎,旨在提供一个灵活、高效且可扩展的数据处理平台,以应对不断增长的数据处理需求。

2. 项目背景

在遥感技术和地球观测领域,处理和分析多源异构原始影像数据已成为一项至关重要的任务。随着卫星技术的不断发展,来自不同传感器、不同平台的原始影像数据呈现出多样化和复杂化的特点。这些数据包括但不限于光学影像、雷达影像、高光谱影像等,每种类型都有其独特的数据结构和元数据信息。我之前博客针对不同各类原始影像数据格式和元数据信息进行过详细梳理:【GIS系列】卫星遥感影像简介及格式梳理-CSDN博客

有效地解析和管理这些多源异构的原始影像数据,对于地质调查、环境监测、城市规划、农业管理等多个领域都具有重要意义。然而,由于数据来源的多样性和复杂性,传统的数据处理方法往往难以满足需求。

本文将介绍一个专门针对多源异构原始影像数据设计的解析系统,探讨如何构建一个灵活、高效、可扩展的数据处理平台。本文仅对如何解析多源异构数据提供解决方案思路,不无偿提供源码。

3. 系统现状与挑战

目前,在处理多源异构原始影像数据时,我们面临以下挑战:

1. 数据格式多样性:不同卫星、不同传感器产生的原始影像数据格式各不相同,包括但不限于GeoTIFF、HDF、NITF等。

2. 元数据结构差异: 各类影像的元数据结构存在显著差异,如何统一解析和存储这些元数据是一大难题。

3. 数据量巨大:遥感影像数据通常体积庞大,如何高效处理和存储是一个挑战。

4. 实时性要求:某些应用场景(如灾害监测)需要近实时的数据处理能力。

5. 扩展性需求:随着新型传感器和卫星的不断发布,系统需要能够快速适应新的数据类型。

6. 质量控制: 原始影像数据可能存在噪声、畸变等问题,需要在解析过程中进行初步的质量评估。

为了应对这些挑战,我们设计了一个基于策略模式和规则引擎的多源异构原始影像数据解析系统。这个系统具有高度的灵活性和可扩展性,能够有效处理各种复杂的原始影像数据。

4. 核心技术实现

多源异构原始影像解析入库流程图如下:

上述流程图从前端、后端及数据库三个角度来呈现原始影像入库流程,首先由前端将文件路径传递给后台,后台基于规则引擎将影像映射到策略工厂,找到影像解析对应类,之后由解析类中的方法解析元数据,若解析成功则将元数据写入数据库同时写入成功日志流程结束,若解析失败则写入失败日志流程结束。 下文将介绍解析流程中涉及的核心技术栈。

4.1. 策略模式

策略模式(Strategy Pattern)是一种行为设计模式,它定义了一系列算法,将每个算法封装起来,并使它们可以互相替换,让算法的变化独立于使用算法的客户。客户端代码通过持有一个策略接口的引用来使用特定的算法,在运行时可以动态地切换不同的算法

4.1.1. 多源异构影像解析策略模式部分核心代码

在多源原始影像元数据解析中引入了策略模式,前端只需要输入文件路径,根据策略模式建立的路由后台即可动态解析不同类型影像并写入数据库。

策略模式的路由策略主要在策略工厂中定义路由Map,以Map键值对的形式实现:

java">private static  Map<String, Function<File,Boolean>> handleMap = null;
@PostConstruct
public void init(){handleMap=new HashMap<>();handleMap.put("GF1B_PMS", originalImageFile -> gf1BPMSHandleService.saveMetadata(originalImageFile));handleMap.put("GF1C_PMS", originalImageFile -> gf1CPMSHandleService.saveMetadata(originalImageFile));handleMap.put("GF1D_PMS", originalImageFile -> gf1DPMSHandleService.saveMetadata(originalImageFile));handleMap.put("GF1_PMS1", originalImageFile -> gf1PMS1HandleService.saveMetadata(originalImageFile));handleMap.put("GF1_PMS2", originalImageFile -> gf1PMS2HandleService.saveMetadata(originalImageFile));handleMap.put("GF6_PMS", originalImageFile -> gf6PMSHandleService.saveMetadata(originalImageFile));handleMap.put("GF6_WFV", originalImageFile -> gf6WFVHandleService.saveMetadata(originalImageFile));handleMap.put("GF2_PMS1", originalImageFile -> gf2PMS1HandleService.saveMetadata(originalImageFile));handleMap.put("GF2_PMS2", originalImageFile -> gf2PMS2HandleService.saveMetadata(originalImageFile));handleMap.put("BJ3B1_PMS", originalImageFile -> bj3B1PMSHandleService.saveMetadata(originalImageFile));handleMap.put("GF5_AHSI", originalImageFile -> gf5AHSIHandleService.saveMetadata(originalImageFile));handleMap.put("LT5_TM", originalImageFile -> lt5TMHandleService.saveMetadata(originalImageFile));handleMap.put("LT05_TM", originalImageFile -> lt05TMHandleService.saveMetadata(originalImageFile));handleMap.put("LC08_OLI", originalImageFile -> lc08OLIHandleService.saveMetadata(originalImageFile));handleMap.put("LC09_OLI", originalImageFile -> lc09OLIHandleService.saveMetadata(originalImageFile));handleMap.put("GF701_BWD", originalImageFile -> gf701BWDHandleService.saveMetadata(originalImageFile));handleMap.put("GF701_MUX", originalImageFile -> gf701MUXHandleService.saveMetadata(originalImageFile));handleMap.put("ZY1E_VNIC", originalImageFile-> zy1EVNICHandleService.saveMetadata(originalImageFile));handleMap.put("zy302a_mux", originalImageFile-> zy302MUXHandleService.saveMetadata(originalImageFile));handleMap.put("zy302a_nad", originalImageFile -> zy302NADHandleService.saveMetadata(originalImageFile));handleMap.put("HJ2B_CCD4", originalImageFile -> hj2BCCD4HandleService.saveMetadata(originalImageFile));handleMap.put("BJ3N1", originalImageFile -> bj3N1PMSHandleService.saveMetadata(originalImageFile));handleMap.put("TRIPLESAT_1_PMS",originalImageFile -> triplesat1PMSHandleService.saveMetadata(originalImageFile));handleMap.put("JL1GF02A_PMS2", originalImageFile -> jl1GF02APMS2HandleService.saveMetadata(originalImageFile));handleMap.put("JL1KF01C_PMSR1",originalImageFile -> jl1KF01CPMSR1HandleService.saveMetadata(originalImageFile));handleMap.put("DP01_PMS", originalImageFile -> dp01PMSHandleService.saveMetadata(originalImageFile));handleMap.put("CB04A_WPM", originalImageFile -> cb04AWPMHandleService.saveMetadata(originalImageFile));handleMap.put("S1A_SAR", originalImageFile -> s1ASARHandleService.saveMetadata(originalImageFile));handleMap.put("S2A_SAR", originalImageFile -> s2ASARHandleService.saveMetadata(originalImageFile));handleMap.put("S2B_SAR", originalImageFile -> s2BSARHandleService.saveMetadata(originalImageFile));handleMap.put("GF3_SYC",originalImageFile->gf3SARHandleService.saveMetadata(originalImageFile));
}

在handleMap中以影像文件名的部分为键值,真实解析方法为map值,以达到用文件名作为路由的目的。 

java">public void saveMetadata(String imageType, File originalImageFile){handleMap.get(imageType).apply(originalImageFile);
}

 直接引用策略工厂的saveMetadata方法即可实现根据文件路径解析不同类型影像。

4.1.2. 策略模式的意义

多源异构影像解析中,我们采用的Map映射的方式,用Map键代表不同路由策略,以上两种设计均使用了策略模式的思想,具体体现在以下几个方面:

  1. 独立的路由策略实现: 每个枚举值对应一种具体的任务路由策略,这样可以将不同的路由策略实现封装到不同的类中,实现了算法的独立性。
  2. 扩展性: 可以轻松地向系统中添加新的路由策略,只需添加对应的枚举值和相应的路由策略实现类。这样做符合开闭原则,使得系统更容易扩展。
  3. 动态切换策略: 策略模式使得在运行时可以动态地切换任务路由策略,而不需要修改调度系统的核心代码。这增加了系统的灵活性。
  4. 清晰的接口定义: 通过策略模式,可以为每种路由策略定义清晰的接口,包括了选择执行器的逻辑。这样,不同的路由策略实现可以按照相同的接口定义来实现。

在项目中,策略模式的运用使得任务的路由策略更加灵活和可扩展,使得系统能够适应不同的业务场景和调度需求。

4.2. 规则引擎

规则引擎是一种软件系统或组件,专门设计用于管理和执行事先定义的业务规则。这些规则通常以条件-动作的形式存在,即当某些条件得到满足时,触发相应的动作。规则引擎通过将业务规则从应用程序中分离出来,提供了更灵活、易于维护的业务逻辑管理方式。网上查询了很多规则引擎框架,最终选择了Easy Rules,原因就是Easy Rules基于java写的,而且 设计简单,仅依赖少量的核心类库,易于集成和使用。

4.2.1. 规则引擎部分核心代码

在上一节中介绍了策略模式的概念以及多源原始影像解析功能中策略模式的使用细节,在策略模式中基于路由解析了不同类型影像写入数据库中,但还缺少一个桥梁,规则引擎正是作为桥梁将文件名称与策略模式的路由做了相关映射,使得多源原始影像元数据解析功能能完整串接起来。

1. 定义规则

我们需要根据不同类别的影像定义不同的规则,下述代码为高分1,2,5,6类别影像的规则:

java">@Rule(priority = 2)
public class GFRule {@Conditionpublic boolean isGFImage(@Fact("fileFact") FileFact fileFact) {return "GF".equalsIgnoreCase(fileFact.getSplit()[0].substring(0, 2));}@Actionpublic void saveMetadata(@Fact("fileFact") FileFact fileFact) {String[] split = fileFact.getSplit();fileFact.saveMetadata(split[0] + "_" + split[1], new File(fileFact.getFilePath()));}
}

@Condition注解标记计算规则条件的方法,return "GF".equalsIgnoreCase(fileFact.getSplit()[0].substring(0, 2))代码为截取文件名如为GF则符合规则。

@Action注解标记要执行规则操作的方法,fileFact.saveMetadata(split[0] + "_" + split[1], new File(fileFact.getFilePath()))代码为执行相应解析影像方法。

2. 定义事实

java">@Data
@AllArgsConstructor
public class FileFact {// 文件路径private String filePath;private String[] split;private ImageFactory imageFactory;public FileFact(String filePath, ImageFactory imageFactory) {this.filePath = filePath;this.imageFactory = imageFactory;File file = new File(filePath);split = file.getName().split("_");}public void saveMetadata(String imageType, File originalImageFile ) {imageFactory.saveMetadata(imageType,originalImageFile);}
}

3. 定义规则引擎调用组件

java">@Service
@Import(LTRule.class)
public class RuleService {//注入影像解析策略工厂@ResourceImageFactory imageFactory;private DefaultRulesEngine rulesEngine = null;private Rules rules = null;@PostConstructpublic void init() {// 创建规则引擎,设置引擎参数 告诉引擎规则被触发时跳过后面的规则RulesEngineParameters parameters = new RulesEngineParameters().skipOnFirstAppliedRule(true);rulesEngine = new DefaultRulesEngine(parameters);// 注册规则rules = new Rules();rules.register(new ZYRule());rules.register(new GFRule());rules.register(new GF7Rule());rules.register(new GF3Rule());rules.register(new LTRule());rules.register(new LT05Rule());rules.register(new LCRule());rules.register(new BJ3B1Rule());rules.register(new BJ3N1Rule());rules.register(new TripleSat1Rule());rules.register(new JL1AndDP01Rule());rules.register(new HJ2BRule());rules.register(new SARule());}public void matchRule(String filePath) {// 创建事实对象Facts facts = new Facts();FileFact fileFact = new FileFact(filePath, imageFactory);facts.put("fileFact", fileFact);// 开始映射rulesEngine.fire(rules, facts);}}

这段代码定义了一个名为 RuleService 的服务类,使用 Spring 框架的特性进行配置。它初始化一个规则引擎,注册了一系列特定的规则来处理不同类型的影像文件。当传入一个文件路径时,这个服务通过匹配的规则动态决定如何解析文件并处理相关的元数据,使得系统能够灵活地应对各种遥感影像数据的处理需求。 

 5. 延展应用

虽然本文主要讨论了多源异构原始影像数据的解析,但这种基于策略模式和规则引擎的方法同样可以应用到其他相关领域:

1. 多源遥感数据融合:将不同类型的遥感数据(如光学和雷达数据)进行融合分析。

2. 历史影像数据处理: 处理和整合不同时期、不同来源的历史影像数据。

3. 实时遥感监测系统:构建能够实时接收和处理多源遥感数据的监测系统。

4. 卫星地面站数据管理: 管理和处理来自多个卫星地面站的数据流。

5. 遥感大数据分析平台:构建能够处理海量多源遥感数据的大数据分析平台。

这种方法为处理复杂的多源异构原始影像数据提供了一个灵活且可扩展的框架,也为其他类型的多源异构数据处理提供了有价值的参考。

 6. 结语

策略模式和规则引擎组合可以形成一套方法论用来解决多源异构数据解析的场景,此后有类似需求场景也可以使用这套方法论。若本文对你有启发和帮助,别忘记点点关注哦~


http://www.ppmy.cn/news/1518752.html

相关文章

学习记录——day37 C++ 基础概念 字符串 命名空间

目录 一、C相关概念 二、面向对象 三、C框架 四、输出流对象&#xff1a;cout 五、输入流对象 cin 六、输入流对象 输出流对象 示例 1、大小写转换 2、输出斐波那契数列 3、进制转换 宽度 精度 七、命名空间 namespace 1、命名空间的意义 2、程序中的标识符&#xff0…

【学习笔记】第三章深度学习基础——Datawhale X李宏毅苹果书 AI夏令营

局部极小值与鞍点 梯度为0的点我们统称为临界点&#xff0c;包括局部极小值、鞍点等 局部极小值和鞍点的梯度都为0&#xff0c;那如何判断呢&#xff1f; 先请出我们损失函数&#xff1a;L(θ)&#xff0c;θ是模型中的参数的取值&#xff0c;是一个向量。 由于网络的复杂性&a…

React基础面试题

React 面试题 以下是面试官最有可能问到的 50 个 React 面试题和答案。为方便你学习&#xff0c;我对它们进行了分类&#xff1a; 基本知识React 组件React ReduxReact 路由 基本知识 1. 区分Real DOM和Virtual DOM Real DOMVirtual DOM1. 更新缓慢。1. 更新更快。2. 可以…

那么多编程语言,先学哪个?

简单介绍一下几种主要的语言&#xff1a; C&#xff0c;是一种面向对象的编程语言&#xff0c;常用于开发游戏、操作系统和嵌入式系统等性能要求比较高的场景。如果你对这些领域感兴趣&#xff0c;C是一个很好的选择。 Java&#xff0c;也是面向对象的编程语言&#xff0c;特点…

前端宝典二十三:Array最常用的34个方法

这里列举了Array最常用的34个方法 其中静态方法两个、实例方法32个&#xff0c;对他们进行了分类比较&#xff0c;有助于更好的掌握。 一、前言&#xff1a;手写一个深拷贝 以下是一个用 JavaScript 手写的深拷贝方法&#xff0c;考虑了正则表达式、日期对象、数组和普通对象…

12 对话模型微调2

1 P-Tuning P-Tuning 是在 Prompt-Tuning的基础上&#xff0c;通过新增 LSTM 或 MLP 编码模块来加速模型的收敛&#xff1b; 之前的实验也看到了使用prompt训练速度很慢&#xff0c;那么P-Tuning呢 参数占比&#xff1a; trainable params: 5,267,456 || all params: 1,308,37…

Windows服务器应急响应(下)

目录 介绍步骤 介绍 进程&#xff08;Process&#xff09;是计算机中的程序关于某数据集合上的一次运行活动&#xff0c;是系统进行资源分配和调度的基本单位&#xff0c;是操作系统结构的基础。在早期面向进程设计的计算机结构中&#xff0c;进程是程序的基本执行实体&#x…

sql 优化,提高查询速度

文章目录 一、前言二、建议2.1 使用索引2.2 避免使用select *2.3. 使用表连接代替子查询2.4. 优化WHERE子句&#xff0c;减少返回结果集的大小2.5 用union all代替union2.6 使用合适的聚合策略2.7 避免在WHERE子句中使用函数2.8 使用EXPLAIN分析查询2.9 小表驱动大表2.10 使用窗…

PHP程序设计教案

文章目录&#xff1a; 一&#xff1a;前言 1.什么是PHP 2.环境安装 3. 语法规范 3.1 注释 3.2 分隔符 3.3 其他规范 二&#xff1a;基础语法 1.输出 1.1 echo 1.2 print 1.3 var_dump类型和值 1.4 print_r()易读 2.常量变量 2.1 常量 2.1.1 define()/const…

vue前端实现登录页面的验证码(新手版)

一、搭建vue前端登录页面 <template><div style"width: 800px; margin: 5px auto; background-color: #17ecf3"><div align"center"><h2>用户登录</h2></div><div style"width: 60%; margin: 1px auto"…

如何解决`.gitignore`规则不生效或已提交相关文件的问题

前言 在使用Git进行版本控制时&#xff0c;.gitignore文件是一个非常有用的工具&#xff0c;它可以帮助我们排除不需要跟踪的文件或目录。然而&#xff0c;在实际开发过程中&#xff0c;有时我们会遇到.gitignore规则不生效的情况&#xff0c;或者是不小心将不应提交的文件提交…

RabbitMQ 入门教程

RabbitMQ 入门教程 1. 引言 RabbitMQ 是一个开源的消息代理和队列服务器&#xff0c;实现高级消息队列协议 (AMQP)。它能帮助开发者实现应用程序间的解耦、异步处理、流量削峰等需求。 2. 安装与配置 2.1 安装RabbitMQ 2.1.1 Ubuntu bash sudo apt-get update sudo apt…

动态IP池在数据抓取中的应用与优势

随着互联网技术的快速发展&#xff0c;数据抓取&#xff08;Web Scraping&#xff09;已经成为获取互联网信息的重要手段。然而&#xff0c;在进行大规模数据抓取时&#xff0c;往往会遇到反爬虫机制、IP封禁等问题。动态IP池作为一种解决方案&#xff0c;可以有效地绕过这些障…

告别手动记录,音频转文字软件助力会议记录新高度

如果你突然被领导指派去参与一场会议&#xff0c;身边没有纸笔要怎么记录转达会议内容呢&#xff1f;我往往会采用手机的录音功能来记录会议内容会后再进行整理。这次我们就来探索音频转文字工具怎么提升我们的工作效率。 1.365在线转文字 链接传送&#xff1a;https://www.p…

微服务优缺点以及如何拆分

微服务优点 1,降低代码逻辑复杂度。 单个微服务模块相当于一个项目&#xff0c;开发人员只用关心这个模块的逻辑即可。 2&#xff0c;技术栈更加灵活 不同的微服务可以使用合适的语言架构实现&#xff0c;然后把服务注册到一个注册中心即可相互调用。 3&#xff0c;按需伸缩 当…

人工智能工作级开发者认证 HCCDP – AI 真题2 答案

1.GBDT通过bagging的防范可以对样本和特征都进行采集。答案:FALSE 原因:GBDT可以对样本采集,不能对特征采集 2.深度学习是机器学习的一个分支。答案:true 3.softmax激活函数的作用是减少及时量和防止梯度消失。答案false 4.在建筑施工现场,基于定制化的图像识别目标检测系统,…

Node.js 安装与使用及连接 MongoDB 的详细教程

下面我将详细讲解如何安装 Node.js、介绍 Node.js 的脚手架工具、使用 Express 脚手架创建项目&#xff0c;以及如何安装和连接 MongoDB。 一、Node.js 安装 下载 Node.js&#xff1a; 访问 Node.js 官方网站。 根据你的操作系统选择最新的 LTS&#xff08;长期支持版&#x…

从自动驾驶看无人驾驶叉车的技术落地和应用

摘 要 &#xff5c; 介绍无人驾驶叉车在自动驾驶技术中的应用&#xff0c;分析其关键技术&#xff0c;如环境感知、定位、路径规划等&#xff0c;并讨论机器学习算法和强化学习算法的应用以提高无人叉车的运行效率和准确性。无人叉车在封闭结构化环境、机器学习、有效数据集等方…

参加 帆软 BI 上海城市 课堂(08-30培训)

参加 帆软 BI 城市 课堂&#xff08;0830&#xff09;&#xff1a; 由于目前是自由职业&#xff0c;也想学习一下新的知识 。所以参加本次的培训&#xff0c;总的来说还是比较专业。 培训在 上海 帆软的总部 环球港进行。时间是 13:30~17&#xff1a;00 老师很专业。学习中 课…

关于前端布局的基础知识

float 横向布局 float 实现横向布局&#xff0c;需要向横着布局的元素添加float 其值left right 存在问题 如果使用float 所在父级五高度&#xff0c;会导致下方的元素上移 top的高度被吞了 解决方法&#xff1a; 给父级元素设置高度&#xff1a;不推荐&#xff0c;需要给父级…