鄭祿喜 羅立宏






關鍵詞:三維地圖;定位;實時導航;Web平臺;Cesium
0 引言
隨著經濟的不斷發展,高樓大廈拔地而起,道路橋梁不斷增加,因此城市的面貌日新月異。現在人們來到一座陌生的城市,不再像以前那樣記住顯眼的標志,摸索著走幾段路就能到達目的地。通常都有著目的地就在附近的想法,但怎么都到達不了目的地,詢問當地居民才得知正確的路線。因現今的道路越發復雜,所以電子地圖成為出行必備的應用。但對于一些方向感較弱的人來說,當前的電子地圖應用給予的地理位置信息還不是很直觀,他們仍然會發生到達不了目的地的可能性。
三維可視化技術能夠給人們帶來強烈的視覺感受,即相比于平面地圖和哥倫布地圖,三維地圖能夠提供更為直觀的地理位置信息。國內外對于三維地圖領域相關的研究力度很大,黃娟娟等[1]在Unity3D上實現景區的可視化,然后利用改進隱性馬爾科夫模型的地圖匹配算法解決了三維地圖定位精度低的問題;田風勛[2]基于現有的PF等數字攝影測量系統生產平臺,利用3DMax等建模工具,通過C#語言輔以SkyLine開發包開發實景三維地圖;王亞美[3]、孫偉[4]各自的團隊都利用OpenGL ES在Android平臺上實現了三維地圖的可視化系統;???等[5]提出使用Kinect等深度相機生成三維地圖以及利用相機拍攝的2D圖像在三維地圖中進行位姿跟蹤,解決了室內無法接收GPS信號定位當前位置生成三維地圖的問題;Hildebrandt等[6]提出了面向服務的、交互式的大規模3D城市模型三維可視化系統架構,該架構為大規模3D城市模型的安全、穩健分布和交互式呈現提供了一種解決方案。
上述研究都通過不同的方法完成了三維地圖的構建,但都需要安裝相應的插件或軟件進行開發,難以實現跨平臺使用,并且研發產品可能在不同的平臺會不兼容。若基于Web平臺開發三維地圖,就能實現跨平臺的效果。由于以前各種條件的限制,在Web上渲染的3D圖形和三維交互的效果都不如在PC和嵌入式設備上的效果,所以很少基于Web平臺開發三維應用。但3D繪圖標準WebGL的出現,加上瀏覽器的性能越來越強,如今網頁上也能夠繪制和渲染復雜、精美的3D圖形。WebGL技術標準不需要安裝插件,只用一個文本編輯器和支持WebGL的瀏覽器就可以開發具有復雜3D圖形的網站或3D網頁游戲。因此,多種基于JavaScript 封裝WebGL API 的3D 引擎逐漸出現,如Babylon.js、Three.js和Cesium.js等,而Cesium.js很適合作為在三維地形、仿真和GIS等領域進行可視化的圖形庫,如袁凌等[7]將地形數據切片,利用Cesium加載地形、谷歌影像和風力發電機模型等要素構建三維場景,實現了風電場地形的三維可視化,能夠輔助風電場的建設和風機運行狀態監測;蘇昊翔等[8]在Cesium平臺上開發了衛星載荷可視化的仿真系統,該系統解決了跨平臺使用,無須使用特定軟件進行展示的問題,有利于仿真結果的可視化共享;GRAEME F.CLARK等[9]使用CesiumJS結合大數據開發一款基于Web的澳大利亞海洋碎片數據庫可視化工具,給專業和民間科學家提供多種方式探索海洋數據;Kilsedar,CE 等[10]利用CityGML和CesiumJS進行三維地理空間數據可視化并模擬洪水發生的過程,達到幫助有關適應措施和減輕洪水影響的知情決策過程的目的;畢碩本等[11]在模擬洪水災害過程的基礎上,還將熱帶氣旋路徑、所致損失等其他災害信息整合于Cesium的三維地球中。因此,本文通過Cesium.js結合高德地圖的Web服務API實現Web平臺的三維地圖實時導航服務。
1 Cesium 簡介
Cesium是用于創建強大的3D地理空間應用程序的基礎開放平臺,也是一款開源的基于JavaScript的3D 地圖框架。Cesium 開發平臺上有著Cesium Ion、ICoens是ium一JS個、C提e供siu3mDfoTrileUsn和rea地l三理空個間主數要據平的臺平。臺C,e它siu有m3D Tiles流式傳輸的最快的管道,可以把3D數據上傳到Cesium Ion中,在使用CesiumJS開發時可以通過申請的access token 直接訪問Cesium Ion 中的數據源;CesiumJS是一個開放源代碼JavaScript 庫,用于創建具有最佳性能、精度、視覺質量和易用性的3D地球和地圖;Cesium for Unreal是游戲引擎中的第一個高精度地球儀,將Cesium的真實世界的細節和準確性帶入了模擬環境。
CesiumJS是一個三維可視化引擎,底層核心基于WebGL技術構建,以WebGL技術作為其圖形渲染引擎,所以可以在支持WebGL的瀏覽器上運行,包括手機、平板、電腦的瀏覽器,所以它具有跨平臺的特點[12]。它有可精確分析的高精度WGS84地球儀,并提供了與地理空間坐標相關的計算功能;支持繪制幾何圖形;能夠加載KML、GeoJSON、CZML和terrain等多種類型的空間數據文件;支持3D Tiles、glTF模型、時間動態數據;可自由切換2D、2.5D、3D視圖模式。
一個完整的Cesium應用程序由五層組成,自下而上分別是核心層(Core) 、渲染器層(Renderer) 、場景層(Scene) 、數據源層(DataSources) 、部件層(Widgets) 。核心層主要是數學運算類,例如笛卡爾坐標運算、地理坐標運算和四元數運算等;渲染器層是WebGL的高級抽象和GLSL庫;場景層囊括了地形和影像引擎、三維模型、幾何圖形、矢量數據和攝像機等對象;數據源層是一個高級Entity API,封裝了場景類型和時間動態屬性;部件層是場景中的一些小部件,如動畫、視圖模式切換、全屏等控件。
2 關鍵技術
2.1 WGS84坐標與笛卡爾坐標的轉換
Cesium項目中經常涉及坐標轉換,如加載模型時的初始位置、模型或實體的空間位置變換等,在執行這些操作時,位置信息幾乎都是輸入經緯度坐標,但Cesium最終都會把坐標轉換為笛卡爾坐標來表達空間位置信息。Cesium中有兩種坐標系,分別是WGS84 坐標系(以下簡稱為84坐標)和墨卡托投影坐標系。本文使用的是84坐標,但Cesium中沒有84坐標相對應的類,所以用弧度表示經緯度,可以通過式(1)求得經緯度的弧度形式,R 表示弧度,D 表示經緯度角度。
84坐標轉換為笛卡爾坐標[13]:已知84坐標中橢球中 的 長 半 軸 a = 6378137.0、短 半 軸 b = 6356752.3142451793、緯度B、經度L、海拔H。根據式(2)求得笛卡爾坐標(X,Y,Z),式(2)中e1為橢球的第一偏心率,N 為橢圓曲率半徑,它們分別可根據式(3)求得:
笛卡爾坐標轉換為84坐標:將式(2)進行反向推導,可得到式(4),通過式(5)可將笛卡爾坐標轉換為84 坐標,但求得的84坐標是弧度形式,可通過式(2)推導出轉換為經緯度形式的式(5)。
2.2 偏移路線檢測
在導航過程中,判斷當前位置是否偏離了規劃的路線是很重要的,若偏離了路線,則需要重新根據當前位置作為起點重新規劃路線。本文采用了點是否在多邊形內作為判斷當前位置是否偏離路線的方法,點在多邊形外則表示偏離了路線。當前位置以點表示,構成該點是當前位置的經緯度坐標,規劃的路線是以曲線表示,構成該曲線是該路線的經緯度坐標集合。以曲線為中心,計算一個半徑為2 m的緩沖區作為多邊形,該多邊形是由點集P={(xi,y≤ i) | 1≤i≤n, n≥3}構成。當2 i≤n-1時,Pi分別與相鄰的兩個點Pi-1、Pi+1相互連接構成一條折線,最后P1與Pn連接形成閉合而構成一個多邊形。判斷點P0(x0, y0)是否在多邊形內的過程如下:
1) 判斷點P0是否在多邊形的邊界框bbox內。計算點集P 中x、y 的最值Xmin、Xmax、Ymin、Ymax,從這些最值中可組合成四個點,分別是點A(Xmin,Ymax)、B(Xmax,Y( max)、C Xmax,Ymin)、D(Xmin,Ymin)、這四個點可構成一個邊界框bbox (圖1 a),然后判斷點P0 是否在bbox里面,即Xmin≤x0≤ Xmax 且Ymin≤y0≤Ymax。若不在bbox范圍內,表示點P0在多邊形外,否則跳到步驟2)。
2) 利用射線法判斷點P0與多邊形的關系。從任意一點繪制一條到達點P0的直線(圖1 b),統計該條直線與多邊形相交的邊數k,通過式(6)計算出k 的奇偶性,點P0與多邊形的關系可用式(7)表示[14]。因為有一種點P0剛好就在多邊形的邊上,但k 為偶數的特殊情況,所以當k 為偶數時,還需要判斷點P0是否落在多邊形的邊上,跳到步驟3)。
3) 利用叉積法判斷點P0與多邊形的邊的關系。多邊形的邊集是它的點集中相鄰兩點和首尾兩點連接而構成的邊,只要點P0在邊集上任一條邊上,則點P0就是在多邊形的邊上。可用叉積判斷點P0與邊P1P2的關系,邊P1 P2是由點P1(x1, y1)和點P2(x2, y2)連接而成,通過式(8)可求得點P0與邊P1 P2的叉積Pc,若Pc = 0,則點P0與邊P1 P2共線[15]。
2.3 相機模式
2.3.1 相機跟隨
在三維地圖的實時導航中,場景中的相機需要一直跟隨表示當前位置的標志,所以需要實現相機跟隨的效果。Cesium中有很多函數可以改變相機的位置,但這些函數要么只能改變相機的視角,沒有平滑的跟隨效果,要么只有跟隨效果,相機的視角卻是固定的,所以需要將兩者結合起來,實現相機的視角始終跟隨在目標的后面。
Viewer中有一個trackedEntity的屬性,一旦給該屬性賦值,相機將一直跟隨該屬性中的目標,它的實現原理是通過式(10)計算出相機的新位置T,其中C 表示被跟隨目標的當前位置,D 表示相機的偏移量。
雖然trackedEntity解決了相機平滑的跟隨,但帶來了相機視角固定在一個方向的問題,即相機視角不會隨著跟隨目標的方向變化而變化,所以需要在這的基礎上,使相機的方向隨著跟隨目標的方向變化而變化。實現方法如下:一旦跟隨目標的位置發生改變,就通過式(11)、式(12)計算目標之前的位置點P(L1, B1) 和當前位置點Q(L2, B2)的方位角A(點P、Q 坐標中的L、B 分別表示經度、緯度),然后利用式(5)把方位角A 轉換成角度形式,最后對方位角A 取模360求得最終的方位角A,其中點P、Q的經緯度是以弧度來表示[16],一旦方位角A>5,就使相機繞Z軸旋轉A 度。
2.3.2 第一人稱視角
相機模式設為第一人稱視角,相當于把相機當成人的眼睛,即相機的朝向能夠和人的視線一樣變換,通過監聽DeviceOrientationEvent事件獲取設備的物理旋轉信息作為相機朝向改變的數據源實現和人的視線一樣變換。它的事件屬性有α、β、γ 三個屬性,分別表示設備繞Z、X、Y軸旋轉的角度,利用α 表示視線左右搖擺,β 表示上下搖擺。實現第一人稱視角的功能只需α、β 兩個屬性,當設備指向正北時α=0,設備逆時針旋轉,則α 值增加,α 的范圍為[0,360];當設備水平擺放時β=0,設備頂部向上方傾斜則β 值增加,β 的范圍為[-180,180]。
通過α 控制相機左右兩側的朝向和導航標志模型的朝向,β 控制相機上下兩方的朝向。基于用戶手持設備的習慣,相機上下兩方的朝向需要做一定的限制,即β=0時,相機朝向為地面;β=45時,相機朝向為水平方向;β=90時,相機朝向為天空。假設相機上下旋轉角度A'的最佳配置為:A'=-90表示地面;A'=0表示水平方向;A'=30表示天空,通過式(13)可獲得最終的旋轉角度A'。
3 功能實現
3.1 開發前的準備
把項目中需要加載的資源上傳到Cesium Ion中(需要在Cesium官網中注冊賬號并申請一個Access Token) ,如3D Tiles、模型和圖片等資源,并獲得資源的accessId;還需要在高德開放平臺注冊為開發者并創建一個Web服務應用,得到該應用的Key。
3.2 搭建Cesium 場景
3.3 路徑規劃
在頁面中添加關于路徑規劃功能的控件,如起點、終點的輸入框、右鍵菜單、規劃路線的信息顯示框等控件,并根據情況控制它們的顯示和隱藏,這些前提準備完成之后,就可以進行路徑規劃功能的實現,該功能的流程圖如圖2所示。
1) 獲取起點和終點的經緯度。獲取經緯度的方式有兩種,一是在起點、終點輸入框中輸入地址,利用高德的地理編碼服務將該地址轉化為經緯度;二是單擊鼠標右鍵彈出菜單,點擊菜單中的起點、終點來標記起點和終點,通過右鍵點擊的屏幕坐標轉化為笛卡爾坐標,再將笛卡爾坐標轉化為經緯度,最后需要將84坐標系的經緯度轉化為高德地圖坐標系的經緯度,Cesium 中的viewer.camera.pickEllipsoid()函數可將屏幕坐標轉化為笛卡爾坐標。
2) 路徑規劃。通過ajax請求高德的路徑規劃服務接口,如駕車路徑規劃請求的url:https://restapi.amap.com/v3/direction/driving?origin=longo,lato&destination=longd,latd&key=keyString。url中的參數origin、destination分別是起點和終點的經緯度(longo, lato) , (longd, latd),keyString是用戶申請的Web服務應用key,這些參數是必填項。除了駕車路徑的接口外,還有公交路徑規劃和步行路徑規劃的接口,它們的url分別是: tegrat①ed?hptatpras:m//eretestrasp;i. amap. com/v3/direction/transit/in?②https://restapi.amap.com/v3/direction/walking?pa?rameters。parameters表示請求中的參數,根據控件中選擇查詢的方式分別向這些url發起請求。
3) 封裝信息。把返回的json數據中的必要信息封裝到一個對象中,如路線的起點和終點經緯度、路線的詳細信息、路線的經緯度數據等。路線的經緯度數據的值在結果中多個經緯度拼接成的字符串,需要對其進行分割用數組儲存,而且結果中的經緯度用于84坐標會有一定的偏差,需要對其轉化為84坐標下的經緯度。
4) 繪制路線。把路線的經緯度數據作為數據源,利用GroundPrimitive類來繪制緊貼地形的線段,即路線,并且通過路線的數據創建一個SampledPosition? tPrraocpkeErtnyti的ty使實相例機賦沿值著到該一條個路實線體進上行,漫即游可。通過viewer.
路徑規劃功能的效果如圖3所示。
3.4 實時導航
在實時導航的過程中,需要獲得用戶的當前的經緯度位置,并需要持續返回用戶移動時更新的經緯度位置,根據獲得的經緯度位置來更新導航標志模型的位置和檢測當前是否偏離了規劃的路線。若偏離了路線,則需要根據當前位置重新規劃路線。一旦自行結束導航或抵達目的地則導航結束。該功能的流程圖如圖4所示。
1)Positin獲事取件當能前夠位持置續。獲H得5地用理戶定移位動功時能的中位的置w,這atc一h?特性恰好符合持續獲得用戶位置的需求,所以需要監聽該事件獲得導航過程中用戶的當前位置,而該事件的位置信息是以經緯度坐標形式返回,所以可通過式(1)、式(2)把經緯度坐標轉換為笛卡爾坐標,然后把該笛卡爾坐標設為導航標志模型的新位置。
2) 檢測是否偏離路線。在繪制路徑的同時,也會繪制一個路徑的緩沖區。該緩沖區是以路徑為中心繪制半徑2m的多邊形,如圖5中的線段表示路徑,橢圓部分表示路徑的緩沖區。在獲得新位置坐標后,需要檢測新坐標是否在該緩沖區的bbox范圍內,若在bbox區域外,則表示當前已經偏離了路線;若在bbox 區域內,則需要通過射線法檢測該坐標是否在緩沖區內,若在緩沖區外,則表示當前已經偏離了路線。
3) 偏離路線。若當前位置偏離了路線,則需要以當前位置為起點重新規劃路線。在重新規劃路徑前需要清空之前路徑的相關信息,包括路徑途徑點、導航信息和路徑緩沖區等信息。
4 結束語
本文通過結合Cesium與高德Web服務API實現了Web平臺的三維地圖實時導航服務、路徑規劃、路徑漫游等基礎功能,研究了經緯度坐標與笛卡爾坐標轉換、點線面的關系、相機模式等關鍵技術,達到了在不同的操作系統下都可以通過瀏覽器訪問三維地圖的效果,完成了跨平臺需求。本次研究中的城市模型是白模,這方面有極大的優化空間,接下來將嘗試使用傾斜攝影技術構建一個更為真實的城市模型。三維地圖實時導航在交通出行、城市規劃、景區、高校、商業圈等區域的導航和宣傳等領域都有一定的應用價值。