趙軍,宮麗瑋,周圣川,胡振彪
(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.