开始使用 CesiumJS

Photo by NASA on Unsplash

开始使用 CesiumJS

配合 Webpack / Vite 创建项目使用 CesiumJS

·

4 min read

获取 Cesium ion Token

Cesium ion 主要用于托管 Cesium 相关数据,更多详细信息参考官方教程

首先,我们需要注册一个免费的 Cesium ion 账户,官方注册页面

登录之后,导航到 Access Tokens 页面。默认的 Token 旁边有个「复制按钮」,复制下来后面会用到。

cesium_ion_access_token.jpg

在页面中直接使用 CesiumJS

可以通过两种途径引用 CesiumJS:

1/ 从 CDN 引用 CesiumJS

<!-- 引用 CesiumJS JavaScript 和 CSS 文件 -->
<script src="https://cesium.com/downloads/cesiumjs/releases/1.93/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.93/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

2/ 从本地引用 CesiumJS

CesiumJS 是一个开源项目,提供全部源代码及发布文件,项目地址。下载发布文件到本地,并在页面中引用。

<!-- 引用 CesiumJS JavaScript 和 CSS 文件 -->
<script src="./cesiumjs/Build/Cesium/Cesium.js"></script>
<link href="./cesiumjs/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

示例:

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
  <meta charset="utf-8">
  <!-- 引用 CesiumJS JavaScript 和 CSS 文件 -->
  <script src="https://cesium.com/downloads/cesiumjs/releases/1.93/Build/Cesium/Cesium.js"></script>
  <link href="https://cesium.com/downloads/cesiumjs/releases/1.93/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
  <div id="cesiumContainer"></div>
  <script>
    // 将 `your_access_token` 替换为你前面申请的 Cesium ion access token.
    Cesium.Ion.defaultAccessToken = 'your_access_token';

    // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
    const viewer = new Cesium.Viewer('cesiumContainer', {
      terrainProvider: Cesium.createWorldTerrain()
    });
    // Add Cesium OSM Buildings, a global 3D buildings layer.
    const buildingTileset = viewer.scene.primitives.add(Cesium.createOsmBuildings());   
    // Fly the camera to San Francisco at the given longitude, latitude, and height.
    viewer.camera.flyTo({
      destination : Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),
      orientation : {
        heading : Cesium.Math.toRadians(0.0),
        pitch : Cesium.Math.toRadians(-15.0),
      }
    });
  </script>
 </div>
</body>
</html>

在 Webpack 项目中使用 CesiumJS

创建 Webpack 项目

mkdir cesium-webpack-example
cd cesium-webpack-example
yarn init

编写项目初始代码

cesium-webpack-example
├──src
│  ├──css
│  │  └──main.css
│  ├──index.html
│  └──index.js
├──webpack.config.js
└──package.json

安装项目依赖

yarn add -D webpack webpack-cli webpack-dev-server
yarn add -D css-loader style-loader url-loader
yarn add -D copy-webpack-plugin html-webpack-plugin

创建 src/index.html 文件

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cesium.js Demo</title>
</head>
<body>
    <p>Hello World!</p>
</body>
</html>

创建 src/index.js 文件

console.log('Hello, world!')

配置 Webpack,创建 webpack.config.js 文件

const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')

module.exports = {
  context: __dirname,
  entry: {
    app: './src/index.js'
  },
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist'),
    sourcePrefix: ''
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader', 'css-loader']
    }, {
      test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
      use: ['url-loader']
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    })
  ],
  mode: 'development'
}

修改 package.json 文件,添加 buildstart 命令

"scripts": {
    "build": "webpack --config webpack.config.js",
    "start": "webpack serve --config webpack.config.js"
}

执行 start 命令

yarn start

hello_world-16535608165771.png

在 Webpack 项目中加入 CesiumJS

安装 CesiumJS

yarn add -D cesium

修改 webpack.config.js,配置 Webpack 如何编译 CesiumJS。

// The path to the CesiumJS source code
const cesiumSource = 'node_modules/cesium/Source'
const cesiumWorkers = '../Build/Cesium/Workers'

const path = require('path')

const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const CopyWebpackPlugin = require('copy-webpack-plugin')

