Home

可透過組合Hashtag搜尋

Published

- 11 min read

應用Node.JS與QGIS展示數位建模成果:以太平溪流域歷史文化資源清查計畫為例

img of 應用Node.JS與QGIS展示數位建模成果:以太平溪流域歷史文化資源清查計畫為例

背景

之前在花蓮林業三部曲的發表會結束之後,用平板展示了自己在舊木瓜機關庫重建的3D模型,後來便有了參與這次調查計畫的機會。在這個計畫裡面,我主要是用攝影測量法協助紀錄結構較完整的家屋遺構,並在電腦裡重建家屋現況的立體模型。

執行過程中就有在想要怎麼呈現這些建模後的檔案,若直接存成.obj3D PDF都需要使用者下載額外的程式才能顯示,且模型解析度與尺寸提高時,obj檔的效率對公部門的電腦來說可能會是個問題。

除了立體模型之外,田調同時也記錄了家屋的位置、座向(方位角)、空間、全景相片與手繪的平面圖,是否有機會能整合這些資料到一個平台上,同時滿足效能與資料離線儲存的需求。

這篇筆記算是簡單紀錄我用一些Node.JS套件來展示田調資料的開發過程,目的是想將家屋的3D模型、全景照片、位置與座向等資料整合到同一個App來呈現,以解決過去展示調查資料時,使用者需為了不同的資料格式下載不同瀏覽程式的問題。

這算是我第一次使用Node JS等網頁前端的語言,都是去應用npm上現有的套件(還有請Github Copilot教我語法XD),不一定是最佳的做法,但就順便把過程紀錄下來。

方法

想法是用基於Node.JS的套件開發,將所有資源輸出成靜態網頁後打包成.exe可執行檔交付。

React Three Fiber

3D模型檔案格式的選擇上,使用適合網頁render並將材質(Texture)包在同個檔案的.glb格式,較.obj檔有較好的儲存的效率1

安裝Node.JS,並透過npm安裝React, React Three Fiber等相依套件後,參考基礎的React app說明文件建立React app。

   npx create-react-app my-app
cd my-app
npm run start

立體模型介面與render設定則直接參考React Three Fiber說明文件,將路徑指向所需的立體模型.glb檔後,調整模型顯示的尺寸與旋轉姿態,透過OrbitControls限制使用者的互動範圍並加上ambientLight光源,擷取部分App.js內容如下。

   const Model = () => {
  const gltf = useLoader(GLTFLoader, "./model.glb");
  return <primitive object={gltf.scene} scale={0.5} rotation={[0, Math.PI / 2, 0]} />;
};

export default function App() {
  return (
    <div className="App">
      <Canvas>
        <Suspense fallback={<Loader />}>
          <Model />
          <OrbitControls  minPolarAngle={0} maxPolarAngle={Math.PI/2} />
          <color attach="background" args={['#373a3f']} />
          <ambientLight intensity={2} />
        </Suspense>
      </Canvas>
    </div>
  );
}

由於網站發布的位置在本機,檔案路徑是相對的,我是直接在package.json裡面加上"homepage": "."設定成相對路徑。

執行npm run start後會在本機http://localhost:3000/部屬預覽用的靜態伺服器,透過瀏覽器即可看到當下的編輯結果。

預覽介面
透過瀏覽器預覽React Three Fiber與家屋模型

執行npm run build後即會在build資料夾內產生立體模型瀏覽器的靜態網頁。此時若直接點開資料夾內的index.html,會發現資源被CORS Policy擋住無法載入,此問題在利用Electron打包後即可解決。

Photo Sphere Viewer

除了立體模型外,田調時也有以RICOH相機拍攝家屋的全景照片。為了整合所有田調資料到同個平台,這裡使用React app配合Photo Sphere Viewer套件達成。

透過npm install @photo-sphere-viewer/core安裝套件後,一樣參考Photo Sphere Viewer的說明文件替換全景照片的路徑,再分別執行npm run startnpm run build即可預覽與編譯全景照片瀏覽器的靜態網頁。

