肖現臣
(濟南市勘察測繪研究院,山東 濟南 250101)
近年來,智慧城市、數字孿生城市是數字化城市建設的熱點,隨著應用與研究的進展,誕生了許多數字化城市系統,為城市基礎設施查詢、分析、顯示和管理提供了極大便利,同時進一步促進了數字城市理論的發展[1]。
在數字化城市建立的過程中,GIS與BIM技術發揮了極為重要的作用[2]。對于城市級、規劃片區級的大場景三維數字城市的建設,目前技術比較成熟,可選的基礎技術方案有ArcGIS API for JavaScript 4.X系列、Cesium等[3],且都具有各自的技術生態鏈,提供系統構建各環節的技術支持。而GIS與BIM在城市細部空間的應用,即關注點在小型園區、工廠、加油站、泵站等較小范圍的小場景三維地理信息系統,作為大場景數字化城市系統的補充,能夠關注到更多、更細粒度的研究內容,是建設數字孿生城市不可或缺的一部分。
本文研究了如何基于Three.js框架搭建小場景三維地理信息系統,并對實踐過程中形成的關鍵技術進行闡述。
Three.js是一個開源JavaScript三維渲染引擎,它對WebGL進行封裝的同時不損失其靈活性,并提供了易于使用的開發接口,讓前端開發人員在不需要掌握很多數學和圖形學知識的情況下,也能夠輕松在瀏覽器端進行三維應用的研發,不但降低了門檻,也大大提升了效率。同時,Three.js的開源特性,讓基于Three.js構建的三維應用可免費用于商業和非商業用途,減少項目成本。
選取Three.js搭建小場景三維地理信息系統的另一個優點是它對多類模型的支持能力,Three.js支持obj、glTF、3ds max、FBX、Collada、Babylon、draco等眾多三維模型格式,可最大可能將現有三維模型數據運用到建設項目,無須重復建模,減少工作量和成本。
Three.js作為對WebGL的封裝,具有簡單易用的特點。使用Three.js的場景(scene)、相機(camera)、渲染器(renderer)三大組件即可完成初始化。初始化后,便可進行模型加載及上層應用的開發。
數據是地理信息系統的基礎,本研究將涉及的數據劃分為模型數據和屬性數據兩類。
模型數據主要存儲的是模型的空間幾何信息和必要的屬性信息(如模型名稱、唯一標識ID等)。對于模型數據的組織,參考具體模型的格式以文件、模型服務的兩種形式進行組織,如obj格式模型以文件組織、glTF模型發布為數據服務,Three.js對此兩種形式均提供了支持,通過其loader機制可以方便地實現模型的連接、加載。
屬性數據存儲的是模型豐富的社會經濟屬性、掛接附件等信息,以傳統關系型數據庫進行存儲,如Microsoft SQL Server,并通過模型的唯一標識與模型建立關聯。屬性數據在基于Three.js的三維地理信息系統中通過搭建后臺服務、前端發起AJAX請求的方式進行獲取。
由于Three.js將繪圖中心作為坐標系統原點即(0,0,0)[4],且場景操控的中心點也默認是原點,這樣做的優點是方便增加其他輔助模型或部件。因此,為了將地理實體模型放置在原點附近展示,需要建立模型自身地理坐標系到Three.js坐標系統的映射機制。
而小場景的模型、部件往往是分開建模、多文件存儲的,為保證多個模型的相對位置關系正確,我們做了如下處理:
(1)以加載的第一個地理實體模型的中心點作為基準,將該模型的中心點映射到Three.js坐標系統的原點,將該模型偏移、放置到映射后的位置。這樣就建立了模型坐標與Three.js坐標系的映射。
(2)由于地理實體模型都具有相同的參考系,后續加載的模型,以此映射進行坐標偏移、定位放置,即可確保地理實體模型之間正確的相對位置關系。
(1)模型加載
前文提到Three.js對多種格式的三維模型提供了支持,同時其也提供了接口一致的加載方式,即loader機制,如通過OBJLoader加載obj模型、通過GLTFLoader加載glTF模型等,使得模型的加載非常容易。
(2)模型圖層化管理
對地理數據進行分層加載并圖層化管理,是地理信息系統常用的數據管理思路,如圖1所示。

