999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

手機三維地圖顯示引擎的設計與實現

2020-02-05 02:19:10顧茂強
電子技術與軟件工程 2020年7期
關鍵詞:瓦片引擎

顧茂強

(首鋼工學院 計算機與媒體藝術學院 北京市 100041)

近年來,隨著CPU 等硬件性能的大幅提升,以及無線網絡模塊、GPS、電子陀螺儀等配件的配置,再加上簡單易用的手機操作系統iOS 和Android 的加持,智能觸屏手機已成為較適合地圖APP 的運行平臺。由于手機的便攜性,手機地圖APP 日益頻繁地出現于日常的活動中,包括打車、訂餐、導航等,甚至不少司機將其用作主導航系統,而將車載導航系統用作手機電池電量不足或接聽電話時的備份[1]。

手機地圖APP 的常見的功能主要包括路徑規劃、方向引導、地圖定位匹配、地圖信息檢索、地圖渲染顯示等,其中地圖渲染顯示功能為其他功能提供顯示、交互支持,是手機地圖APP 的核心部件[2]。而iOS 和Android 都提供了OpenGL ES 的接口,完全滿足三維地圖開發的要求。與二維地圖相比,三維地圖直觀立體的可視化效果更符合人們的認知習慣和認知規律[3],能夠滿足用戶在手機上日益增長的圖形交互體驗的需求。

隨著三維渲染技術研究的不斷發展,以及電子地圖應用的不斷深人,不少公司和學者正將三維技術應用于地圖可視化。目前主流的手機地圖App 如google maps、高德地圖等,均采用了三維地圖作為導航地圖展示的主要方式[4]。OSM(OpenStreetMap)已經成為權威數據的的一個重要的替代來源,Brinkhoff Thomas 從OSM 要素中獲取足夠精度和性能的建成區和城市區域,并對結果的質量進行探討[5];Brovelli Maria 和Zamboni Giorgio 通過地圖匹配和相似性檢查,從OSM 中檢測出建筑物、計算出完整性指數[6]。架構對手機地圖渲染顯示功能來說也很重要,José M.Noguera 等人根據渲染操作發生在客戶端還是發生在服務端,將地圖渲染架構可以分為本地渲染架構、客戶端渲染架構、服務端渲染架構、混合渲染架構,設計、開發了三維地圖混合渲染架構,在移動客戶端和遠程服務器間自適應分配地圖渲染任務[7];王亞美、魯田在Android 手機上實現了二、三維地圖的渲染功能,闡述二、三維地圖渲染用到的緩沖機制、多線程機制、模型精簡等關鍵技術[8]。

為了實現三維地圖的手機端顯示,本文基于iOS 或Android 系統上的OpenGL ES 2.0,歸納總結了手機上三維地圖渲染引擎的開發流程,以OSM 為數據來源,以SDK 為主體設計且實現了手機平臺的三維地圖渲染引擎,并開發了相應的應用程序。該三維地圖渲染引擎的SDK 增強了對地圖的三維動態可視化描述,具有簡單的開發接口,能簡化客戶端的開發流程,具有一定的實用價值和應用前景。

1 整體設計

一個完整的三維地圖渲染引擎包括服務器端和客戶端兩個部分,如圖1 所示。

圖1:地圖渲染的整體架構

圖2:地圖渲染矢量數據的邏輯模型

1.1 地圖客戶端

地圖客戶端劃分為3個層次,即客戶端OS層、SDK層和App層。其中地圖渲染SDK 是地圖客戶端乃至整個地圖渲染功能的核心,它適配主流的Android 與IOS,被APP 層調用,對UI 事件做出響應,調度管理地圖矢量數據和樣式數據,基于OpenGL ES渲染基礎地圖、3D 模型等要素。

地圖渲染SDK 又可以劃分為第三方庫、渲染引擎、地圖引擎和接口封裝等幾個子層。

第三方庫子層為整個渲染SDK 提供基礎函數功能,包括開源字體引擎庫FreeType 庫、跨平臺(Windows, Mac,Linux)應用程序框架類庫JUCE、PNG 文件讀寫的庫libpng、嵌入式數據庫sqlite3 等。

