張 云,于文馳,韓彥嶺,洪中華
(上海海洋大學 信息學院,上海 201306)
隨著上海市軌道交通的覆蓋,人們的出行很大一部分依賴著地鐵提供的快捷。對于日益增多的地鐵站和同時成倍增長的地鐵出口,站內提供的引導地圖已經很難滿足人們的需求,使得為地鐵出行乘客設計一款能夠準確查詢地鐵出口周邊信息的軟件極為迫切。為地鐵乘客提供專業的地鐵出口導航軟件不僅需要信息搜集的準確性,最重要的是要考慮到乘客在途中查詢的方便快捷性。而現在智能機特別是基于android智能手機的日漸普及,開發出能在android手機上運行的地鐵出口導航系統將極大的方便市民的出行。
本文介紹了一款基于android手機平臺的上海地鐵出口導航軟件,在該軟件中,實現了地鐵站的各個出口周邊信息的查詢,側重展示了軟件開發時所用到的各項技術及開發流程。
該軟件與同類型軟件相比較,特點在于:1)能夠提供離線地鐵出口地圖,便于手機沒有信號的情況下,也能夠提供詳細的地鐵出口說明;2)直接觸控屏幕上顯示的地圖中的站點,便可以出現地鐵出口的詳細情況等。
Android一詞的本義指“機器人”,同時也是Google公司于2007年11月5日宣布的基于Linux平臺開源手機操作系統的名稱。該平臺由操作系統、中間件、用戶界面和應用軟件組成,號稱是首個為移動終端打造的、真正開放和完整的移動軟件。
Android分為4層,從高到底分別是應用層、應用框架層、系統的運行庫層和Linux內核層。
應用層:用JAVA語言編寫的運行在虛擬機上的程序。Google最開始時就在Android系統中捆綁了一些核心應用,比如E-Mail客戶端、SMS短消息程序、日歷、地圖、瀏覽器、聯系人管理程序等。
應用框架層:是編寫Google發布的核心應用時所使用的API框架,開發人員也可以使用這些框架來開發自己的應用,簡化了程序開發的架構設計,但是必須遵守其框架開發原則。
系統運行庫層:含有C/C++的實現,包含C/C++庫,能夠被Android系統中不同組件使用,通過Android應用程序框架為開發者進行服務。
Linux內核層:Android最新的核心系統服務基于Linux3.0.1內核,如安全性、內在管理、進程管理、網絡協議棧和驅動模型等都依賴于該內核[1-2]。
軟件的總體設計思路是在android手機上開發一個地鐵出口查詢軟件,為用戶提供更為精細的出行計劃安排,方便更快捷的到達目的地。使用本軟件可以根據需求,查任意一個地鐵站附近的街道、可換乘公交路線及地鐵線路的首末班車時間,還能夠瀏覽地鐵站周邊詳細地圖信息。在圖1中表示了該軟件系統的實現的功能。如圖1所示,該系統主要由4個主要功能組成,分別是:
1)位置服務功能,該功能主要實現出口周邊導航定位功能;
2)出口選擇功能,該功能主要實現便捷服務和地圖信息顯示的2個子功能。其中,邊界服務功能主要是針對出口處公交路線換乘指南,和出口處街道指南。地圖信息服務功能主要包括在線周邊地圖顯示和離線地圖顯示,即使在手機沒有信號的情況下,也能顯示出口地圖;
3)運營時間功能,該功能主要實現地鐵首末班車時間的查詢功能;
4)智能查詢功能,該功能主要實現最近出口查詢功能,提供最為便捷的查詢服務。

