解析和读取 S-57 电子海图的数据
[toc]
本文主要在 S-57 电子海图数据的理论模型和数据结构的基础上,实现对 S-57 电子海图数据文件的解析,将海图信息解析后保存到 xml 文件中,供下游程序调用和后续研究。
什么是电子海图
电子导航图 (Electronic Navigational Chart, ENC) 是为航海需要而绘制的包含海域地理信息和航海信息的一种数字化的专题地图,是由各个国家的航道官方部门根据国际航道组织的《数字海道测量数据传输标准》 (S-57 标准) 而制作的。符合国际标准的电子海图数据统称为 S-57 电子海图, 它是一种面向对象的矢量格式的电子地图,其存储形式是二进制。
电子海图的理论模型和数据结构,可以查看国际标准《数字海道测量数据传输标准》,这里不再详述,对应英文版是《IHO TRANSFER STANDARD for DIGITAL HYDROGRAPHIC DATA》。
S-57 电子海图的结构如下图所示,来自 Research and Implementation of Global Path Planning for Unmanned Surface Vehicle Based on Electronic Chart。
ISO 8211lib 和 OGR 简介
S-57 标准封转格式是 ISO/IEC 8211 国际标准,封装标准的基础是文件,逻辑记录是封装标准的基本成分。
ISO 8211lib 是 C++ 编写的开源库,专门用于读取符合 ISO 8211 封装标准的数据文件,如 S-57 电子海图数据格式和空间数据传输标准数据集 (SDTS); GDAL 是一个开源栅格空间数据转换库,其中 OGR 是对 GDAL 的扩展,功能与 GDAL 类似,主要提供对矢量数据格式的读写,支持 S-57 电子海图格式,其中 S57reader 类是对 ISO 8211lib 库的封装,该类中包含读取 S-57 电子海图数据文件所用到的基本函数。
程序实现
读取 ENC
OGR 有关于 S-57 读取的官方文档 IHO S-57 (ENC),其中需要注意 OGR 的 S-57 驱动模块将处理 S-57 文件里所有的 feature 要素,其中 S-57 的特征物标 (feature objects) 转换为要素 (feature),空间物标 (geometry objects) 自动转换化对应要素下的空间几何对象。
在 OGR 中,从 S-57 文件读取的所有要素根据物标类型 (OBJL) 归属于相应的图层,可以类比于 GIS 里的 shape 格式,对应的图层下有要素 (feature), 要素下面有字段 (field) 和几何对象 (geometry),要素的几何形状可以从几何形状中获取,要素属性可以从字段中获取。
1 | layer according to OBJL |
其中,深度信息 (Depth soundings) 是 S-57 文件特有的,在读取 Depth soundings 需要设置 S57 Control Options 中的 ADD_SOUNDG_DEPTH 选项为 ON,对于 S57 Control Options 读取和导出的深层次知识请阅读官网文档。
最后,注意在程序中附加 s57objectclasses.csv 和 s57attributes.csv 文件,否则会缺少信息,如图层只有 5 层,无法读取等深线等。官方文档是这么解释的:
The S-57 reader depends on having two supporting files, s57objectclasses.csv, and s57attributes.csv available at runtime in order to translate features in an object class specific manner. These should be in the directory pointed to by the environment variable S57_CSV, or in the current working directory.
保存到 xml 文件中
因为项目需要,需要把 S-57 文件里特定图层的信息提取出来,S-57 文件解析后,把感兴趣的信息保存到 xml 文件中,方便后续的处理。
在 C++ 中,对 XML 文件处理中,使用一个开源的解析 XML 的解析库 – TinyXML,这个解析库的模型通过解析 XML 文件,然后在内存中生成 DOM 模型,从而让我们很方便的遍历这棵 XML 树。
一些实现细节
如果无法得到一个 object class 的属性或者值不正确,如 VALDCO 的值始终为 0。根据论坛的讨论 OGR to access s57 file, missing attributes issue,注意是否加载了 S-57 的支持文件.csv。
The solution to that is to set the GDAL_DATA environment variable to point the directory with the s57objectclasses.csv and related files。
代码和结果
解析和存储效果如下图所示,按图层要素顺序依次组织。
程序实现源代码及示例,欢迎访问 Github: wylloong/S57-Electronic-Chart-Reading-and-Storing。
程序开发环境是 VS2015,其中需要在编译的时候修改两个位置,如下图所示,否则编译会报错。
如果有内容讨论,可以下面留言。