渲染引擎響應來自于APP UI 的touch 事件,為地圖引擎提供地圖元素渲染服務。其中,資源管理器實現對圖片資源、3D 模型的本地文件到內存的加載、卸載以及網絡下載等管理;字體管理器基于FreeType 開源軟件庫實現對字體文件的加載、更換以及字體圖片的渲染等工作;相機模塊保存了地圖地理中心點GeoCenter 等狀態信息,接受來自相機控制模塊的控制并因此更新自己的狀態參數及相關的坐標變換矩陣,提供坐標變換服務;相機控制器提供了包含了動畫參數的平移、旋轉、縮放、傾斜等接口,接受手勢識別模塊的調用;3D 對象渲染器實現對3D 對象的渲染。

地圖引擎對地圖矢量數據和地圖樣式數據進行管理,調用渲染引擎中的3D 對象渲染器的接口進行地圖等對象的渲染。其中,矢量數據管理模塊采用三級緩存機制對矢量瓦片數據進行管理并對數據的渲染前3D 建模準備(如建筑數據的柱狀拔高、道路線的擴展成面等)等;樣式數據管理模塊主要用于實現對多個地圖渲染樣式(style)文件的加載、當前被使用的地圖渲染樣式(style)文件的設置和替換、樣式元素的查詢等操作;基礎地圖(BaseMap)渲染模塊調用渲染引擎中的3D 對象渲染器的接口進行綠地、河流、道路、樹木模型等對象的渲染。

MapView 類是一個C++封裝類,它采用Facade(外觀)模式,為地圖渲染SDK 中的各類(或結構與方法)提供一個簡明一致的界面,隱藏地圖渲染SDK 的復雜性,使之更加容易使用。

而地圖渲染SDK 是使用C++語言開發的,針對Android 上的APP 需要把MapView 封裝成JNI 接口,針對iOS 操作系統上的APP 需要把MapView 封裝成Objective-C 接口,接口封裝子層主要是完成這個功能。

1.2 地圖數據服務端

地圖數據服務端的cache 中存放著地圖渲染數據包括矢量瓦片數據、3D 模型數據等,對客戶端的數據請求作出響應。

瓦片數據是由來自于OSM 的地圖要素數據(如背景面、背景線、道路、樓塊、3D 模型、以及文字標注等)經過處理轉換得到的。在該處理轉換的過程中,首先對mid/mif 格式的地圖原始數據進行數據過濾等預處理,然后采用按比例尺分層、層內分塊、層級數據復用的方式對地圖進行組織,最后將塊(即瓦片)內地圖數據要素存儲成符合OpenGL ES 圖形API 需求的二進制數據格式。層級間數據復用的目的在于減少最終數據量。圖2 即地圖渲染矢量數據的邏輯模型。

除了少量3D 模型外不做大規模手工3D 建模,而是在客戶端由地圖矢量數據生成3D 模型,以縮短數據制作時間、保證地圖繪制及開發的輕量級和高效。

本文采用業界常用的圖2 所示。

2 關鍵技術

2.1 三級緩存機制和線程模型

地圖渲染SDK 主要的工作流程是由客戶端APP 的UI touch 事件操作發起的。該事件被地圖渲染SDK 的手勢識別模塊轉換成對相機控制模塊的平移、旋轉、縮放、傾斜等接口的調用,從而更新了相機的狀態參數。地圖渲染SDK 根據相機狀態參數計算出屏幕范圍對應的地理范圍及其內的待渲染的瓦片ID 列表,從矢量數據管理模塊的緩存中提取出相應的瓦片數據進行渲染。

圖3:地圖渲染SDK 的線程模型

圖4:視圖變換和投影變換

圖5:兩遍法渲染天空

圖6:水系的渲染效果

圖7:反走樣紋理圖及其alpha 分量分布

圖8:建筑陰影的構建

為了提高客戶端地圖數據的處理效率,矢量數據管理模塊采用了瓦片三級緩存機制。第三級為存儲了所有地圖數據瓦片遠程地圖數據服務器;第二級為移動終端本地sqlite 數據庫,從服務器獲取的地圖瓦片數據首先緩存到本地sqlite 數據庫,并采用LRU(最近最少使用)算法替換數據。第一級為內存,從本地sqlite 數據庫獲取的數據會緩存到內存中,最多緩存64 個瓦片,數據替換的算法也是LRU。提取瓦片數據時,矢量數據管理模塊首先從速度最快的內存緩存中查找,查找不到的瓦片再讀取較慢的本地sqlite 數據庫;因為從遠程服務端下載數據速度最慢,所以第三級緩存是提取瓦片數據的最后選擇。

