코드조각 저장소

Cesium Terrain Builder 3D Tiles 만들기 본문

Programing/GIS &

Cesium Terrain Builder 3D Tiles 만들기

basic 2021. 4. 26. 15:28

이전 글에서 WMS tiles를 만들 었고, 이번에는 뼈대와 같은 Mesh Tiles를 만들어 보겠습니다. 정확히는 Quantized Mesh로 칭합니다만 이 데이터 포멧을 구현한 Cesium Terrain과 CesiumJS에서 사용하는 데이터 구조의 Tiles 입니다.

 처음 시도할 때에는 WMS와 같이 평범한 Web 서버를 통해 서비스 되는 줄로 이해했습니다. 하지만 동일한 방법으로는 예제의 페이지가 정상적으로 동작하지 않았습니다. 결론적으로는 Cesium Terrain Server를 이용해야만 정상적으로 동작하였고 차이점은 빈 Tile 데이터의 처리를 서버쪽에서 어떻게 하느냐 정도로 이해하고 넘어 갔습니다.

 그래서 생성된 결과물을 확인하려면 3D Tiles의 Cesium Terrain Server와 WMS Tile 서비스를 위한 웹서버, 이렇게 두개의 서버를 사용하였습니다. Cesium Terrain Server에서도 Static한 리소스에 대한 일반 web 서비스도 가능하지만 URL설정 및 기본 폴더등 설정이 잘 되지 않아서, Viwer html파일과 wms Tile은 NPM 패키지관리자를 통해 http-server로 확인 하였습니다.

 GitHub나 검색을 통해서 Cesium Terrain Builder를 찾으면 비슷하지만 것 같지만 다른 두개의 저장소가 검색이 됩니다.

두개의 차이점은 layer.json 파일을 생성할 수 있느냐이고 파생된 저장소인것 같습니다. layer.json은 CesiumJS에서 사용하는 메타데이터 파일 정도로 생각하시면 될것 같습니다. 파일이 없다면 웹 콘솔에서 오류가 발생합니다.

github.com/geo-data/cesium-terrain-builder

 

geo-data/cesium-terrain-builder

A C++ library and associated command line tools designed to create terrain tiles for use in the Cesium JavaScript library - geo-data/cesium-terrain-builder

github.com

github.com/tum-gis/cesium-terrain-builder-docker

 

tum-gis/cesium-terrain-builder-docker

Dockerfile for the geo-data/cesium-terrain-builder app with quantized mesh support. - tum-gis/cesium-terrain-builder-docker

github.com

저의 경우에는 소스 컴파일에 대한 부담이 없고, layer.json파일도 생성할 수 있는 tum-gis의 ctb를 사용하여 작업 하였습니다. Docker Desktop이 설치되어 있다면 간단한 명령으로 ctb-tiles를 생성할 수 있습니다.

#make 3D tiles 
docker run -it -v E:\my\study\opentopography:/data tumgis/ctb-quantized-mesh ctb-tile -f Mesh -C -o /data/tiles /data/hawaii_dem.tif

#make layer.json -l 옵션 추가
docker run -it -v E:\my\study\opentopography:/data tumgis/ctb-quantized-mesh ctb-tile -l -f Mesh -C -o /data/tiles /data/hawaii_dem.tif

CTB의 소스 파일은 DEM파일입니다. 좌표와 높이 Height 값의 Band를 가진 Raster 파일입니다. 여기 CTB로 생성된  3D Tile의 한계를 짐작 할 수 있는데 온전한 3D가 아닌 2.5D 수준의 모델 한계를 가집니다. 이것은 데이터에서 오는 제한인지, quatized mesh 포멧 자체의 한계인지에 대한 파악은 아직 하지 못 했습니다. 하지만 CityGML, BIM등에 사용되는 Mesh Tile은 온전한 3D를 지원해야 하지 않을까 생각이 들었습니다.

생성된 타일과 layer.json

이제는 결과물들을 확인할 차례입니다. Cesium Terrain Server와 http-server를 구동하고 브라우져에서 확인해 보겠습니다. 확인하기 위한 샘플페이지도 간단히 만들어 보았습니다.

Cesium Terrain Server는 소스코드, Docker 그리고 go Lang으로 구동할 수 있게 제공됩니다. 전과 같이 Docker로 구동하려다가 web-dir 옵션등이 잘 되질 않아 go lang을 설치합고 빌드하여 보기도 하였습니다. go 역시 nodeJS의 패키지 관리처럼 패키지관리자가 잘 만들어져 있는 듯하였습니다.  튜토리얼만으로도 서버구동이 가능했고 Window CMD 상이라 이것저것 테스트하기 좋았습니다.

