近年來,新技術(shù)的不斷涌現(xiàn),使得網(wǎng)頁功能更加豐富。數(shù)字地圖創(chuàng)造性地將傳統(tǒng)地圖與網(wǎng)頁相結(jié)合,極大豐富和方便了人們的生活。從最初的“無縫”圖片發(fā)展到現(xiàn)在的二維、三維,數(shù)字地圖,以其特有的優(yōu)勢,得到了人們越來越多的青睞。
在用戶體驗上,數(shù)字地圖為用戶提供了一種新的信息查詢方式,信息顯示更精準(zhǔn)全面,而查詢結(jié)果通常都是以標(biāo)記形式展現(xiàn),用戶的可視區(qū)域有限,如何在當(dāng)前縮放級別下,利用最小的區(qū)域展示出最全面的信息,而又不產(chǎn)生重疊覆蓋,就要利用到標(biāo)記聚合技術(shù),這也正是文章討論的中心。
一個開發(fā)地圖應(yīng)用的快捷方法是利用第三方的API。運(yùn)用美國衛(wèi)星航拍技術(shù)的Google地圖,以及與交通部門合作的百度地圖這兩個地圖服務(wù)商都為應(yīng)用程序開發(fā)者提供了API。Google與百度的API文檔相對其他服務(wù)商提供的文檔來說,更完備、詳盡、簡潔,并且給出了很多學(xué)習(xí)示例,非常適合初學(xué)者學(xué)習(xí)開發(fā)。Google更精準(zhǔn),精確度達(dá)小數(shù)點后14位,而百度地圖則是小數(shù)點后6位。但由于Google的ICP牌照已失效,因此理論上谷歌不能再向中國用戶提供Google Map和Google Earth服務(wù)了,所以文章最終采用百度Map API實現(xiàn)。
為了減小計算量,以下討論的三種算法只計算在視圖區(qū)域內(nèi)標(biāo)記點,在視圖區(qū)域外的不計算。
將視圖區(qū)域劃分成若干矩形,矩形的大小視地圖的縮放級別而定。將同一矩形內(nèi)的標(biāo)記點聚合成一個聚合標(biāo)記,該聚合標(biāo)記需記錄被聚合的標(biāo)記點個數(shù)或其他重要的統(tǒng)計信息。
利用百度地圖API中Map類的getBounds方法,獲取視圖區(qū)域的西南點及東北點的經(jīng)緯度數(shù)據(jù),并根據(jù)當(dāng)前的縮放級別確定出矩形大小,綜合這三個數(shù)據(jù)計算得出各個矩形的邊界。
現(xiàn)矩形劃分已定,需要解決標(biāo)記點的經(jīng)緯度到所在矩形區(qū)域的對應(yīng)問題。有個直接的方法是將每一個標(biāo)記點依次與視圖中的矩形區(qū)域邊界比較,直到有一個匹配的為止。這種方法簡單,但費(fèi)時,實驗中采用一種時間復(fù)雜度比較低的算法。
首先將視圖視為2維數(shù)組,按從上到下從左到右的順序依次對矩形編號,以lngDiff代表一個矩形所跨域的經(jīng)度,以latDiff代表一個矩形所跨域的緯度,以swp代表視圖區(qū)域的西南點,利用Math庫提供的下取整函數(shù)Math.floor,則點point所在的矩形行標(biāo)為:Math.floor((nep.lat-point.lat)/latDiff),列標(biāo)為:Math.floor((point.lngswp.lng)/lngDiff),這樣就找到了標(biāo)記點到矩形的對應(yīng)關(guān)系。對應(yīng)關(guān)系找到,標(biāo)記點的分類與聚合就可以順利完成。下一步就需要確定聚合點的顯示位置。
聚合點在矩形的顯示位置需要考慮當(dāng)前的縮放級別,若縮放級數(shù)低,為避免聚合點重疊,可以將聚合點顯示在矩形正中;若縮放級別高,則可選取矩形內(nèi)某個標(biāo)記點的位置為聚合點的顯示位置,這個標(biāo)記點可以簡單的選取遇到的第一個標(biāo)記點,也可以選取最靠近矩形中心的標(biāo)記點,或者可以根據(jù)標(biāo)記點內(nèi)容,選取最重要的點。
實驗中選取矩形中心為聚合點的目標(biāo)位置。圖1、圖2分別為使用聚合算法前后標(biāo)記點的顯示情況,可以看出,聚合后的信息呈現(xiàn)更加簡潔豐富。選取矩形中心為聚合點的顯示位置,可以避免出現(xiàn)圖3所示的情況,圖3中由于[3]
[2]矩形及[3][3]矩形的聚合點位置隨機(jī)選取為矩形內(nèi)的某個標(biāo)記點位置,而恰巧這兩個標(biāo)記點相鄰,這就使得聚合點發(fā)生覆蓋,信息無法讀出。
基于矩形的標(biāo)記點聚合實現(xiàn)簡單,但不夠靈活?,F(xiàn)實應(yīng)用中,標(biāo)記點多與國家地區(qū)相聯(lián)系,因此聚合時,常需要考慮標(biāo)記點間的距離。
首先需要解決地球表面上兩點間距離的計算問題。通常在不要求特別精確的情況下,將地球視為正球體,而實際上地球是個兩頭略扁的橢球體,因此實驗中得出的距離是個近似距離。在球面幾何中,定義正球體表面兩點間的距離為經(jīng)過這兩點的大圓所在的劣弧長,如圖4中弧AB即為A、B兩點間的距離。以 表示∠AOB的弧度,以R表示地球半徑,則根據(jù)弧長公式得到:A、B兩點間的距離為R。這樣,選取某個標(biāo)記點為基點,則其他點到基點的距離都可以得到。
以絕對距離劃分標(biāo)記點存在一個問題,在不同縮放級數(shù)下,同一距離對應(yīng)不同的像素點數(shù)目,而視圖區(qū)域的像素點數(shù)目是一定的,用戶是以兩點間的像素點數(shù)目來衡量點與點之間的距離,因此以間隔的像素點數(shù)目為標(biāo)準(zhǔn)設(shè)計聚合算法更合理(圖4)。
圖1 點聚合前
圖2 點聚合后
圖3 聚合點發(fā)生覆蓋
百度地圖API默認(rèn)使用墨卡托投影。選取經(jīng)緯線原點為平面原點,即原點位置為赤道與0度經(jīng)線相交的位置。在百度地圖API中,以18級為平面坐標(biāo)基準(zhǔn)級數(shù)。已知某點的經(jīng)緯度,利用BMap.MercatorProjection類可獲取該點在18級下的平面像素坐標(biāo),在其他級別下的像素坐標(biāo)可通過Math. floor (平面坐標(biāo)×2zoom-18)換算得到,其中zoom代表當(dāng)前縮放級別。至此,點的經(jīng)緯度坐標(biāo)到像素坐標(biāo)轉(zhuǎn)換完成,點的像素坐標(biāo)已知,則點間的像素距離不難得到。
圖4 地球表面兩點間距離示意圖
圖5 點聚合前
圖6 點聚合后
實驗中,取成都市為基點(經(jīng)緯度坐標(biāo):104.067923,30.679943),到該點的距離小于等于65像素的點被聚合,聚合前后標(biāo)記點情況分別如圖5、6所示。易實現(xiàn),基于距離的聚合算法則更靈活些。在實際應(yīng)用中,常在這兩種方法的基礎(chǔ)上增加一些限制條件,更精確的定位及聚合標(biāo)記點。
文章重點介紹了基于視圖矩形的聚合算法及基于距離的聚合算法的原理及實現(xiàn),基于視圖矩形的聚合算法簡單
[1]許輝,馬曉鵬. 基于web墨卡托投影地理信息系統(tǒng)設(shè)計與實現(xiàn).電腦編程技巧與維護(hù), 2011年第8期
[2]崔文紅. 電子地圖的應(yīng)用及發(fā)展趨勢. 測繪與空間地理信息, 2008年第3期