赵军,宫丽玮,周圣川,胡振彪
(1.青岛市勘察测绘研究院,山东 青岛 266032; 2.青岛市西海岸基础地理信息中心有限公司,山东 青岛 266000)
随着智能移动设备的飞速发展,电子海图系统不再停滞于桌面系统,移动端电子海图系统的应用也越来越多。然而,相比传统桌面电子海图系统,移动设备由于其存储空间小、运算能力有限、屏幕尺寸较小、输入输出形式较少[1,2],对于大量TPK海图栅格瓦片的加载,“瘦小”的移动设备就显得不切实际,对于数据的更新也是一个难题。其次,移动设备可视化范围较小,对于海图符号的精细化显示要求更高,这些相对传统桌面海图系统可以忽略的问题,在移动设备上都是必须解决的难题。
本文将矢量电子海图“移植”到移动端;同时,不同于传统的纯底层电子海图读取-解析-显示-功能开发模式,本文依托ArcGIS for Android SDK作为技术框架,通过继承图层类DynamicLayer,自定义新View图层类,采用MVC模式,不仅实现了矢量电子海图的可视化,采用ArcGIS本身的可视化引擎,可视化速度和效果显著,而且“借用”ArcGIS成熟的功能模块,依托ArcGIS API进行二次开发,系统稳定,大大缩短后期的系统功能模块开发时间,提高系统的可扩展性和应用效果。
本文采用S-57电子海图数据,即符合IHO标准《数字化海道测量数据传输标准》的国际标准电子海图。国际标准电子海图是按S-57标准的要求组织的描写海域地理信息和航海信息的数字产品,主要以描述海域要素为主,详细表示水深、航行障碍物、助航标志、港口设施、潮流、海流等要素的数字化信息。电子海图数据文件的命名已经严格规范设定,按照IHO要求和规定编制,000是标准电子海图文件格式的后缀,其封装结构是一种高压缩的数据交换格式。中国海事电子海图的数据文件名表现形式为CN******.000,以CN331340.000为例,其中“CN”是中国海事的代码(由IHO统一分配)、数字“3”是航海用途(表示沿海、Coastal),31340表示图幅编号;小改正更新数据文件表现形式是CN******.nnn,其含义与基础数据文件名的意义相同,但后缀根据小改正更新次数进行编号,最大可达到999次,如第十次小改正更新,其文件名是CN******.010[3,4]。
电子海图根据空间信息的数据结构主要包括两大类:光栅式电子海图和矢量式电子海图。其各自特点如表1所示。
电子海图分类 表1
从上表可以看出,矢量电子海图数据占用空间更小,矢量绘制海图符号显示效果更佳,支持各种空间分析、数据更新。移动平台内存空间有限,考虑到需要海上作业、离线加载海图数据等问题,矢量电子海图的优势可以得到更好的发挥。
000海图文件的解析用C++来实现,而Android主流应用的开发使用Java语言,因此涉及C++与Android端Java代码的对话问题,需要实现两者之间的无障碍交流;为了解决这一问题,本文选择采用NDK工具和JNI技术,也是目前Android开发解决此类相关问题的主流途径。
(1)NDK介绍
众所周知,Android相关应用软件的开发,都是以Java作为主流开发语言,这主要是因为Android SDK使用Java语言编写。但在实际程序开发中,同样支持C/C++,即所谓的原生编程。Android系统架构下的核心库是一个由C/C++编写的库的集合,因此,可以认为,Android平台实际是由C/C++搭建,由C/C++编程也成为现实[8]。
为了在系统底层支持“Java与C/C++”的交换开发,催生了NDK(Native Development Kit)。NDK是一个工具集,支持开发者使用本地代码(C/C++)进行程序部分功能的开发。NDK的出现,使得开发者可以重用一些成熟的C/C++本地库来完成程序某些特定功能的开发,从而提高程序性能。
C/C++的嵌入,丰富了Android的开发;同时,C/C++语言本身的特性,也使NDK给Android开发带来了一系列的天然优势:
①明显提高代码的安全性。应用层主流语言Java被反编译难度较低,而以C/C++编写的动态库的反编译过程则要困难得多。
②对本地开源动态库的利用更加方便。NDK的出现,可以大大提高这些开源库的使用,不仅可以有效重用现有代码,还可以有效提高程序开发的效率。
③明显提高代码的执行效率。C/C++语言本省的高性能性,将其进行较高性能的应用逻辑层面的开发时,可以大大优化代码的执行效率。
④提高代码的可移植性。本地C/C++动态库以 .so库的形式独立存在,可以方便地应用于其他的嵌入式平台,明显提高代码的重用性。
(2)JNI技术混编
JNI,即Java Native Interface,Java本地接口;用来实现Java代码和本地C/C++代码的交互。
NDK作为谷歌开发推出的开发和编译工具集,主要用于Android的JNI开发,NDK提供Java和C/C++交互的环境,用来实现Java代码与本地的C/C++的相互调用。比如,当我们需要使用某个函数,基于效率等原因,函数用C/C++语言在NDK环境中一个类文件中实现,然后将该类文件打包成so动态库;利用JNI技术,我们只需在Java层加载上述本地动态库、定义一个JNI式的接口,便可以实现语言之间的交互,如图1所示。
图1 JNI应用流程图
通过Android中的应用程序框架,可以简单、直接地看出JNI给程序调用带来的变化。正常情况下的Android框架:最上层是Android的应用程序代码,为Java语言,中间层是Framework框架层,为C/C++代码,通过Framework层进行系统的调用,调用系统的底层库函数和Linux内核,如图2所示。
图2 Android框架图
图3 使用JNI的Android框架图
使用JNI时的Android框架:不再经过Framework框架层,通过JNI直接调用本地开发者编写的C/C++代码,本地代码最后通过NDK环境编译成so动态库,该动态库通过JNI提供的一个Stable的ABI(二进制程序接口application binary interface)调用Linux内核,如图3所示。
上述两张图2和3,可以看出JNI是连接Android框架层(Framework-C/C++)和应用框架层(Application Framework-Java)的纽带。
本文研究选择ArcGIS Runtime SDK for Android作为系统开发框架,虽然ArcGIS的API技术已相对成熟,但ArcGIS SDK并不能解析和绘制S-57电子海图矢量格式的000文件。通过对NDK的研究和JNI技术的了解,本文选择用标准C++解析000文件读进内存,利用JNI技术,然后用Java进行绘制的模式进行矢量海图的绘制显示,简单的基本流程如下图4所示。这么做的好处就是文件的解析部分是可以跨平台运行的,以后如果要在其他平台上布设移动海图系统就可以直接使用这里的解析模块而不用重新解析从头开始。绘制的部分由于要考虑到不同操作平台的绘制环境,故没有必要做成跨平台的通用模块,这样还可以利用不同平台对自有绘制引擎的加速功能,从而使绘制更加高效。
图4矢量海图绘制流程
(3)ArcGIS Runtime SDK for Android介绍
ArcGIS Runtime SDK for Android为Android平台上开发地理信息系统产品提供了最基本的地理信息系统相关功能的开发框架,本文选择ArcGIS Runtime SDK for Android作为系统开发的技术框架,可以充分利用其API在地图应用层面目前已具备的成熟的技术支持。其主要功能包括:数据加载、地图查询、数据展示、外业数据采集、数据编辑、数据同步。
基于ArcGIS Runtime SDK for Android进行二次开发,能够大大改善之前海图系统零起步自主研发导致的系统不稳定性,而且对于后期的系统可拓展性可以提供很好的支持。
ArcGIS for AndroidSDK提供各种类型的图层类,各图层类继承关系如图5所示。其中,DynamicLayer提供自定义矢量绘制接口,对于000矢量电子海图的绘制,通过继承DynamicLayer自定义图层来实现,做到对ArcGIS for Android框架的无缝对接。
图5 图层类继承关系图
为了实现矢量电子海图解析的跨平台性,提高整个海图系统在平台间的可移植性,提高代码的使用率,000矢量海图的解析部分采用标准C++来完成,NDK环境和JNI技术的引入,使得Android开发环境对于标准C++具有比较良好的兼容性,不仅支持调用C++封装的底层库,而且支持Java和C++混编,最终将解析的部分打包成so动态库供上层绘制模块调用。解析模块整体上分为两个部分,对000海图文件和符号库进行分离解析。
不同平台具有各自不同的绘制引擎,同时不同的操作平台对于自身绘制引擎的支持性也相对较好,并且调用起来也更加方便;本文000矢量海图的具体绘制,采用Android自带的绘制引擎Skia进行。Skia Graphics Library(SGL)是一个由C++编写的开放源代码图形库,最初由Skia公司开发,后由Google收购,搭配OpenGL ES,成为Android的专属绘制引擎库[5]。Skia主要有以下几个特点[9]:
①高度优化的软件rasteriser(module sgl/);
②选择性透过OpenGL ES,加速特定操作,如shader与textures(module gl/);
③较强的动画处理能力(module animator/);
④内建SVG支援(module svg/);
⑤内建若干image codec,如PNG,JPEG,GIF,BMP(modules images/);
⑥具有一定的文字处理功能,但对于不太常见的文字的处理相对不足;
Android对Skia的调用是一个比较经典JNI式的调用过程,这与下面矢量绘制的调用过程有异曲同工之处;JNI放在框架的JNI目录下面的Graphic目录;Skia以第三方组件的身份,放在external目录下面。Android对Skia的调用流程如图6所示。
图6 Android调用Skia流程图
海图适量绘制的过程总体思想就是解析、绘制、显示三过程上下层环境的分离、开发语言Java/C++的交互;最后形成独立的视图控件。实现解析过程的可移植性、跨平台性;利用JNI实现上下层环境Java/C++语言的交互、海图的绘制;通过自定义开发ArcGIS for Android View图层类,实现海图显示图层的模块化、独立性。整个调用绘制过程如图7所示。
图7 海图矢量绘制图
海图矢量绘制具体步骤如下:
(1)首先是海图000文件和符号库文件的解析。该过程发生在C++底层,这是一个可移植的过程,桌面版、IOS平台均可适用;
(2)将解析结果内存块转化为bitmap。解析结果内存对象ENCProject到海图bitmap图像的过程发生在Android NDK环境下的C++底层,利用Android的Skia图形库方法DrawMap方法将内存块ENCProject绘制出bitmap;
(3)利用JNI将C++底层bitmap上传到Android应用层java类。该过程符合Android对Skia JNI式的调用过程,将结果返回到上层Java层。
(4)自定义新的View图层类TeleSeaMapServiceLayer。通过覆写继承自DynamicLayer的TeleSeaMapServiceLayer的getImage方法,接收底层传出的bitmap。
(5)采用ArcGISAPI类MapView加载地图场景方法addLayer,实现S-57海图图层的显示。
(1)开发环境
海图系统采用AndroidStudio作为开发平台,开发语言使用Java和标准C++,采用ArcGIS for Android作为开发接口,数据库使用Sqlite。
测试环境
主要测试设备包括Galaxy Note Ⅱ和Galaxy Tab Pro T320。各项参数指标如表2所示。
测试参数 表2
(2)效果展示
S-52标准对海图的显示做了基准规范,将航道图显示分类为以下三种:
①基础显示:指不能从显示中删除的,由那些在任何情况下都需要的信息所组成的SENC信息层。基础显示作为标准显示的一部分,并不能满足安全航行的需要。
②标准显示:指当航道图默认情况下在电子海图显示与信息系统上显示时所展示出的系统电子航海图(SENC)信息。在实际航海应用时,相关工作人员可根据需要选择性显示系统航道图的信息,同时可以进行相关修改。
③所有其他信息:指不包含在标准显示中的航道图信息、它仅在需要时才显示[10]。
实验结果表明,矢量电子海图的显示达到预定目标,尤其是对精细化海图符号的显示非常成功,如图8所示。
图8矢量海图显示效果图
相比传统tpk瓦片栅格海图,矢量电子海图所占存储空间更小,大大提高了移动端海图显示的应用范围。矢量电子海图的显示质量更好,海图缩放不失真;同时,从图8可以看出,矢量电子海图实现了对海图符号显示精度和显示质量的双重保障,解决了瓦片栅格海图符号标识模糊、位置不明确的问题;并且,本文实现可以随意切换实时渲染显示不同专题的海图符号,相比栅格海图“一个专题符号海图就需要重新打包一份对应的GB级别的栅格瓦片”,这完全是跨越式的进步。
海洋地理空间的发展是这个时代的主旋律。电子海图作为海上作业的必备工具,智能移动设备的发展推动,对矢量电子海图的需求越来越大。本文提出通过继承ArcGIS DynamicLayer,自定义海图图层TeleSeaMapServiceLayer,实现了ArcGIS for Android下的矢量电子海图的可视化,可视化效果显著。同时,基于ArcGIS for Android的二次开发,有助于后期可视化系统的维护和可拓展性。对于系统的优化和相关功能的开发,有待于后期进一步开发。
[1] 齐胜利. 基于Android的移动电子海图平台研究[D]. 大连:大连海事大学,2012.
[2] 李超,潘明阳,李邵喜等. 基于Android的电子海图显示系统研究与实现[J]. 大连海事大学学报,2013,39(4):55~58.
[3] 陈辉. Web方式下电子海图的显示技术研究与应用[D]. 武汉:武汉理工大学,2011.
[4] 董才华,秦臻. 电子海图数据读取与显示技术[J]. 中国航海,2012,35(4):22~25.
[5] 徐铁.电子海图数据库及其索引技术研究[D]. 上海海运学院,2003.
[6] 徐永峰.基于分层动态网格的电子海图显示技术研究[D]. 上海:上海海事大学,2006.
[7] 董晓光,李树军,李改肖等. 移动平台下电子海图矢量数据访问优化方法[J]. 海洋测绘,2015,35(4):57~59.
[8] 王有禄,李代平. Android系统下基于NDK方式的图形开发[J]. 计算机系统应用,2013(12):56~59.
[9] 邵哲平,孙腾达,潘家财等. 基于ECDIS和AIS的船舶综合信息服务系统的开发[J]. 中国航海,2007,2:7.