圖1 模型圖層化管理
在Three.js中,并沒有地理圖層的概念和機制,但是提供了圖層對象Layers和模型圖層屬性layers,圖層對象Layers可用于控制可見性,通過Three.js渲染器渲染場景的時候,場景中的模型圖層屬性layers必須和相機的圖層屬性layers一致,模型才會被渲染出來。因此,可借助圖層對象Layers和模型圖層屬性layers實現地理信息系統的圖層管理機制。實現方法如下:
①模型加載之前創建一個圖層對象Layers。
②模型加載后,將圖層對象Layers賦值給模型的圖層屬性layers,這樣可以通過圖層屬性layers區分模型所屬圖層。
③圖層顯示與隱藏的控制通過切換相機的圖層屬性來實現,將圖層對象Layers傳入camera.layers.toggle()方法即可。
對地理實體的屬性進行查詢,是用戶基于空間位置了解地物的社會經濟信息的常用操作,也是二三維地理信息系統的一個必備的基礎功能。基于Three.js搭建小場景三維地理信息應用,也可以實現此功能。下面以點選查詢功能的實現為例闡述屬性查詢的相關技術。
屬性查詢的關鍵點在于捕獲地理要素,在Three.js工程中即為捕獲模型,需要用到Raycaster射線類。Raycaster射線類用于鼠標去獲取在三維場景中被鼠標選中的一些物體。它的使用也非常簡便,步驟如下:
(1)首先,在當前Three.js實例所在的窗口對象中綁定鼠標click事件onMouseClick。
(2)在click事件中,可以獲取鼠標點擊處的坐標,根據此坐標和相機位置創建Raycaster實例。
(3)使用Raycaster實例的intersectObjects方法計算捕獲到的地理實體模型。
(4)對捕獲的地理實體通過材質做高亮顯示,并通過彈窗展示模型屬性或掛接的外部社會經濟屬性信息,模型屬性查詢與高亮顯示如圖2所示。

圖2 模型屬性查詢與高亮顯示
場景漫游對于三維地理信息系統是一個比較重要的功能,常用的漫游方式有地上地下漫游、室內室外漫游、街區路線漫游等,其原理是通過以一定的時間間隔不斷地切換相機和場景的位置,達到呈現給用戶的三維視圖平滑過渡的效果。
在Three.js中,通過不斷更新相機的位置和軌跡球控制器(Three.js自帶的場景操控工具)的目標朝向可以實現場景的漫游,如圖3所示,其實現流程有以下幾個關鍵步驟:

圖3 場景漫游的實現流程
(1)路徑規劃
規劃漫游路線,并在漫游路線中選取若干初始過程點(具有三維坐標的空間點),為正確還原路線走向,可在路線方向變化較大的區域,適當多選取過程點。
(2)獲取漫游過程點
為實現平滑、順暢的漫游效果,需要對初始過程點進行曲線擬合、過程點重采樣,生成場景漫游中實際使用的過程點。本研究中,通過Three.js提供的THREE.CatmullRomCurve3曲線函數實現了基于初始過程點擬合三維樣條曲線,并通過曲線按漫游步長進行重采樣,獲取到最終漫游過程點,重采樣形成的過程點越多,漫游效果就越平滑。
(3)漫游實現
通過編程實現場景的漫游,原理是首先將漫游當前點設置到第一個過程點:通過改變相機位置將Three.js的場景中心位置移動到第一個過程點,并通過當前點與下一個過程點的兩個坐標計算漫游方向,以此設置軌跡球控制器的朝向。然后按照時間間隔將當前點設定到下一個過程點,時間間隔可按設定的速率和兩點之間的距離進行計算。依次移動當前點到下一個過程點,完成場景的漫游。
為優化漫游效果,減少開發難度,本研究采用了第三方動畫工具TWEEN.js,通過TWEEN.js自動增加補間動畫使漫游更加平滑、順暢。
小場景地理信息應用往往在加載重點關注區域的同時,也會加載一定緩沖區范圍內的地形、建筑、道路網等地理要素,一是為了襯托場景,不至于太單調,二是為了區分場景的位置,便于了解周邊地物等。周邊地理要素加載后,如何突出重點研究區域是小場景要解決的一個問題,重點區域標注是常用的方法。
Three.js中的標注方法有多種,本文就實現思路和優缺點進行簡要闡述。實現標注有以下幾種方法:
(1)傳統HTML元素實現,使用DOM繪制元素、CSS設置樣式。優點是實現簡單,缺點是與場景結合的效果不好。
(2)使用Three.js的文字對象,并可結合文字貼圖THREE.TextGeometry進行美化。優點是實現簡單,效果與場景同步;缺點是設置顏色和動畫復雜,耗費資源大。
(3)使用Three.Sprite精靈,不但支持加載圖片,還可以通過canvas繪制圖形和文字。優點是文字效果豐富,方便繪制,尤其對于熟悉canvas編程的人員學習成本較少。缺點是生成后,分辨率固定,放大后會產生失真。
(4)使用底層著色器接口實現。優點是可較自由地定制開關、顏色、材質、動畫,效果豐富,與場景結合最好。缺點是學習成本很高。
具體項目應用中,可根據實際需求,通過以上多種方法的結合實現標注效果,如圖4所示。

