【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

相关文章

网页解析 lxml 库--实战

lxml库使用流程 lxml 是 Python 的第三方解析库,完全使用 Python 语言编写,它对 XPath表达式提供了良好的支 持,因此能够了高效地解析 HTML/XML 文档。本节讲解如何通过 lxml 库解析 HTML 文档。 pip install lxml lxm| 库提供了一个 etree 模块,该模块专门用来解析 HTML/XML 文档,下面来介绍一下 lxml 库

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

异构存储(冷热数据分离)

异构存储主要解决不同的数据,存储在不同类型的硬盘中,达到最佳性能的问题。 异构存储Shell操作 (1)查看当前有哪些存储策略可以用 [lytfly@hadoop102 hadoop-3.1.4]$ hdfs storagepolicies -listPolicies (2)为指定路径(数据存储目录)设置指定的存储策略 hdfs storagepolicies -setStoragePo

csu 1446 Problem J Modified LCS (扩展欧几里得算法的简单应用)

这是一道扩展欧几里得算法的简单应用题,这题是在湖南多校训练赛中队友ac的一道题,在比赛之后请教了队友,然后自己把它a掉 这也是自己独自做扩展欧几里得算法的题目 题意:把题意转变下就变成了:求d1*x - d2*y = f2 - f1的解,很明显用exgcd来解 下面介绍一下exgcd的一些知识点:求ax + by = c的解 一、首先求ax + by = gcd(a,b)的解 这个

hdu1394(线段树点更新的应用)

题意:求一个序列经过一定的操作得到的序列的最小逆序数 这题会用到逆序数的一个性质,在0到n-1这些数字组成的乱序排列,将第一个数字A移到最后一位,得到的逆序数为res-a+(n-a-1) 知道上面的知识点后,可以用暴力来解 代码如下: #include<iostream>#include<algorithm>#include<cstring>#include<stack>#in

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

zoj3820(树的直径的应用)

题意:在一颗树上找两个点,使得所有点到选择与其更近的一个点的距离的最大值最小。 思路:如果是选择一个点的话,那么点就是直径的中点。现在考虑两个点的情况,先求树的直径,再把直径最中间的边去掉,再求剩下的两个子树中直径的中点。 代码如下: #include <stdio.h>#include <string.h>#include <algorithm>#include <map>#

在JS中的设计模式的单例模式、策略模式、代理模式、原型模式浅讲

1. 单例模式(Singleton Pattern) 确保一个类只有一个实例,并提供一个全局访问点。 示例代码: class Singleton {constructor() {if (Singleton.instance) {return Singleton.instance;}Singleton.instance = this;this.data = [];}addData(value)