QGIS

QGIS在這個專案的功能是作為最上層的圖台,讓使用者在圖台中點選後連結到上面提到的立體模型或全景照片的頁面,並利用QGIS2Web功能將圖台打包成基於Leaflet的靜態網頁。

將田野調查的家屋點位與空間資訊以python程式轉換為座向的點位資料,匯入QGIS製成家屋的座向圖,再將每棟家屋的Attribute table填入3D模型與全景照片瀏覽器的相對路徑,如<a href="./BU01/index.html" target="_blank">前往檢視</a>,即可讓QGIS2Web輸出時以超連結的形式render。

家屋座向圖
家屋座向圖。由於撰文時計畫尚未結案,故遮蔽部分識別資訊,並以OpenStreetMap作為底圖
Attribute table
家屋的Attribute table,連結指向3D模型與全景照片瀏覽器路徑

圖台介接中研院百年歷史地圖,提供1989-臺灣經建1版地形圖-1:25,000, 1954-臺灣地形圖-1:50,000,1921-日治臺灣堡圖(大正版)-1:20,000,1916-日治蕃地地形圖-1:50,000等圖層瀏覽,同時以OpenStreetMap Tile Server2作為底圖。

QGIS2Web輸出時,一直沒辦法顯示WMTS Layer,但將所有連線換成XYZ Tiles又沒有問題,不確定是不是CRS不一致造成的。

QGIS2Web
QGIS2Web輸出的靜態網頁,點選家屋後即會顯示先前在QGIS內設定的Attribute table內容

Electron JS

到目前為止,我們已經將立體模型檢視器、全景相片檢視器與上層的圖台輸出成靜態網頁,但若直接點開html檔會被CORS Policy阻擋而無法載入資源,此時便需要Electron JS協助將所有檔案打包成每個人執行後就可以瀏覽的程式。

這裡一樣是參考Electron JS的說明文件以及其餘線上資訊3,建立my-electron-app後將前面React Three Fiber、Photo Sphere Viewer與QGIS2Web打包出來的靜態網頁複製到my-electron-app/dist資料夾內,調整package.json內的欄位(節錄如下),執行npm run start即可預覽應用程式,安裝electron-packager後執行npm run build_win則可以將全部的資源編譯並部屬成exe執行檔。

   {
  "name": "太平溪流域家屋建模圖台",
  "version": "1.0.0",
  "description": "my electron app",
  "main": "main.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "electron .",
    "build_win": "electron-packager . WinApp --platform=win32 --arch=x64 --asar"
  },
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "electron": "^30.0.1"
  },
  "dependencies": {
    "electron-packager": "^17.1.2"
  }
}

初步結果

Demo影片

程式截圖

圖台介面
圖台介面,透過QGIS2Web與Leaflet呈現家屋空間座向,使用者點選後可連結至立體模型與全景相片
立體模型瀏覽介面
React Three Fiber顯示立體模型glb檔,可平移、旋轉、縮放以調整視角
360全景介面
Photo Sphere Viewer顯示360全景照片

未來可以做什麼?

  • 立體模型的呈現: 透過攝影測量法解析的相機姿態訓練Gaussian splatting模型,以重建環境中的植被與光影等更細緻的視覺效果。Gaussian splatting可理解成透過多個橢圓球點雲表示環境,相較與傳統攝影測量法輸出的網格模型通常有更好的視覺效果,但若要應用到幾何尺寸的量測,可能需要進一步的探討

  • 圖台發布: 目前圖台的底層實際上是個靜態網頁(只是用Electron包成執行檔),若未來有在網路上公開發表的需求,可直接部屬在靜態Web server上


Footnotes

  1. gltf與obj檔案大小比較

  2. https://tile.openstreetmap.org/{z}/{x}/{y}.png

  3. https://jonny-huang.github.io/angular/training/18_electron/

相關文章

There are no related posts yet. 😢