圖1 軟件功能圖Fig.1 Software function map
基于上述思路,本軟件的設計可分為如下步驟:1)界面UI設計;2)數據的存儲與解析;3)操作圖片后地鐵站的變化后的坐標與原始地鐵站坐標的匹配;4)不同功能頁面的跳轉5)完善程序并打包發布。步驟的內容將在以下的章節中做詳細說明。
Android手機程序是由多個Activity交互組成的,對于獲取的操作信息在不同的Activity之間傳遞,由此實現不同的功能展示。程序的主界面是一張填充屏幕的上海市軌道交通圖,用戶通過多點觸控操作和長按屏幕來查詢所選的地鐵站點,因此該頁面采用了LinearLayout布局文件進行布局,然后再上面加一個ImageView控件,以此實現軌道交通圖在主界面的填充顯示。
選取站點進入后,顯示的是需要用戶進行選擇的信息,比如首末班車時間、出口地圖以及需查詢的幾號出口。在這里選用的是在LinearLayout布局文件上放置一個ListView組件,再通過ArrayAdapter適配器根據從數據庫中讀取的每個地鐵站不同的出口數目而適應顯示。同時加上Checked Text View控件以實現對用戶作出的選擇進行事件響應。
在出口地圖界面有一個ImageView控件用來放置離線的地鐵站周邊地圖,還有一Button按鈕提供在線Google Map選擇,這兩者都是在LinearLayout布局文件下實現的。接著在下一個布局文件中采用AbsoluteLayout布局,再引入Google MapView Widget,以實現Google Map的顯示。
對于站點出口信息是在LinearLayout布局文件中放置ListView組件,通過ArrayAdapter適配器根據信息量的不同適應顯示的。這一模塊和進入站點后顯示的界面有相似之處,只不過不再需要添加CheckedTextView控件[3-5]。
地鐵站的原始屏幕坐標是在模擬器上用鼠標分別點擊顯示并記錄到XML文件里的。當對軌道交通圖進行縮放、移動操作后,地鐵站的屏幕肯定會隨著用戶的操作而變化,因此需要設計出一種算法,能夠根據記錄圖片的各項變化,使站點原始坐標經過相應的轉換得出變化后的屏幕坐標。
3.2.1 XML存儲站點坐標
XML信息讀取后是被加載到內存里,而一般的數據庫讀取是通過頻繁的I/O訪問,在本軟件中,地鐵站的坐標會隨用戶的操作而快速頻繁變化,這對數據解析讀取的效率要求是很高的。把地鐵站原始屏幕坐標存放到XML文件中,在程序中通過合適的方法把信息解析出來可以使軟件的效率大大提高,因此這里我們采取將地鐵站的原始屏幕坐標以XML文件的格式進行存儲。
程序運行后,先對存儲在XML文件里的原始屏幕坐標進行解析,存入到一個新建的數組中,以實現下一步坐標的匹配。由于該數據文件比較小,而且不會隨著使用而增大,所以采用DOM解析器來解析XML數據。
DOM解析器將所有XML文檔讀取到內存中,然后允許使用DOM API遍歷XML樹、檢索所需的數據。這是非常直觀的代碼,并且,在某些方面比基于 SAX的實現更加簡單。雖然,DOM因為一切內容都會先讀取到內存中,因此通常比較占用內存,但由于本程序所需解析的XML文檔始終保持著很小的大小,以此使用DOM解析顯得更為方便快捷[6]。
3.2.2 坐標變換原理
所謂坐標轉換,就是將已記錄點的坐標轉變為動態變化后的坐標位置[7]。首先要了解手機屏幕坐標系統的正負值關系。如圖2所示,在笛卡兒坐標系統中x軸向右為正值,保持增加數值,而y軸向上為正值的增加數值,但手機屏幕坐標系雖然x軸向右是正值,但y軸卻是向下為正值,而且手機屏幕的原點也與笛卡兒坐標系統的不同,位于手機屏幕的左上角。