三級緩存機制的相關操作都是很耗費時間的操作。為避免UI界面和地圖渲染的卡頓現象,提升整體處理性能,采用多線程模式,將手勢事件處理、地圖渲染、數據獲取操作分別放入不同的線程,如圖3 所示。

2.2 地圖渲染SDK的坐標變換

地圖渲染SDK 中,坐標變換前的地理坐標原點、視點(攝像頭)均和OpenGL 的世界坐標系的原點重合;經過下列坐標變換后,最終變成繪制在二維屏幕上的場景:

(1)平移變換T:地圖平移到指定的中心點GeoCenter(x,y,0);

(2)縮放變換S:地圖縮放到指定的比例尺級別ZoomLevel;

(3)旋轉變換Rz:繞z+ 軸逆時針旋轉指定的方位角bearing,bearing 的取值范圍為[0,360 度];

(4)旋轉變換Rx:繞x+軸順時針旋轉指定的倒伏角pitch,pitch 的取值范圍為[0,85 度],pitch 取0 度時,視線垂直于地圖平面;

(5)視圖變換V:將視點(攝像頭)向z 軸正向移動一個視距sightDist 的距離,視線指向OpenGL 的世界坐標系的原點,視點的up 向量為(0,1,0),如圖4 左圖;

(6)地圖透視投影變換P:投影矩陣P 采用類似于gluPerspective( fovy, aspect, zNear, zFar)類的軸對稱透視投影函數來計算,其中fovy 取[45~60]度范圍內的一個角度,各參數如圖4 右圖。

經過上述6 個步驟,將地圖的地理坐標 (x,y,0)投影轉換成屏幕坐標(xPixel,yPixel,0) ,即

3 三維地圖的可視化實現

3.1 天空的渲染

在地圖場景渲染天空,不僅使地圖場景更加逼真,而且在大倒伏角度時能填補地圖上方空缺、減少要渲染的地圖矢量瓦片數量。地圖天空的渲染方法有如下4 種[9]:方法1 是清除背景時用近似于天空顏色的淡藍色,但是在三維地圖場景中,這種方法渲染出來的天空因為缺乏正確的深度信息而無法遮擋天際線處的樓宇等立體模型,導致渲染出樓宇飄在天空的奇怪場景;方法2 是天空盒,它采用立方體貼圖模擬的天空,這種方法較逼真,但在立方體的棱角處會產生明顯的接縫;方法3 是天空穹,它用半球面模擬天空,但是渲染過程中使用過多的頂點,涉及過多的三角函數的計算,影響渲染效率;方法4 是曲面型天空模型,采用三角條帶加紋理貼圖的方式渲染,但是仍然涉及較多的計算。

本文采用更簡單的兩遍渲染的方法實現天空的渲染:

第一遍畫2D 天空顏色信息:采用正射投影(ortho),打開顏色緩沖區、關閉深度檢測,在屏幕視口的上部畫出天空,如圖5(a)所示;

圖9:FPS 測試

第二遍畫3D天空深度信息:在透視投影下,求出圖5(a)中 A、B、C、D 四點的地理坐標,然后在關閉顏色緩沖區、開啟深度檢測的條件下,采用三角條帶的方式渲染這4 點構成的四邊形。

3.2 背景面的渲染

背景面形狀包括草地、林地、水系(河流、湖泊等)等地圖數據元素,采用無縫紋理平鋪貼圖的方式渲染的。通過對每個紋理坐標做某個方向向量的定時偏移,實現水系背景面水波紋動畫的效果。

為了使得水系的渲染更加立體、逼真,突出水岸邊的效果,水系以外的背景面渲染在z=0 的地平面上,而水系則渲染地平面以下的z=-Z(Z>0)平面,水系的岸邊渲染樹立的平面表示岸邊,如圖6 所示。

3.3 道路的渲染

GLES 對于三角形類型的繪制方式(如三角形條帶GL_TRIANGLE_STRIP)的支持很好,三角形上紋理貼圖的支持更是獨到。

