基于FME Objects 的空间数据格式转换方法研究
2023-02-05周飞
周 飞
(江苏省测绘工程院,江苏南京 210013)
0 引言
地理信息数据的格式转换是相当普遍的。各主流数据处理软件能够实现一些简易的格式转换功能,但存在要素或属性丢失、图形变形的情况,无法满足无损转换的需要。
FME Objects 提供了一套软件组件用于处理空间数据。程序的二次开发引用软件安装生成的FME Objects Dot Net 4 库,该库包含了一整套处理空间数据的类、对象、常用变量、函数方法。本文利用FME Objects 读写数据、编辑数据、属性传递的特性及对多种数据格式支持、灵活嵌入其他系统的优势,开发集成了多源数据的格式转换工具,高效满足了各类数据源的统一使用。
1 FME软件简介
FME 主要功能由FME Data Inspector 与FME Workbench 实现。FME Data Inspector 主要用于查看数据的要素数量、组织结构、要素属性、图层分类。FME Workbench 是支持数据格式转换与处理的软件平台,可手动设置读模块、转换器、写模块3部分,用于数据的格式转换。FME 采用的是语义转换方法,支持多源数据的读取与相互转换,针对需求,调用丰富的函数转换器,处理坐标、图形、属性,在转换过程中实现数据重构的功能。“语义转换”运用映射文件的对应模型,提供了不同类型数据的流通通道,破除了数据之间的壁垒,有效避免了数据丢失或图形变形的发生,实现全过程自动化。FME凭借其强大的功能,封装了500 多种转换器(函数),实现了数据的多需求、多方向的格式转换。对于大批量数据格式的转换处理,借助开发链接库,运用程序定制处理同类型的数据转换是高效的。
2 程序运行
依托FME Objects 动态链接库,运用C#语言,在.NET 平台面向对象开发的程序界面如图1 所示。界面提供了选择源数据按钮、目标数据存储路径选择按钮、对应格式转换按钮,以及更新状态栏。软件主要包括dgn->shp、dgn->dwg、dgn->gdb、dgn->mdb、dwg->dgn、mdb->dgn、dwg->shp、gdb->dgn 八种格式转换功能。程序运行流程如图2 所示。
图1 程序界面图
图2 转换流程图
3 程序架构
3.1 窗体运行与设置
c#界面窗体的运行是以static void Main()为起点,主要调用EnableVisualStyles()、SetCompatibleTextRenderingDefault(false)、Run(new Form1())这三个函数方法实现窗体的初步运行。
EnableVisualStyles()函数实现窗体及设置控件的可视化;SetCompatibleTextRenderingDefault(false)函数的参数一般设置为false,此函数使用GDI 方式设置控件的显示文本;Run(new Form1())则用于窗体标准消息的运行与循环。
窗体的设置主要包括button(按钮)、ListBox(列表盒)、StatusStrip(状态栏)、OpenFileDialog(打开对话框)。地理信息数据格式中的Geodatabase(简称gdb)是以文件夹形式表示的,应选用FloderBrowser Dialog 打开数据对话框。窗体设置的控件、对话框、状态栏主要用于触发函数的运行、显示数据的选择及状态等。
3.2 创建对象
FME Objects 运用接口定义了对象必须实现的成员变量。IFM EOSession 定义成员m_fmeSession并使其初始化,这是所有后续成员变量定义的起点。由于接口不能直接创建对象,所以对象m_fmeSession 由FME Objects 根类通过CreateSession()方法创建,其他对象均由对象m_fmeSession 通过函数方法创建。次级生成的6 种对象主要包括图形操作工具、转换日志、对话框、要素、磁盘向量以及读写器,对象的关系及创建方法如图3 所示。
图3 对象关系及创建方法图
3.3 主要功能
3.3.1 释放内存函数
Dispose()函数广泛用于释放界面对象的资源空间,如m_fmeSession 等对象在调用后释放资源避免报警,代码编写位于设计页面的void Dispose(bool disposing)函数中,伪代码如下:
if(m_fmeSession!=null)
{ m_fmeSession.Dispose();
m_fmeSession=null;}
其他各类对象的释放资源可参考m_fmeSession对象的操作,所有对象释放完成后调用系统基类的释放函数base.Dispose()。
3.3.2 属性复制传递
地理信息数据的非图形属性是不可或缺的,FME 默认的转换通道不能直接实现此类属性的复制传递。我们以dgn 数据转换为shapefile 数据为例,实现在读取过程中加入属性参数。
如图3 所示,已阐述对象fmeReader 通过CreateReader(参数)创建,CreateReader()方法主要包含m_dataInfo、m_createDirectives 两个变量和一个布尔值。m_dataInfo 用于设定数据导入的路径与数据格式,m_createDirectives 用于设置属性参数。由于两个参数是基于FME 的m_fmeDialog 对象设置的,而m_fmeDialog 是启用对话框形式实现参数与路径的传输,每次只能导入一个文件,限制了批量转换的可能性,故程序将对象m_fmeDialog 解构,分别设置两个变量的传入参数。
m_createDirectives 通过Add()的方法加入属性参数,伪代码如下:
m_createDirectives.Add(“......DGNV8_EXPOSE_FORMAT_ATTRS,“entity_num_0,integer entity_num_1,integer link_type_0,char(40)link_type_1,char(40)”......”);
加入属性参数设定后,程序根据属性名称依次复制属性值到目标数据,可灵活增添删除非图形类属性。Shapefile 文件由于对属性字段长度的限制,超过10 个字符的属性字段会被强制截取表示,故可导入mdb/gdb 数据库后另行操作。
3.3.3 读取数据与模式要素函数
FME 设计中同时读取数据要素与模式要素才能够完整地读取文件数据。数据转换系统将读取数据要素函数命名为readDataFeatures,读取模式要素函数命名为readSchemaFeatures。
readDataFeatures 函数运用while(fmeReader.Read(fmeFeature))的循环遍历数据特征并记录存储到数据字典中,读完每条信息后重建对象,同时在转换日志中记录每条信息。伪代码如下:
while(fmeReader.Read(fmeFeature))
{m_fmeLogFile.LogFeature(fmeFeature,FMEOMessageLevel.Inform,-1);
insertIntoFeatureTypeDictionary(fmeFeature);
fmeFeature=m_fmeSession.CreateFeature(); }
readSchemaFeatures 函数运用方法与readData-Features 类似。
为将完整的数据信息整合存入到字典中,需设置insertIntoFeatureTypeDictionary 函数。此函数通过FME OFeature 定义的成员对象pFeature 所收集字符串形式的信息与原库自定义的FeatureType 格式,实现数据字典格式的存储。伪代码如下:
string currFeatureType=pFeature.FeatureType;
IFMEOFeatureVectorOnDisk
currVectorOnDisk=m_featureTypeDictionary-
[currFeatureType];
currVectorOnDisk.Append(pFeature);
由已创建的对象fmeReader 实现数据的磁盘存储,伪代码如下:
StringCollection openParams=new
StringCollection();
fmeReader.Open(m_dataInfo.Dataset,
openParams);
readSchemaFeatures(fmeReader,ref
schemaFeatureCount);
readDataFeatures(fmeReader,ref featureCount);
3.3.4 转换输出
数据的转换输出类似于数据的读取,创建打开FMEOWriter 对象,设定输出格式与路径,输出目标的数据和模式要素。伪代码如下:
StringCollection openParams=new
StringCollection();
fmeWriter.Open(m_dataInfo.Dataset,
openParams);
writeSchemaFeatures(fmeWriter,ref
schemaFeatureCount);
writeDataFeatures(fmeWriter,ref featureCount);
3.4 状态栏更新
状态栏位于程序的左下角,用于更新数据转换的进度及数量,更新状态栏的代码如下:
private void updateStatusBar(string pText)
{ toolStripStatusLabel1.Text=pText;
statusStrip1.Refresh();}
为方便用户了解读取与转换的进程,每循环一次要素的读取,便通过numFeatures 计数。状态栏展示内容的更新代码如下:
while(fmeReader.Read(fmeFeature))
{ numFeatures++;
updateStatusBar(" 已读取" + numFeatures.ToString()+"要素......"); }
3.5 要素数量检查
m_fmeLogFile 对象通过LogFeature()函数输出转换日志,日志内容包含了源数据与目标数据的格式和路径、调用的动态库函数、读取要素的模式、读取要素量、转换线型的粗细颜色值、属性名字段、输出要素量等。但是要素是否丢失是最为关键的,故系统设置了用于对比要素读取量与转换量的检查文件,结合numFeatures 的计数功能,在读取函数和转换函数中嵌入文件流代码。伪代码如下:
string datacheck=@"D:datacheck.txt";
streamWriter=new StreamWriter(fileStream);
streamWriter.WriteLine("第" +(i + 1).ToString()+ "个文件所有要素量为:" + numFeatures.ToString());//嵌入读取函数
streamWriter.WriteLine("第" +(i + 1).ToString()+"个文件要素转换量为:"+featureCount.ToString());//嵌入转换函数
检查文本示意图如图4 所示:
图4 要素数量检查文本
4 结语
本文基于FME Objects 动态链接库开发的格式转换软件,解析了FME Objects 应用的类对象、函数方法、成员变量。通过对带属性数据的格式归类与批量输入,软件实现了各类数据图形与属性的无损转换,促进了多源地理信息类文件的高效使用。随着自然资源机构改革的深入,原属国土、测绘、海洋、规划等行业数据的格式转换并叠加分析使用是必然的趋势。对于FME Objects 中涉及要素操作、坐标转换的程序处理则是下一步的研究点。