圖2 手機屏幕坐標系Fig.2 Mobile-phone screen coordinate
3.2.3 屏幕坐標變換算法
當對圖片進行操作時,可以時刻記錄圖片像素的變化情況,比如在x軸、y軸的移動距離x、y。當不再對圖片進行操作時,通過對比縮放前后的分辨率,可以得到整張圖片的變化比例,設為Sx、Sy。把用戶最終所點擊的坐標X1、Y1與縮放中心的坐標相減(一般為屏幕中心的坐標,會隨屏幕大小的不同有所不同,以m、n為例),除以縮放的比例s后,與屏幕中心的坐標相加,最終減去移動的距離x、y,即可得到所選擇地鐵站的原始坐標X0、Y0。設置一個合適的誤差范圍,當條件符合時,即可確定所選擇站點的編號,再由此編號來獲取出口的相關信息。以公式可表示為(X0-m)*Sx+m=X1;(Y0-n)*Sy+n=Y1,由此實現了地鐵站屏幕坐標匹配的全過程。
3.2.4 站點匹配的實現
當響應用戶在屏幕上的長按事件時,后臺會將當前的屏幕坐標通過自主設計的匹配算法自動搜索誤差范圍內的初始屏幕坐標。匹配成功即可得知用戶選擇的是哪一個地鐵站,由此可以從XML文件中得到和地鐵站坐標對應的編號。通過這個和站帶你對應的編號我們可以從數據庫中讀取該站點的所有信息,包括街道信息、可換乘公交、地鐵站周邊地圖,以及使用GoogleMap服務所必需的經緯度。
3.3.1 SQLite數據庫
作為被android完美支持的輕量級數據庫,SQLite的核心文件僅500多K,與大部分SQL有著很好的支持性,本身包含著零配置、事務化、跨平臺等一系列的優點。SQLite在Android系統運行時已被集成,每個應用程序均可對其進行使用[8]。本程序數據庫的存儲位置設置為:data/data/com.shou.MetroExitQuery/databases。
3.3.2 SQLite在應用程序中的集成
1)創建數據庫
Android本身并沒有提供數據庫,當程序中需要使用SQLite數據庫時,必須先自行創建,然后創建表、索引,填充數據[9]。 本軟件使用的數據庫是預先創建好的.sqlite文件。其中填充著上海市各個地鐵站的出口數據以便供程序中使用。系統會檢測要創建的數據庫是否存在,不存在則創建,若存在則打開。代碼如下:
mDbHelper=DatabaseHelper.getInstance(mContext);
mDb=mDbHelper.getReadableDatabase();
try{
mDbHelper.copyDataBase();
}catch (IOException e) {
}
2)打開數據庫
將加載程序時存放在databases文件下的sqlite數據文件打開,為出口信息的顯示做第一步準備。
Private static String
DB_PATH=
“/data/data/com.shou.MetroExitQuery/databases/”;
public void openDataBase() throws SQLException{
String myPath=DB_PATH+DATABASE_NAME;
myDataBase=
SQLiteDatabase.openDatabase(myPath, null,SQLiteDatabase.OPEN_READONLY);
}
3)數據的讀取
將不同表中的數據讀取出來進行整合利用,以作為數組進行傳遞利用。例如從數據庫中的存放街道名稱信息的“guide_street”列存到一個數組中,我們可以通過cursor.getColumnIndex(“name”)和 cursor.getString()結合的方法從數據庫中取得數據,代碼示例:
while (cursor.moveToNext()){
lid_1 =cursor.getString (cursor.getColumnIndex(“guide_street”));
guidence_street[nNum]=lid_1;
}
4)關閉
數據庫使用完畢,需將其關閉:myDataBase.close();
Google Map API是 Google為開發者提供的 Maps編程API,它允許開發者在不建立自己地圖服務器的情況下,將GoogleMap地圖數據嵌入到網站之中,從而實現嵌入GoogleMap的地圖服務應用,并借助GoogleMap的地圖數據為用戶提供位置服務。如圖3所示,集成Google Map的效果圖。