圖4 通過著色器和Three.Sprite實現的重點區域標注(棱錐、文字框)
酷炫的動畫、流光特效,不但可以讓三維場景運動起來,還能營造強烈的視覺沖擊,給人留下深刻的印象。本節介紹幾個常用特效的實現技術。
(1)線狀地物流光效果
線狀地物流光效果常用于道路、地下管道等地理實體,用于突出流動效果,本文基于紋理偏移機制實現了道路的流光效果(圖5),實現關鍵技術如下:

圖5 道路流光效果
①首先準備一張流光紋理圖片,圖片為線狀需包含高光部分、暗色部分,才能做出流動的效果。
②使用THREE.TextureLoader加載圖片為紋理,并設置屬性wrapS、wrapT為THREE.RepeatWrapping意為可重復,設置needsUpdate為true意為需要更新。
③新建材質,將紋理作為貼圖賦值給材質。
④將材質賦給道路(線狀地物),在幀動畫中不斷改變紋理的偏移值(如texture.offset.x+=0.02),即可實現流光效果。
(2)建筑物線框模式
建筑物線框模式指的是隱藏建筑物的表面細節,僅展示建筑物的輪廓線,可以達到精簡界面烘托重點的作用。
本文實現建筑物線框的思路是通過THREE.EdgesGeometry方法提取建筑物模型的邊線,然后通過THREE.LineSegments構造線條對象,并應用線狀材質,到達線框模型的效果,如圖6所示。

圖6 線框模式實現效果
(3)后處理特效
三維地理信息系統的構建,對界面或模型進行調光、調色是必不可少的,Three.js提供了許多的后期處理通道,不但可以減少對復雜的著色器的使用,還能實現功能強大的光效設置,如輝光、邊緣泛光、抗鋸齒等,后處理特效可以通過THREE.EffectComposer組合器組合使用,給小場景三維地理信息系統建設提供了豐富的效果支持。
本文探索了基于Three.js三維渲染引擎構建小場景三維地理信息系統的技術路線,并研究了在Three.js框架下實現地理模型加載、圖層化管理、屬性查詢、場景漫游、模型特效處理等關鍵功能的相關技術,為構建智慧城市、智慧園區等小場景應用鋪平了道路。
研究表明,基于Three.js構建小場景三維地理信息系統的技術思路是可行的,Three.js對于模型加載與管理、系統功能建設、特效處理等的支持是豐富的、易用的,相比其他方案具有框架開源節約成本、兼容模型格式多、開發友好、特效豐富、易于集成等獨特優勢,這些都有助于Three.js在三維地理信息系統構建中進一步推廣應用。
BIM技術與GIS技術的結合應用,已經成為一種勢在必行的趨勢[5],相信基于Three.js的小場景三維地理信息系統建設方案將會在未來智慧城市、數字孿生城市的建設中得到更多的應用和發展。