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

本文主要是介绍【GIS系列】多源异构原始影像解析:策略模式与规则引擎的应用,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

作者:后端小肥肠

🍇 我写过的文章中的相关代码放到了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键值对的形式实现:

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值,以达到用文件名作为路由的目的。 

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类别影像的规则:

@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. 定义事实

@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. 定义规则引擎调用组件

@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. 结语

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

这篇关于【GIS系列】多源异构原始影像解析:策略模式与规则引擎的应用的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1106189

相关文章

Redis中Stream详解及应用小结

《Redis中Stream详解及应用小结》RedisStreams是Redis5.0引入的新功能,提供了一种类似于传统消息队列的机制,但具有更高的灵活性和可扩展性,本文给大家介绍Redis中Strea... 目录1. Redis Stream 概述2. Redis Stream 的基本操作2.1. XADD

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析(结合应用场景)

《nginx-t、nginx-sstop和nginx-sreload命令的详细解析(结合应用场景)》本文解析Nginx的-t、-sstop、-sreload命令,分别用于配置语法检... 以下是关于 nginx -t、nginx -s stop 和 nginx -s reload 命令的详细解析,结合实际应

MyBatis中$与#的区别解析

《MyBatis中$与#的区别解析》文章浏览阅读314次,点赞4次,收藏6次。MyBatis使用#{}作为参数占位符时,会创建预处理语句(PreparedStatement),并将参数值作为预处理语句... 目录一、介绍二、sql注入风险实例一、介绍#(井号):MyBATis使用#{}作为参数占位符时,会

PostgreSQL的扩展dict_int应用案例解析

《PostgreSQL的扩展dict_int应用案例解析》dict_int扩展为PostgreSQL提供了专业的整数文本处理能力,特别适合需要精确处理数字内容的搜索场景,本文给大家介绍PostgreS... 目录PostgreSQL的扩展dict_int一、扩展概述二、核心功能三、安装与启用四、字典配置方法

Java设计模式---迭代器模式(Iterator)解读

《Java设计模式---迭代器模式(Iterator)解读》:本文主要介绍Java设计模式---迭代器模式(Iterator),具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,... 目录1、迭代器(Iterator)1.1、结构1.2、常用方法1.3、本质1、解耦集合与遍历逻辑2、统一

深度解析Java DTO(最新推荐)

《深度解析JavaDTO(最新推荐)》DTO(DataTransferObject)是一种用于在不同层(如Controller层、Service层)之间传输数据的对象设计模式,其核心目的是封装数据,... 目录一、什么是DTO?DTO的核心特点:二、为什么需要DTO?(对比Entity)三、实际应用场景解析

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

深度解析Java项目中包和包之间的联系

《深度解析Java项目中包和包之间的联系》文章浏览阅读850次,点赞13次,收藏8次。本文详细介绍了Java分层架构中的几个关键包:DTO、Controller、Service和Mapper。_jav... 目录前言一、各大包1.DTO1.1、DTO的核心用途1.2. DTO与实体类(Entity)的区别1

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.