在矢量瓦片中,道路數據是以無寬度的折線形式提供的;而在地圖SDK 中,寬度可控的道路是采用三角形條帶GL_TRIANGLE_STRIP 的方式渲染的。首先對道路折線進行曲面細分,方法是沿著折線路徑獲取每個點的法線,并在每側向外擴展一半的線寬,以得到三角形條帶;然后設置三角形條帶每個頂點的紋理坐標,把紋理圖片延展到適當的頂點位置上;最后在啟用混合的情況下,采用GL_TRIANGLE_STRIP 繪制方式對道路進行繪制。

道路采用兩遍渲染。第一遍依然是用較大的寬度渲染出整體上圓潤的道路輪廓線,方法是通過設置紋理坐標把如圖7 所示的圓形反走樣紋理延展到三角形條帶適當的頂點位置上,使得道路輪廓線的線帽和拐點都是圓頭;第二遍用略小的寬度渲染道路的車道線。

3.4 建筑陰影的渲染方法

在三維電子地圖中,建筑要素及其陰影的存在,使得整個三維地圖的場景真實感得到增強。

矢量瓦片中只存儲了建筑底面多邊形和高度信息。地圖渲染SDK 是對建筑的底面進行柱狀拔高建模后渲染的。

傳統的陰影實現方法包括平面陰影、陰影映射[10][11]、陰影體[12]、光線跟蹤等。但是陰影映射、光線跟蹤兩種方法的實現較為復雜,光線跟蹤技術的渲染效率較差;文獻[13]提出一種建筑陰影渲染方法,但是也比較繁雜。而平面陰影生成方法較簡單、性能好,本文進一步簡化了平面陰影技術,結合FBO 技術,用于實現太陽平行光下的建筑陰影的渲染,更加簡單方便,能滿足手機渲染的性能和效果要求。

以圖8 為例,已知建筑底面由點B0、B1、B2、B3、B4 構成,太陽的平行光向量在地面上的投影向量為V,影子長度為shdLen,則頂面在地面上的投影相當于底面在地面上沿著V 的方向偏移shdLen 的距離,即頂面每個點在地面上的投影Si(i=1,2,...,4)坐標可以通過下面的公式計算得到:

ShdLen 的大小這里簡單地指定為樓高的某個百分比,受到當前時辰的制約;V 向量則受到當前時辰和樓位置緯度的制約。

顯然,圖8 中陰影的三角條帶坐標序列為B0、S0、B1、S1...B4、S4,可以采用三角條帶方式將其直接畫到地面上。但是這種方法只能渲染各個建筑的陰影相互間沒有重合相交的情形,這在地圖渲染中是不現實的。為解決這個問題,本文采用了FBO,因此建筑陰影的具體渲染步驟是先關閉GL_BLEND 和GL_DEPTH_TEST、通過GL 的三角條帶渲染方式以灰色渲染到離屏渲染的FBO 中,然后打開GL_BLEND 和GL_DEPTH_TEST,將FBO 紋理渲染到屏幕上。

圖10:16 級和18 級三維地圖顯示效果示例

4 性能測試

地圖渲染SDK 適配了當前主流的iOS 和Android 系統。地圖數據服務器端測試用的地圖數據是由來源于OSM 的印尼雅加達范圍內容的數據經過分層分塊處理的數據。地圖渲染SDK 及相應App 主要在PC 機上用VC2010 進行模擬開發;PC 上基本開發調試完成后,將代碼整合移植到MAC 機上的iOS 版本導航App 中,并利用Mac 上的Xcode 環境進行性能評測和相關bug 的修正;最后在AndroidStudio 環境下微調適配Android 版本的導航App。

地圖渲染SDK 性能的定量測試分析是在MacBook 上的Xcode環境下連接iPhone6 真機進行的。測試方法是一邊打開Xcode 的instruments 工具,一邊對三維地圖畫面進行勻速瀏覽測試,具體做法是在手機地圖上先后分別用常速、較快的速度勻速左右滑動屏幕,接著用常速和和較快的速度勻速旋轉屏幕。圖9 是Xcode 的instruments 工具的測試結果,從中看出程序啟動后穩定運行時的FPS 大于20。

從測試操作時的感覺來看,除了16 比例尺,在其他大于16 級的比例尺下的常速瀏覽地圖時感覺不到明顯的卡頓現象;而快速瀏覽地圖時在所有大于17級的比例尺下都感覺不到明顯的卡頓現象。

