WebGIS 初嘗試 - CesiumJS

November 17, 2025

WebGIS 的介紹 (IT 邦幫忙)

CesiumJS 安裝與執行

  1. 安裝 Node.js。
  2. 下載獨立的 CesiumJS 預編譯檔案。
  3. 解壓縮 CesiumJS 預編譯檔案,移動到解壓縮後的目錄,並開啟命令列,執行 npm install 。
  4. 輸入 npm run start 啟動 Node.js,輸入網址即可看到 CesiumJS 的首頁。

範例

<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8" />
  <title>Cesium Demo</title>
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <link rel="stylesheet" href="Build/Cesium/Widgets/widgets.css" />
  <style>
    html, body, #cmap {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  </style>
  <script src="Build/Cesium/Cesium.js"></script>
</head>
<body>
  <div id="cmap"></div>
  <script>
    // 如果需要 Ion 資源,請填入你的 Access Token;若不需要,可移除這行。
    // Cesium.Ion.defaultAccessToken = '替換為你的 token';

    const viewer = new Cesium.Viewer('cmap', {
      animation: false,
      timeline: false,
      //terrainProvider: Cesium.createWorldTerrain(),  // 建立地形
      // 可視需要加其他初始化選項
      // imageryProvider: new Cesium.IonImageryProvider({ assetId: 2 })
    });

    // 簡單測試:在地球上加一個點
    viewer.entities.add({
      position: Cesium.Cartesian3.fromDegrees(121.5654, 25.0330, 100), // 台北
      point: { pixelSize: 10, color: Cesium.Color.YELLOW },
      description: '台北測試點'
    });
    viewer.zoomTo(viewer.entities);
        viewer.entities.add({
            name: "line",
            polyline: {
                positions: Cesium.Cartesian3.fromDegreesArray([121.523333, 25.15, 120.3508, 23]),
                width: 5,  // 線寬度
                material: Cesium.Color.RED,  // 紅色
                clampToGround: true,  // 虛線
            },
        });

        viewer.entities.add({
            name: "polygon",
            polygon: {
                hierarchy: Cesium.Cartesian3.fromDegreesArray([
                    120.6, 22.8,
                    120.7, 22.6,
                    120.5, 22.5,
                ]),
                material: Cesium.Color.RED,
            },
        });

  </script>
</body>
</html>
<!DOCTYPE html>
<html lang="zh-Hant">
<head>
  <meta charset="utf-8" />
  <title>Cesium Flight Demo</title>
  <meta name="viewport" content="width=device-width,initial-scale=1" />
  <link rel="stylesheet" href="Build/Cesium/Widgets/widgets.css" />
  <style>
    html, body, #cmap {
      width: 100%;
      height: 100%;
      margin: 0;
      padding: 0;
      overflow: hidden;
    }
  </style>
  <script src="Build/Cesium/Cesium.js"></script>
</head>
<body>
  <div id="cmap"></div>
  <script>
    // 若需 Ion 資源(全球影像/地形等),請填入你的 Access Token:
    // Cesium.Ion.defaultAccessToken = 'YOUR_TOKEN';

    const viewer = new Cesium.Viewer('cmap', {
      animation: true,
      timeline: true,
      shouldAnimate: true
    });

    // 原始資料 (不需要 JSON.parse)
    const flightData = [
      { longitude: 121.523333, latitude: 25.15, height: 1000 },
      { longitude: 120.3508, latitude: 23.0, height: 3000 }
    ];

    // 每段時間間隔 (秒)
    const timeSpan = 30;
    const totalSeconds = timeSpan * (flightData.length - 1);

    // 起訖時間
    const start = Cesium.JulianDate.fromIso8601("2025-11-05T15:10:00Z");
    const stop = Cesium.JulianDate.addSeconds(start, totalSeconds, new Cesium.JulianDate());

    // 設定時鐘
    viewer.clock.startTime = start.clone();
    viewer.clock.stopTime = stop.clone();
    viewer.clock.currentTime = start.clone();
    viewer.clock.multiplier = 1; // 播放速度
    viewer.clock.shouldAnimate = true;
    viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;
    viewer.timeline.zoomTo(start, stop);

    // 建立隨時間改變的位置
    const positionProp = new Cesium.SampledPositionProperty();
    flightData.forEach((pt, idx) => {
      const t = Cesium.JulianDate.addSeconds(start, idx * timeSpan, new Cesium.JulianDate());
      const pos = Cesium.Cartesian3.fromDegrees(pt.longitude, pt.latitude, pt.height);
      positionProp.addSample(t, pos);
    });

    // 使用速度自動計算方向
    const orientationProp = new Cesium.VelocityOrientationProperty(positionProp);

    // 建立飛行實體 (可用 model 或 point)
    const planeEntity = viewer.entities.add({
      availability: new Cesium.TimeIntervalCollection([
        new Cesium.TimeInterval({ start, stop })
      ]),
      position: positionProp,
      orientation: orientationProp,
      // 如果沒有模型檔,可先用 point 顯示
      // point: { pixelSize: 60, color: Cesium.Color.YELLOW },
      // 嘗試使用 CesiumAir 模型 (請確認路徑是否存在)
      model: {
        uri: 'Apps/SampleData/models/CesiumAir/Cesium_Air.glb',
        minimumPixelSize: 64,
        maximumScale: 200
      },
      path: {
        resolution: 1,
        material: new Cesium.PolylineGlowMaterialProperty({
          glowPower: 0.2,
          color: Cesium.Color.CYAN
        }),
        width: 6,
        leadTime: 0,
        trailTime: totalSeconds // 播放中顯示拖尾
      },
      description: '簡單兩點飛行示例'
    });

    // 讓鏡頭跟著
    viewer.trackedEntity = planeEntity;

    // 縮放到軌跡範圍
    viewer.zoomTo(planeEntity);

    // (除錯) 顯示是否正確建立
    console.log('Flight samples count:', positionProp._property._values.length || positionProp._values?.length);

    // 在播放最後一刻解除 trailTime 限制
    viewer.clock.onTick.addEventListener(function(clock) {
      if (Cesium.JulianDate.greaterThanOrEquals(clock.currentTime, stop)) {
        // 清掉 trailTime 讓整條線都顯示
        planeEntity.path.trailTime = undefined;
        // 也可停住動畫
        clock.shouldAnimate = false;
      }
    });
  </script>
</body>
</html>