#go lang를 설치합니다(window)
#go Lang 소스코드를 사용한 서버 빌드

go get github.com/geo-data/cesium-terrain-server/cmd/cesium-terrain-server

#run cesium server 
cesium-terrain-server -base-terrain-url="/tilesets" -cache-limit=1.00MB -dir="." -port=8000 -web-dir="."

#nodeJS HTTP-SERVER
npm i -g http-server

>http-server

#CesiumJS의 샘플페이지 사용을 위해 GitHub에서 clone 합니다.
git clone https://github.com/CesiumGS/cesium

서비스 폴더(CesiumJS, tile Data)

데이터 확인을 위한 샘플페이지 코드입니다.

<!DOCTYPE html>
<html lang="en">
  <head>
    <!-- Use correct character set. -->
    <meta charset="utf-8" />
    <!-- Tell IE to use the latest, best version. -->
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
    <meta
      name="viewport"
      content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"
    />
    <title>Hello World!</title>
    <script src="../Cesium/Cesium.js"></script>
    <style>
      @import url(../Cesium/Widgets/widgets.css);
      html,
      body,
      #cesiumContainer {
        width: 100%;
        height: 100%;
        margin: 0;
        padding: 0;
        overflow: hidden;
      }
	  #bt {
	  position : absolute;
	  left : 0;
	  top : 0;
	  }
    </style>
  </head>
  <body>
    <div id="cesiumContainer"></div>
    <script>      
	   var viewer = new Cesium.Viewer('cesiumContainer',
	   {
		terrainProvider : Cesium.createWorldTerrain(),
      //terrainExaggeration : 10.0 
	  }
	  );
   
	var layers = viewer.imageryLayers;

    //WMS Tiles  TileMapServiceImageryProvider
	var provider_20210324 = new Cesium.TileMapServiceImageryProvider({
					url : '/wms',
					fileExtension: 'png'
				});
	layers.addImageryProvider(provider_20210324);
		
		
    //3D tiles CesiumTerrainProvider
	var terrainProvider = new Cesium.CesiumTerrainProvider({
      url : 'http://localhost:8000/tilesets/tiles'
    });
    viewer.scene.terrainProvider = terrainProvider;
	
    viewer.camera.setView({
      destination : new Cesium.Cartesian3.fromDegrees(4.7128563,53.051284, 500),
	  orientation: {
        heading : Cesium.Math.toRadians(30),
        pitch : Cesium.Math.toRadians(-20),
        roll : 0.0
      }
    });
    </script>	
  </body>
</html>

WMS Tile :  Cesium.TileMapServiceImageryProvider

3d Terrain : Cesium.CesiumTerrainProvider

각 서버를 구동하고 페이지에 접속해 보겠습니다.

Cesium Terrain Server on 8000 port
http-server on 8080
WMS Tiles and CTB 3dTerrain, WMS Tiles and CTB 3dTerrain with Cesium WGS84 ellipsoid
Cesium World Terrain and WMS Tiles

결과물 까지 확인해 보았습니다. 이번 작업을 진행한 목적은 Cesium ION 없이 Terrain 모델을 표출하는데 있다고 한다면 어느정도 성과는 있었던것 같습니다.

 하지만 Multi Terrain이 가능한가에서는 답을 찾지 못했습니다. 기본적으로 CesiumJS에서는 한개의 Terrain Layer만 지원하는 것으로 파악되었고 추가적인 Terrain Medel을 중첩하고자 한다면 새로운 라이브리가 필요해 보였습니다.

github.com/heremaps/quantized-mesh-viewer

 

heremaps/quantized-mesh-viewer

Render custom quantized mesh tiles in Cesium.js and debug individual tiles using THREE.js renderer. - heremaps/quantized-mesh-viewer

github.com

결과적으로는 원하는 결과를 얻지는 못했습니다. 아무래도 new SurfaceProvider 도 CesiumJS 안에서 동작하는 구조라 CesiumJS에 종속된다라고 생각할 수 밖에 없는것 같습니다. 이외의 방법으로는 별도의 Render를 구성하여 구현하는 방법이 있을수 있을것 같습니다. 

참고적으로 CesiumJS와 ThreeJS를 통합한 예제가 있어 소개하고 이번 글은 마치도록 하겠습니다.

Potree라는 PointCLoud를 Tile 데이터셋으로 나누어 웹상에서 표현할 수 있도록 만든 라이브러리 입니다. Potree 내부에서는 Threejs 이용해 직접적으로 3D객체를 렌더링 합니다. 이점을 확장하여 생각하면 가능한 일이지 않을까 생각해봅니다.

감사합니다.

potree.org/potree/examples/cesium_retz.html

 

Potree Viewer

 

potree.org

 

Comments