從測試結果來看,16 和17 級比例尺下地圖瀏覽時就有卡頓現象,是因為這級比例尺下加載的地圖數據較多,需要顯示的三維立體地圖要素超過了CPU、GPU 的負載能力。而在比例尺大于17 級的情況下,盡管有不少立體地圖要素要顯示,由于地圖可顯示地理范圍迅速變小,加載的地圖數據也少了,因此顯示負荷小了很多,顯示速度明顯變快。如圖10 左圖和右圖分別是16 級和18 級三維地圖顯示效果示例,明顯可見16 級地圖范圍更廣,顯示的地物更多。

從顯示效果和性能的定性、定量測試結果來看,地圖渲染SDK顯示效果良好,性能也基本能滿足手機導航地圖渲染的要求。

5 結論

本文根據Android 和iOS 平臺上OpenGL ES 程序開發的特點,將三維渲染技術應用于地圖顯示表達,對三維地圖引擎的客戶端架構和服務端數據模型進行了設計,描述了三級緩存機制和線程模型等關鍵技術,詳細介紹了客戶端SDK 的三維地圖可視化實現方法,并對客戶端SDK 進行性能測試分析。經實驗驗證,整個三維地圖渲染引擎顯示效果和性能良好,完成了建設目標。本文設計的三維地圖渲染引擎具有一定普適性和使用價值。

猜你喜歡
瓦片引擎
河水
遼河(2025年7期)2025-07-25 00:00:00
慣性
揚子江(2019年1期)2019-03-08 02:52:34
藍谷: “涉藍”新引擎
商周刊(2017年22期)2017-11-09 05:08:31
無形的引擎
河南電力(2015年5期)2015-06-08 06:01:46
基于Cocos2d引擎的PuzzleGame開發
基于NoSQL數據庫的瓦片地圖服務
One Engine Left只剩下一個引擎
主站蜘蛛池模板: 亚洲国产精品日韩专区AV| 午夜一级做a爰片久久毛片| 狠狠做深爱婷婷综合一区| 欧美第一页在线| 亚洲精选无码久久久| 久无码久无码av无码| 国产亚洲欧美日韩在线一区| 视频二区中文无码| 欧美在线中文字幕| 国产主播福利在线观看| 欧美激情视频二区三区| 亚洲欧美成人综合| 国产91精品调教在线播放| 欧美日韩第二页| 国产成人91精品免费网址在线| 国产真实自在自线免费精品| 国产日韩丝袜一二三区| 国产浮力第一页永久地址| 亚洲无码日韩一区| 国产丰满大乳无码免费播放| 天堂在线www网亚洲| 亚洲成aⅴ人片在线影院八| 欧美日韩动态图| 亚洲午夜久久久精品电影院| 999在线免费视频| 欧美综合中文字幕久久| 国产欧美视频在线| 国产精品伦视频观看免费| www精品久久| 免费毛片全部不收费的| 亚洲国产成人久久精品软件| 美女被躁出白浆视频播放| 国产免费久久精品44| 一本大道视频精品人妻| 成人精品在线观看| 日韩成人免费网站| 国产自在自线午夜精品视频| 亚洲香蕉伊综合在人在线| av大片在线无码免费| 91成人在线免费视频| 国产成人精品高清不卡在线| 亚洲乱强伦| 日韩精品毛片| 国产SUV精品一区二区| 国产av无码日韩av无码网站| 欧美激情视频二区| 99这里精品| 午夜国产大片免费观看| 免费一级毛片在线播放傲雪网| 伊人成人在线视频| 色久综合在线| aaa国产一级毛片| 青青网在线国产| 日本a∨在线观看| 国产精选小视频在线观看| 久久天天躁狠狠躁夜夜2020一| 亚洲国产高清精品线久久| 欧美一区二区精品久久久| 人与鲁专区| 国产肉感大码AV无码| 精品人妻无码区在线视频| 欧美精品1区2区| 亚洲美女AV免费一区| 亚洲性网站| 国产高清在线观看| 国产三级韩国三级理| 久久免费视频6| 精品一区二区三区波多野结衣| 中文字幕丝袜一区二区| AV在线麻免费观看网站 | 欧美日韩在线成人| 国产在线专区| 亚洲日韩AV无码一区二区三区人 | 国产永久在线视频| 日韩 欧美 小说 综合网 另类| 99这里只有精品免费视频| 91视频青青草| 九九热免费在线视频| 内射人妻无套中出无码| 99草精品视频| 久久久久88色偷偷| 99视频有精品视频免费观看|