圖3 集成Google Map的效果圖(以上海南站為例;左為離線地圖,右在線地圖)Fig.3 Image map with google map(Shanghai South Station Map, left:Off-line, right:on-line)
3.4.1 安裝Google Map API
開發關于MAP的應用一般需要安裝Google Map API。啟動SDK管理器后選擇 “Installed Options”查看是否已安裝Google Map API,如果沒有則需在“Available Packages”中查找并下載安裝[10]。
當建立Eclipse工程,必須在Build Target中勾選Google API,版本根據安裝情況自主選擇。
3.4.2 從Google獲得map-api密鑰
獲得map-api密鑰,需要從用于簽名應用程序的證書里獲得MD5指紋,然后再Google網站上輸入它,以成相關的map-api密鑰。
首先必須找到調試證書,他由Eclipse生成和維護,可使用Eclipse IDE找到它的精準位置。在Eclipse工具下,選擇windows-->Preference轉到Android-->Build,則調試證書的位置將顯示在“Default debug keystore”字段中。
然后取得debug.keystore的MD5值。首先運行cmd命令行進入debug.keystore文件所在的路徑,命令行下輸入如下語句:keytool-list-keystore debug.keystore,這時可能會提示你輸入密碼,這里默認的密碼是 “android",這樣即可取得MD5值。
最后需要打開瀏覽器到Google Map API的主頁去申請一個 Map的 key, 網址:http://code.google.com/android/mapsapi-signup.html。在其中的MD5 fingerprint一欄中輸入填入上一步獲取的認證指紋(MD5),輸入后,點 Generate API Key,之后會產生本軟件需要的Google Map API。
至此從Google獲得map-api密鑰已經完成。
3.4.3 Google Map應用模塊
1)將Google Map的API KEY寫到顯示地圖的MapView控件中:
xmlns:android=“http://schemas.android.com/apk/res/android” android:id=“@+id/map_view” android:apiKey="API-KEY-HERE"/> 2)添加使用訪問權限 在AndroidManifest.xml配置文件中加上對Internet和Map的使用訪問權限,由于Google Map的API是另外提供的API,因此也需要使用use-library標簽進行說明: 3)MapController的使用 當需要對地圖顯示的地點、放大倍數等進行設置時,使用MapController可以很好的對地圖進行控制。獲得MapController對象的代碼如下: mMapController=mMapView.getController(); 當需要定位地點時,則需要構造一個GeoPoint表示地點的經緯度,然后使用animateTo 方法將地圖定位到指定的GeoPoint上,以上海南站為例的代碼如下: mGeoPoint = new GeoPoint ((int) (121.427658 *1000000),(int) (31.156707*1000000)); mMapController.animateTo(mGeoPoint); 整個功能模塊實現完成后,運行程序。我們以上海南站來舉例說明,選取幾個功能畫面,運行結果充分表明程序運行良好,整體設計滿足要求。 如圖4所示,主界面是一張上海地鐵交通圖,用戶可以用手指多點觸控對畫面進行操作。當用戶希望查詢地鐵出口的情況時,將兩只手指放到屏幕上,然后進行手指的移動,就能夠完成對主界面的放大或縮小,再通過移動主界面,找到的地鐵站所在的區域,按住該區域一秒(以上),系統會根據用戶的選擇進行準確的判斷,會自動進入顯示有上海南站全部出口及地圖信息的界面。 圖4 從主界面操作選取站點Fig.4 Operation that choose station from main menu 如圖5所示,選擇需要查詢的出口后,會進入提供關于該出口基本信息的界面,包括出口在線地圖、可到達街道、可換乘公交。出口在線地圖為地圖類信息,為用戶提供通該出口周邊的地圖信息,包括在線地圖和離線地圖;可到達街道和可換乘公交選項提供的是文字信息,包括從該出口可到達的街道、附近地標和附近的公交站點及可供換乘的公交。用戶根據需求,點擊相應按鈕即可獲得所需信息。 圖5 出口詳細信息顯示Fig.5 Information of subway exit 文中首先闡述了Android體系的層次架構,通過分析地鐵出行的實際需求,設計開發了并基于Android平臺的地鐵出口導航系統,并應用于上海南站的出口導航中。系統解決了屏幕坐標轉換算法,SQLite數據庫編程技術,以及Google Map的地圖展示。今后,在該軟件基礎上,還將增加利用GPS(全球定位導航系統)實現出口附近公交站點自動導航等功能。 [1]Hashimi S Y,KomatineniS,MacLeanD. 精通 Android 2[M].人民郵電出版社,2010. [2]楊豐盛.Android應用開發揭秘[M].機械工業出版社,2007. [3]余志龍,陳昱勛,鄭名杰,等.Android SDK開發范例大全[M].北京:人民郵電出版社,2009. [4]公磊,周聰.基于Android的移動終端應用程序開發與研究[J].計算機與現代化,2008(8):85-89.GONG Lei,ZHOU Cong.Development and research of mobile termination application based on android[J].Computer and Modernization,2008(8):85-89 [5]張仕成.基于Google Android平臺的應用程序開發與研究[J].電腦知識與技術,2009(28):7959-7962.ZHANG Shi-cheng.Development and research of application based on google android[J].ComputerKnowledge and Technology,2009(28):7959-7962. [6]劉磊,仇菊香,吳國洋.基于Google地圖服務的城市地理信息公共服務平臺的設計與實現[J].測繪標準化,2011(1):10-13.LIULei,QIUJu-xiang,WUGuo-yang.DesignandImplementation of public service platform for urban geographic information based on google map services[J].Standardization and Surveying and Mapping,2011(1):10-13. [7]李華明.Android游戲編程之從零開始[M].北京:清華大學出版社,2011. [8]韓善鋒,曹鳳海,易昌華.SQLite數據庫在嵌入式程序開發中的應用[J].物探裝備,2011(3):170-173.HAN Shan-feng,CAO Feng-hai,YI Chang-hua.Application of SQLite database in the embedded program development[J].Equipment for Geophysical Prospecting,2011(3):170-173. [9]Open source.開放源碼嵌入式數據庫SQLite簡介[EB/OL].[2005-08-22].http://www.ibm.com/developerworks/cn/opensour ce/os-sqlite/. [10]劉正,陳強.基于Android的GPS應用中的研究與開發[J].中國西部科技,2010(32):15-16.LIU Zheng,CHEN Qiang.Development and research based on android operating system and GPS technology[J].Science and Technology of West China,2010(32):15-16.4 系統應用實例
4.1 選擇站點

4.2 出口信息查詢

5 結束語