module.exports = {
  context: __dirname,
  entry: {
    app: './src/index.js'
  },
  output: {
    filename: 'app.js',
    path: path.resolve(__dirname, 'dist'),
    sourcePrefix: ''
  },
  amd: {
    // Enable webpack-friendly use of require in Cesium
    toUrlUndefined: true
  },
  resolve: {
    alias: {
      // CesiumJS module name
      cesium: path.resolve(__dirname, cesiumSource)
    },
    mainFiles: ['index', 'Cesium']
  },
  module: {
    rules: [{
      test: /\.css$/,
      use: ['style-loader', 'css-loader']
    }, {
      test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
      use: ['url-loader']
    }]
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html'
    }),
    // Copy Cesium Assets, Widgets, and Workers to a static directory
    new CopyWebpackPlugin({
      patterns: [
        { from: path.join(cesiumSource, cesiumWorkers), to: 'Workers' },
        { from: path.join(cesiumSource, 'Assets'), to: 'Assets' },
        { from: path.join(cesiumSource, 'Widgets'), to: 'Widgets' }
      ]
    }),
    new webpack.DefinePlugin({
      // Define relative base path in cesium for loading assets
      CESIUM_BASE_URL: JSON.stringify('')
    })
  ],
  mode: 'development'
}

修改 src/index.html 文件

<!DOCTYPE html>
<html lang="zh-Hans">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Cesium.js Demo</title>
</head>
<body>
    <div id="cesiumContainer"></div>
</body>
</html>

修改 src/index.js 文件

import { Ion, Viewer, createWorldTerrain, createOsmBuildings, Cartesian3, Math } from 'cesium'
import 'cesium/Widgets/widgets.css'
import './css/main.css'

// 将 `your_access_token` 替换为你前面申请的 Cesium ion access token.
Ion.defaultAccessToken = 'your_access_token';

// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
const viewer = new Viewer('cesiumContainer', {
  terrainProvider: createWorldTerrain()
})

// Add Cesium OSM Buildings, a global 3D buildings layer.
viewer.scene.primitives.add(createOsmBuildings())

// Fly the camera to San Francisco at the given longitude, latitude, and height.
viewer.camera.flyTo({
  destination: Cartesian3.fromDegrees(-122.4175, 37.655, 400),
  orientation: {
    heading: Math.toRadians(0.0),
    pitch: Math.toRadians(-15.0)
  }
})

创建 src/css/main.css 文件

html, body, #cesiumContainer {
    height: 100%;
    width: 100%;
    margin: 0;
    padding: 0;
    overflow: hidden;
}

执行 start 命令

hello_cesium.png

在 Vite 项目中使用 CesiumJS

创建 Vite 项目

> yarn create vite

√ Project name: ... cesium-vite-example
√ Select a framework: » vanilla
√ Select a variant: » vanilla

> cd cesium-vite-example
> yarn
> yarn dev

hello_vite.png

在 Vite 项目中加入 CesiumJS

安装依赖

yarn add -D cesium vite-plugin-cesium

创建 vite.config.js 文件

import { defineConfig } from 'vite'
import cesium from 'vite-plugin-cesium'

export default defineConfig({
  plugins: [cesium()]
})

修改 index.html 文件

<!DOCTYPE html>
<html lang="zh-Hans">
  <head>
    <meta charset="UTF-8" />
    <link rel="icon" type="image/svg+xml" href="favicon.svg" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Cesium.js Demo</title>
  </head>
  <body>
    <div id="cesiumContainer"></div>
    <script type="module" src="/main.js"></script>
  </body>
</html>

修改 style.css 文件

html, body, #cesiumContainer {
  height: 100%;
  width: 100%;
  margin: 0;
  padding: 0;
  overflow: hidden;
}

修改 main.js 文件

import * as Cesium from 'cesium'
import './style.css'

// 将 `your_access_token` 替换为你前面申请的 Cesium ion access token.
Cesium.Ion.defaultAccessToken = 'your_access_token'

// Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
const viewer = new Cesium.Viewer('cesiumContainer', {
  terrainProvider: Cesium.createWorldTerrain()
})

// Add Cesium OSM Buildings, a global 3D buildings layer.
viewer.scene.primitives.add(Cesium.createOsmBuildings())

// Fly the camera to San Francisco at the given longitude, latitude, and height.
viewer.camera.flyTo({
  destination: Cesium.Cartesian3.fromDegrees(-122.4175, 37.655, 400),
  orientation: {
    heading: Cesium.Math.toRadians(0.0),
    pitch: Cesium.Math.toRadians(-15.0)
  }
})

执行 yarn dev

hello_cesium-16536572871912.png

(END)