Opticks 开发者指南/概念
本节介绍了一些使用 Opticks 的主要概念。第一节描述了插件架构。
Opticks 插件架构使开发人员能够轻松地添加用于导入、处理和导出遥感数据的功能。启动时,Opticks 会扫描插件目录以查找 Opticks 插件。任何新的插件都会自动注册,其功能将可以使用。随着新的插件可用,Opticks 主应用程序无需更新。这使多个开发团队能够快速、独立地创建功能。
如右图所示,插件架构由 Opticks 主应用程序、模块和插件组成。一个模块将一个或多个插件打包在 DLL 或共享对象中,并定义 Opticks 加载插件的接口。模块也是一个方便的地方,可以放置多个插件共享的代码。例如,该图显示了 NITF 导入器和导出器在同一个模块中,因为它们共享读取和写入 NITF 文件格式的代码。
插件是用 C++ 类实现的。要创建一个插件,您只需从几个预定义的插件类类型中继承,并添加自己的功能。下表显示了基本的插件类型
- 算法 - 通用处理和利用算法。
- 导出器 - 用于保存数据的插件。
- 地理配准 - 支持添加新型地理配准算法的插件。
- 导入器 - 用于加载数据的插件。
- 解释器 - 脚本语言支持。
- 栅格分页器 - 用于动态请求栅格“像素”数据的插件。
- 查看器 - 支持基本无模式对话框的插件。
如该图所示,Opticks 为插件提供了通用服务。这些服务都可以通过通用的 Service 类访问。ApplicationServices、DesktopServices、ModelServices 和 PlugInManagerServices 是主要的几个服务。查看 Service 文档以获取完整的列表。每个服务都以相同的方式获取,并为插件提供与 Opticks 通信的方法。
- ApplicationServices 提供对配置设置和会话信息的访问。
- DesktopServices 提供对 Opticks 主显示机制的访问。它提供创建工作区窗口、可停靠窗口和工具栏的功能。
- ModelServices 提供对活动会话中数据元素的访问。
- PlugInManagerServices 为插件提供访问其他可用插件的能力。
模块是通过 ModuleManager 类实现的。该类在 ModuleManager.h 头文件中声明,该头文件包含在 Opticks 软件开发工具包 (SDK) 的“include”目录中。默认实现是在 ModuleManager.cpp 源文件中提供的。插件开发者应该获取提供的默认 ModuleManager.cpp 源文件并修改它以描述正在开发的模块。不应修改 ModuleManager.h 头文件。
在 ModuleManager.h 中声明并在 ModuleManager.cpp 中定义了模块设置变量,这些变量描述了模块。这些模块设置包括模块名称、版本、描述和唯一的模块标识符字符串。ModuleManager 还包含一个名为 getPlugIn() 的方法。此方法用于 Opticks 获取插件类。此方法将索引作为参数,指定要返回的插件,其中 0 表示第一个插件。默认 ModuleManager.cpp 源文件中 getPlugIn() 的实现应该被编辑以创建和返回您的插件。下面的代码片段显示了包含两个插件(导入器和导出器)的模块中 getPlugIn() 方法的可能实现。
PlugIn* ModuleManager::getPlugIn(unsigned long plugInNumber) { PlugIn* pPlugIn = NULL; switch (plugInNumber) { case 0: // Get importer plug-in pPlugIn = new NitfImporter(); break; case 1: // Get exporter plug-in pPlugIn = new NitfExporter(); break; default: break; } return pPlugIn; }
每个插件不应位于其自己的模块中,太多的模块会显著增加 Opticks 加载时间。
插件可以在交互模式或批处理模式下启动。在交互模式下执行的插件通常使用对话框从用户请求信息。然后使用用户输入来进一步执行插件。相反,在批处理模式下执行的插件不应包含用户界面组件以从用户获取必要的输入,而应该要求这些输入存在于插件的输入参数列表中。这意味着插件在交互模式和批处理模式下可能具有不同的参数数量。
为每种类型的插件构建了 shell 类。这些 shell 类可用作创建插件的起点。AlgorithmShell、ExporterShell、GeoreferenceShell、ImporterShell、InterpreterShell、RasterPagerShell 和 ViewerShell 就是几个例子。shell 为该插件类型实现了通用功能。例如,下图显示了 NITF 导出器继承自 ExporterShell 类。ExporterShell 实现了许多通用方法。插件开发者应该从 shell 类继承,重载方法,并使用 Opticks 服务来实现其独特的功能。
大多数 shell 类继承自 PlugIn 和 Executable 接口。这些通用插件接口为 Opticks 提供了一种与插件交互的标准方法。PlugIn 提供一个用于描述插件的通用类。这包括插件名称、版本、描述和菜单位置等信息。Executable 是一个非常强大的通用接口,使所有插件能够以通用方式调用。
Executable 接口使 Opticks 能够确定插件的输入和输出参数,指定插件是将以批处理模式还是交互模式运行,以及执行插件。此接口使分析师能够使用 Opticks 向导生成器将算法链接在一起并自动化常见任务。
class Executable { ... bool setBatch() = 0; bool setInteractive() = 0; bool getInputSpecification(PlugInArgList*& pArgList) = 0; bool getOutputSpecification(PlugInArgList*& pArgList) = 0; bool execute(PlugInArgList* pInArgList, PlugInArgList* pOutArgList) = 0; bool abort() = 0; ... }
getInputSpecification() 和 getOutputSpecification() 方法指定插件的输入和输出参数。setBatch() 和 setInteractive() 方法有两个目的,一是通知插件它应该以批处理模式或交互模式执行,二是查询插件是否支持该模式。execute() 方法启动插件,可以由 Opticks 或其他插件调用。abort() 方法由 Opticks 在用户单击进度对话框中的“取消”按钮时调用,也可以由其他插件调用。