npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

geoglobe-3d

v1.3.0

Published

基于 Cesium 的三维地图框架,支持 Vue/React 等前端框架

Readme

geoGlobe3D

基于 Cesium 的三维地图开发框架,提供简洁易用的 API,快速构建 WebGL 三维地球应用。

版本 v1.1.0 · 协议 Apache-2.0 · 依赖 Cesium(内置)

npm

NPM: https://www.npmjs.com/package/geoglobe-3d


目录


架构总览

┌──────────────────────────────────────────────────────────┐
│                       geoGlobe3D                         │
│                                                          │
│  ┌────────────────────────────────────────────────────┐  │
│  │                     GeoMap                         │  │
│  │  ┌──────────┐  ┌──────────┐  ┌──────────────────┐ │  │
│  │  │  Layers  │  │ Graphics │  │    Managers      │ │  │
│  │  │          │  │          │  │                  │ │  │
│  │  │ Imagery  │  │  Point   │  │  EventManager   │ │  │
│  │  │ Terrain  │  │  Line    │  │  PopupManager   │ │  │
│  │  │ Tileset  │  │  Polygon │  │  TooltipManager │ │  │
│  │  │ GeoJSON  │  │  Circle  │  │                  │ │  │
│  │  │ KML/CZML │  │  Model   │  └──────────────────┘ │  │
│  │  │ Graphic  │  │  Wall    │                        │  │
│  │  │          │  │  Rect    │  ┌──────────────────┐  │  │
│  │  └──────────┘  │  Box/... │  │    Controls      │  │  │
│  │                └──────────┘  │                  │  │  │
│  │  ┌──────────┐                │  NavBar          │  │  │
│  │  │  Tools   │                │  Navigation      │  │  │
│  │  │  Draw    │                │  Toolbar         │  │  │
│  │  │  Measure │                └──────────────────┘  │  │
│  │  └──────────┘                                      │  │
│  └────────────────────────────────────────────────────┘  │
│                                                          │
│                   ┌──────────────┐                       │
│                   │  Cesium.js   │                       │
│                   └──────────────┘                       │
└──────────────────────────────────────────────────────────┘

数据流向:GeoMap 初始化 Cesium Viewer → 图层/图形/控件通过 addTo(map) 挂载 → EventManager 统一派发交互事件 → PopupManager / TooltipManager 响应图形交互。

关键设计

  • 所有坐标统一使用 [经度, 纬度, 高度] 度制数组
  • 所有颜色支持 CSS 字符串'#ff0000''rgba(255,0,0,0.5)')或 Cesium.Color 实例
  • 异步图层(Imagery / Terrain / Tileset / GeoJSON / KML / CZML)加载完成后触发 'load' 事件
  • Draw / Measure 使用 Promise APIawait draw.point(),右键结束

安装与构建

# 安装依赖
npm install

# 生产构建
npm run build

# 开发模式(文件监听 + 自动重建)
npm run dev

# 本地预览 http://localhost:8080
npm start

快速开始

UMD — 浏览器直接引用

<!DOCTYPE html>
<html lang="zh-CN">
<head>
  <meta charset="utf-8">
  <link rel="stylesheet" href="dist/Widgets/widgets.css">
  <style>html, body, #map { margin: 0; width: 100%; height: 100%; }</style>
</head>
<body>
  <div id="map"></div>
  <script src="dist/geoglobe.min.js"></script>
  <script>
    // 创建地图
    const map = new geoGlobe.GeoMap('map', {
      skyBox: 'space',
      camera: { position: [116.4, 39.9, 8000000] }
    });

    // 添加影像图层
    const imagery = new geoGlobe.ImageryLayer({
      type: 'xyz',
      url: 'https://webst01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=6'
    });
    map.addLayer(imagery);

    // 在图层上绘制点
    const layer = new geoGlobe.GraphicLayer({ id: 'marks' });
    map.addLayer(layer);

    layer.addGraphic(new geoGlobe.PointGraphic({
      position: [116.4, 39.9, 0],
      style: { pixelSize: 12, color: '#ff0000' },
      popup: '<b>北京</b>',
      tooltip: '中国首都'
    }));
  </script>
</body>
</html>

ESM — 模块化导入

import { GeoMap, GraphicLayer, PointGraphic, ImageryLayer } from 'geoglobe-3d';

const map = new GeoMap('map', {
  skyBox: 'space',
  camera: { position: [116.4, 39.9, 8000000] }
});

const layer = new GraphicLayer({ id: 'marks' });
map.addLayer(layer);

layer.addGraphic(new PointGraphic({
  position: [116.4, 39.9, 0],
  style: { pixelSize: 12, color: '#ff0000' }
}));

Vue 3 + Vite 集成

完整示例项目见 examples/vue3-demo/

1. 安装

npm install geoglobe-3d

Cesium 已内置于 geoglobe-3d,无需单独安装 cesium。

2. 拷贝静态资源

node_modules/geoglobe-3d/dist/ 整个目录拷贝到 public/geoglobe/(包含 JS 产物、Workers、Assets、Widgets、ThirdParty):

# Linux / macOS
cp -r node_modules/geoglobe-3d/dist public/geoglobe

# Windows (PowerShell)
Copy-Item -Recurse -Force "node_modules/geoglobe-3d/dist" "public/geoglobe"

推荐在 package.json 中添加脚本自动执行:

{
  "scripts": {
    "copy-assets": "node scripts/copy-geoglobe-assets.js"
  }
}
// scripts/copy-geoglobe-assets.js
import { cpSync, existsSync } from 'fs';
import { resolve, dirname } from 'path';
import { fileURLToPath } from 'url';

const __dirname = dirname(fileURLToPath(import.meta.url));
const root = resolve(__dirname, '..');
const src = resolve(root, 'node_modules/geoglobe-3d/dist');
const dest = resolve(root, 'public/geoglobe');

if (!existsSync(src)) {
  console.error('找不到 node_modules/geoglobe-3d/dist,请先运行 npm install');
  process.exit(1);
}
cpSync(src, dest, { recursive: true });
console.log('已复制 geoglobe-3d/dist -> public/geoglobe');

3. 在 index.html 引入 UMD 版本

<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>geoGlobe3D Vue3 Demo</title>
    <!-- 引入 Cesium 组件样式 -->
    <link rel="stylesheet" href="/geoglobe/Widgets/widgets.css" />
  </head>
  <body>
    <div id="app"></div>
    <!-- 引入 UMD 版本,注册全局 window.geoGlobe -->
    <script src="/geoglobe/geoglobe.js"></script>
    <script type="module" src="/src/main.js"></script>
  </body>
</html>

UMD 版本加载后自动根据 script 标签路径推断 CESIUM_BASE_URL,无需手动设置。

4. Vite 配置

// vite.config.js
import { defineConfig } from 'vite';
import vue from '@vitejs/plugin-vue';

export default defineConfig({
  plugins: [vue()]
});

由于 geoglobe 通过 <script> 标签引入(非 ESM import),Vite 配置无需额外处理。

5. 地图组件

<!-- src/components/MapView.vue -->
<template>
  <div class="map-wrapper">
    <!-- 自定义工具栏 -->
    <div class="toolbar">
      <div class="bar-group">
        <span class="label">绘制</span>
        <button @click="doDraw('point')">点</button>
        <button @click="doDraw('polyline')">线</button>
        <button @click="doDraw('polygon')">面</button>
        <button @click="doDraw('rectangle')">矩形</button>
        <button @click="doDraw('circle')">圆</button>
        <button @click="clearDraw()">清除</button>
      </div>
      <div class="bar-group">
        <span class="label">量算</span>
        <button @click="doMeasure('distance')">距离</button>
        <button @click="doMeasure('area')">面积</button>
        <button @click="doMeasure('height')">高度</button>
        <button @click="clearMeasure()">清除</button>
      </div>
    </div>
    <!-- 地图容器 -->
    <div ref="mapContainer" class="map-container"></div>
  </div>
</template>

<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue';

// geoGlobe 通过 index.html 的 <script> 标签引入,挂载在 window.geoGlobe 上
const { GeoMap, Draw, Measure } = window.geoGlobe;

const mapContainer = ref(null);
let map = null;
let draw = null;
let measure = null;

onMounted(() => {
  map = new GeoMap(mapContainer.value, {
    skyBox: 'space',
    control: {
      timeline: false,
      animation: false,
      baseLayerPicker: false,
      homeButton: false,
      sceneModePicker: false,
      navigationHelpButton: false,
      fullscreenButton: false,
      toolbar: true,    // 底部状态栏
      navBar: true,     // 左侧导航栏
      navigation: false
    },
    camera: {
      position: [116.39, 39.91, 8000000],
      heading: 0,
      pitch: -90,
      roll: 0
    }
  });

  draw = new Draw(map);
  measure = new Measure(map);
});

function doDraw(type) {
  if (draw && draw[type]) draw[type]();
}
function clearDraw() {
  if (draw && draw.clear) draw.clear();
}
function doMeasure(type) {
  if (measure && measure[type]) measure[type]();
}
function clearMeasure() {
  if (measure && measure.clear) measure.clear();
}

onBeforeUnmount(() => {
  if (map && map.destroy) {
    map.destroy();
  }
});
</script>

<style scoped>
.map-wrapper {
  width: 100%;
  height: 100%;
  position: relative;
}
.map-container {
  width: 100%;
  height: 100%;
}
</style>

6. 运行

npm install
npm run copy-assets   # 复制 geoglobe-3d/dist -> public/geoglobe
npm run dev            # 启动 Vite 开发服务器

注意事项

  • 确保 CSS 高度链完整:html, body, #app 都需设置 width: 100%; height: 100%,否则地图容器高度为 0。
  • 使用 let 而非 ref() 保存地图实例,避免 Vue 的 reactive proxy 深度代理 Cesium 内部对象导致性能问题。
  • 组件卸载时务必调用 destroy() 释放 WebGL 资源。
  • public/geoglobe/ 目录由脚本生成,建议加入 .gitignore

产物说明

| 文件 | 格式 | Cesium | 适用场景 | |------|------|--------|----------| | dist/geoglobe.js | UMD | 内含 | 浏览器 <script> 标签 | | dist/geoglobe.min.js | UMD (压缩) | 内含 | 生产环境 | | dist/geoglobe.esm.js | ES Module | 内含 | Webpack / Vite / Rollup | | dist/geoglobe.cjs.js | CommonJS | 内含 | Node.js / SSR | | dist/index.d.ts | TypeScript 声明 | — | Vue/React + TS 项目 |

附属资源(需整体部署):

| 目录 | 说明 | |------|------| | dist/Workers/ | Cesium Web Worker 文件 | | dist/Assets/ | 纹理、地形高度等静态资源 | | dist/Widgets/ | UI 组件样式 |

引用 UMD 版本时,框架自动推断 CESIUM_BASE_URL,无需手动设置。


GeoMap — 核心类

// UMD
const map = new geoGlobe.GeoMap(container, options);

// ESM
import { GeoMap } from 'geoglobe-3d';
const map = new GeoMap(container, options);

container:DOM 元素或元素 id 字符串。GeoMap 同时以 Map 别名导出。

构造参数

const map = new GeoMap('map', {
  // ─── 底图 ───
  baseImagery: 'naturalEarth',    // 'naturalEarth'(默认) | 'osm' | 'none' | imageryProvider 实例

  // ─── 天空盒 ───
  skyBox: 'space',                // 'space'(默认) | 'default' | false | { sources, animate, ... }

  // ─── 场景 ───
  scene: {
    sceneMode: SceneMode.SCENE3D, // SCENE3D | SCENE2D | COLUMBUS_VIEW
    globe: {
      baseColor: Color.BLACK,
      depthTestAgainstTerrain: false,
      enableLighting: false,
      showGroundAtmosphere: true
    }
  },

  // ─── 控件 ───
  control: {
    // Cesium 原生控件
    baseLayerPicker: false,    geocoder: false,
    homeButton: true,          sceneModePicker: true,
    navigationHelpButton: true,animation: false,
    timeline: false,           fullscreenButton: true,
    infoBox: false,            selectionIndicator: false,
    // 扩展控件
    navigation: false, // true | false | { compass, zoomControls, distanceLegend }
    navBar: false,     // true | false | { position, showCompass, showHome, showSceneMode, showZoom }
    toolbar: false     // true | false
  },

  // ─── 弹窗 & 提示 ───
  popup: true,   // true | false | { auto, closeButton, followCamera, offset, className }
  tooltip: true, // true | false | { offset, className }

  // ─── 地形 ───
  terrain: {
    enabled: false,
    url: undefined  // 自定义 CTB URL;不填且 enabled:true 时使用 Cesium World Terrain
  },

  // ─── Ion Token ───
  accessToken: 'your-cesium-ion-token',

  // ─── 初始相机 ───
  camera: {
    position: [116.4, 39.9, 10000000], // [经度, 纬度, 高度(米)]
    heading: 0,   // 朝向角(度)
    pitch: -90,   // 俯仰角(度)
    roll: 0
  }
});

图层管理

增删查

| 方法 | 签名 | 返回值 | 说明 | |------|------|--------|------| | addLayer | (layer: Layer) | GeoMap | 添加图层 | | removeLayer | (layer: Layer) | GeoMap | 移除图层 | | removeLayerById | (id: string) | GeoMap | 按 id 移除 | | removeAllLayers | () | GeoMap | 移除全部 | | getLayer | (id: string) | Layer \| undefined | 按 id 查找 | | getLayerByName | (name: string) | Layer \| undefined | 按 name 查找 | | getLayers | () | Layer[] | 获取全部(副本) | | hasLayer | (layer: Layer) | boolean | 是否包含 | | getLayerCount | () | number | 图层数量 |

排序

| 方法 | 说明 | |------|------| | raiseLayer(layer) | 上移一层 | | lowerLayer(layer) | 下移一层 | | raiseLayerToTop(layer) | 置顶 | | lowerLayerToBottom(layer) | 置底 | | moveLayerTo(layer, index) | 移到指定位置(0 = 最底层) |

显隐

| 方法 | 说明 | |------|------| | showLayer(id) | 显示图层 | | hideLayer(id) | 隐藏图层 | | toggleLayer(id) | 切换显隐 |

相机与视图

| 方法 | 签名 | 说明 | |------|------|------| | flyTo | (position: [lng,lat,h], options?) | 飞行动画。options: { duration, heading, pitch, roll } | | setView | ([lng,lat,h])({ position, heading, pitch, roll }) | 瞬间跳转 | | setCamera | ({ position?, heading?, pitch?, roll? }) | 设置相机 | | resetView | () | 复位到初始位置 | | zoomIn | (amount=2) | 放大 | | zoomOut | (amount=2) | 缩小 | | zoomTo | (target, options?) | 飞行到图层/图形范围 | | setSceneMode | (mode, duration=2) | 切换场景: '3d'/'2d'/'columbus' |

查询

| 方法 | 返回值 | 说明 | |------|--------|------| | getCenter() | [lng, lat, h] \| undefined | 视图中心 | | getCamera() | { position, heading, pitch, roll, height } | 相机姿态 | | getCurrentExtent() | { west, south, east, north } \| undefined | 视图范围(度) |

// 飞行到北京上空
map.flyTo([116.4, 39.9, 5000], { duration: 2, pitch: -45 });

// 瞬间跳转(两种写法等价)
map.setView([116.4, 39.9, 5000]);
map.setView({ position: [116.4, 39.9, 5000], heading: 0, pitch: -45, roll: 0 });

// 切换到 2D 模式
map.setSceneMode('2d', 2);

底图与地形

// 运行时切换底图
map.setBaseImagery('osm');
map.setBaseImagery('naturalEarth');
map.setBaseImagery(customProviderInstance);
map.setBaseImagery('none');

// 运行时切换地形(异步)
await map.setTerrain({ url: 'https://your-terrain-ctb' });  // 自定义 CTB
await map.setTerrain({ ionAssetId: 1 });                     // Cesium World Terrain
await map.setTerrain({ enabled: false });                     // 关闭地形

场景效果

| 方法 | 参数 | 说明 | |------|------|------| | setSkyBox(opt) | 'space' \| 'default' \| false \| { sources } | 天空盒 | | setFog(opts) | { enabled, density, minimumBrightness } | 雾效 | | setAtmosphere(opts) | { show, lightIntensity, rayleighScaleHeight } | 大气 | | setSunLight(enabled) | boolean | 太阳光照 |

时钟与时间

| 方法 | 签名 | 说明 | |------|------|------| | setClock | (opts) | 配置时钟 | | getTime | ()string | 获取当前时间 (ISO) | | setTime | (isoString) | 跳转到指定时间 | | setTimeSpeed | (multiplier) | 播放速率(负值倒放) | | startClock | () | 开始 | | stopClock | () | 暂停 |

setClock 参数:

| 属性 | 类型 | 说明 | |------|------|------| | start | string | 开始时间 ISO,如 '2024-01-01T00:00:00Z' | | stop | string | 结束时间 ISO | | current | string | 当前时间 ISO | | multiplier | number | 时间倍率,默认 1 | | clockRange | string | 'unbounded' / 'clamped' / 'loop' | | animate | boolean | 是否自动播放 |

map.setClock({
  start: '2024-01-01T00:00:00Z',
  stop: '2024-12-31T23:59:59Z',
  current: '2024-06-01T12:00:00Z',
  multiplier: 100,
  clockRange: 'loop',
  animate: true
});

截图与销毁

const base64 = map.screenshot();                                  // PNG base64
const jpeg   = map.screenshot({ type: 'image/jpeg', quality: 0.9 });
map.downloadScreenshot('my-map.png');                              // 浏览器下载

map.destroy(); // 销毁地图,释放所有资源

图层 API

Layer — 基类

所有图层继承自 Layer,共享以下接口:

构造参数

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | id | string | 自动 UUID | 唯一标识 | | name | string | '' | 名称 | | show | boolean | true | 可见性 |

公共方法

| 方法 | 说明 | |------|------| | addTo(map) | 添加到地图 | | remove() | 从地图移除 | | destroy() | 移除并清理事件 | | setShow(show) / showLayer() / hideLayer() / toggleShow() | 显隐控制 | | getIndex() | 在 map.layers 中的索引 | | on(event, cb) / once(event, cb) / off(event, cb?) | 事件监听 |

图层事件:'load'(加载完成)、'error'(加载失败)、'click'


ImageryLayer — 影像图层

const layer = new ImageryLayer({
  id: 'gaode', name: '高德影像',
  type: 'xyz',
  url: 'https://webst01.is.autonavi.com/appmaptile?x={x}&y={y}&z={z}&style=6'
});
map.addLayer(layer);

构造参数(除 Layer 公共参数外)

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | string | 'xyz' | 类型,见下表 | | url | string | — | 服务 URL | | alpha | number | 1.0 | 透明度 (0~1) | | maximumLevel | number | — | 最大层级 | | minimumLevel | number | 0 | 最小层级 | | layer | string | — | WMTS/WMS 图层名 | | style | string | — | WMTS 样式名 | | format | string | 'image/png' | 瓦片格式 | | tileMatrixSetID | string | — | WMTS 矩阵集 | | layers | string | — | WMS 图层列表 | | ionAssetId | number | — | Ion 资产 ID | | color | string | — | 单色图层颜色 | | rectangle | number[] | — | [west,south,east,north] 度 |

type 取值对照

| type | 底层 Provider | 说明 | |------|--------------|------| | 'xyz' | UrlTemplateImageryProvider | XYZ 瓦片 | | 'tms' | UrlTemplateImageryProvider | TMS 服务(与 xyz 共用) | | 'osm' | OpenStreetMapImageryProvider | OSM 瓦片 | | 'wmts' | WebMapTileServiceImageryProvider | WMTS 服务 | | 'wms' | WebMapServiceImageryProvider | WMS 服务 | | 'arcgis' | ArcGisMapServerImageryProvider | ArcGIS 服务 | | 'ion' | IonImageryProvider | Cesium Ion 影像 | | 'singleTile' | SingleTileImageryProvider | 单张图片 | | 'singleColor' / 'color' | Canvas 生成 | 纯色覆盖 |

图层调整方法

| 方法 | 说明 | |------|------| | setAlpha(v) / setOpacity(v) | 透明度 (0~1) | | setBrightness(v) | 亮度 (1.0=默认) | | setContrast(v) | 对比度 | | setSaturation(v) | 饱和度 (0=灰度) | | setHue(v) | 色调 | | setGamma(v) | 伽马 | | raise() / lower() / raiseToTop() / lowerToBottom() | 排序 |

// WMTS
new ImageryLayer({
  type: 'wmts',
  url: 'https://example.com/wmts',
  layer: 'layerName',
  style: 'default',
  tileMatrixSetID: 'EPSG:4326'
}).addTo(map);

// WMS
new ImageryLayer({
  type: 'wms',
  url: 'https://example.com/wms',
  layers: 'roads'
}).addTo(map);

TerrainLayer — 地形图层

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | type | string | 'ellipsoid' | 'ion' / 'cesium' / 'ellipsoid' | | url | string | — | CTB 地形 URL(cesium 类型必填) | | ionAssetId | number | 1 | Ion 资产 ID(ion 类型) | | requestVertexNormals | boolean | false | 请求法线(光照用) | | requestWaterMask | boolean | false | 请求水面遮罩 |

new TerrainLayer({
  type: 'cesium',
  url: 'https://your-terrain-ctb-service'
}).addTo(map);

TilesetLayer — 3D Tiles

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | url | string | — | tileset.json URL | | ionAssetId | number | — | Ion 资产 ID | | maximumScreenSpaceError | number | 16 | 最大屏幕空间误差 | | maximumMemoryUsage | number | 512 | 最大内存 (MB) | | position | number[] | — | 位置偏移 [lng, lat, height] | | rotation | object | — | 旋转 { heading, pitch, roll }(度) | | shadows | boolean | false | 阴影 | | backFaceCulling | boolean | true | 背面剔除 | | style | object | — | 3D Tiles Style,转为 Cesium3DTileStyle | | onClick | Function | — | 点击回调 (picked, click) | | onReady | Function | — | 加载完成回调 |

方法flyTo(options?)raise()lower()raiseToTop()lowerToBottom()

const tileset = new TilesetLayer({
  url: 'https://your-server/tileset.json',
  maximumScreenSpaceError: 16,
  position: [116.4, 39.9, 0],
  rotation: { heading: 0, pitch: 0, roll: 0 },
  style: { color: "color('white', 0.8)" }
});
map.addLayer(tileset);
tileset.flyTo();

GeoJsonLayer

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | url | string | — | GeoJSON 文件 URL | | data | object | — | 内联 GeoJSON 对象 | | stroke | string | '#ffff00' | 线颜色 | | strokeWidth | number | 2 | 线宽 | | fill | string | 'rgba(255,255,0,0.4)' | 填充色 | | markerSize | number | 48 | 点标记大小 | | markerColor | string | '#4169E1' | 点标记颜色 | | clampToGround | boolean | false | 贴地 | | onClick | Function | — | 点击回调 (entity, click) | | onLoad | Function | — | 加载回调 (dataSource) |

注意:样式属性在顶层,不嵌套在 style 对象中。

方法getEntities()flyTo(options?)raise()lower()raiseToTop()lowerToBottom()

// URL 加载
new GeoJsonLayer({
  url: './data/china.geojson',
  stroke: '#ff6600',
  strokeWidth: 2,
  fill: '#ff6600',
  clampToGround: true
}).addTo(map);

// 内联数据
new GeoJsonLayer({
  data: { type: 'FeatureCollection', features: [...] }
}).addTo(map);

GraphicLayer — 图形容器

承载 Graphic 图形对象的容器图层。

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | graphics | Array | [] | 初始图形 | | clustering | object | — | 聚合配置 { enabled, pixelRange, minimumClusterSize } |

| 方法 | 签名 | 说明 | |------|------|------| | addGraphic | (graphic) | 添加单个图形 | | addGraphics | (graphics[]) | 批量添加 | | removeGraphic | (graphic) | 移除图形 | | getGraphicById | (id)BaseGraphic? | 按 id 查找 | | getGraphics | ()Array | 获取全部(副本) | | clear / clearGraphics | () | 清空全部 | | flyTo | (options?) | 飞行到范围 |

const layer = new GraphicLayer({ id: 'marks', name: '标注' });
map.addLayer(layer);

layer.addGraphic(point);
layer.addGraphics([line, polygon]);
layer.removeGraphic(point);
layer.clear();

KmlLayer / CzmlLayer

// KML
new KmlLayer({ url: './data/file.kml' }).addTo(map);

// CZML
const czml = new CzmlLayer({ url: './data/scene.czml' });
map.addLayer(czml);

// CZML 增量更新
await czml.process(newCzmlPackets);

共享方法getEntities()flyTo(options?)raise()lower()raiseToTop()lowerToBottom()

CzmlLayer 独有方法:process(czmlPacket) — 异步追加/更新 CZML 数据包。


图形 API

BaseGraphic — 公共接口

所有图形继承 BaseGraphic,共享以下构造参数和方法。

构造参数

| 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | id | string | 自动 UUID | 唯一标识 | | name | string | '' | 名称 | | show | boolean | true | 可见性 | | position | number[] | — | 位置 [lng, lat, height] | | style | object | {} | 样式(各图形不同) | | attr | object | {} | 自定义属性 | | popup | string \| Function | — | 弹窗内容(HTML / 返回 HTML 的函数) | | tooltip | string \| Function | — | 悬浮提示文本 | | onClick | Function | — | 点击回调 (graphic, event) | | onMouseover | Function | — | 鼠标进入 (graphic, event) | | onMouseout | Function | — | 鼠标离开 (graphic) |

公共方法

| 方法 | 签名 | 说明 | |------|------|------| | setPosition | (position: number[]) | 更新位置 | | setShow | (show: boolean) | 显隐 | | setStyle | (style: object) | 合并更新样式 | | flyTo | (options?) | 相机飞行到此图形 | | entity | getter | 底层 Cesium.Entity |


PointGraphic

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | pixelSize | number | 10 | 像素大小 | | color | string | '#ff0000' | 颜色 | | outlineColor | string | — | 描边色 | | outlineWidth | number | 0 | 描边宽 | | heightReference | string | — | 'clamp' / 'relative' / 'none' | | scaleByDistance | number[] | — | [near, nearScale, far, farScale] | | distanceDisplayCondition | number[] | — | [near, far] |

new PointGraphic({
  position: [116.4, 39.9, 0],
  style: { pixelSize: 12, color: '#ff0000', outlineColor: '#fff', outlineWidth: 2 },
  popup: '<b>北京</b>'
});

BillboardGraphic

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | image | string | — | 图片 URL | | scale | number | 1.0 | 缩放 | | width / height | number | — | 像素尺寸 | | rotation | number | 0 | 旋转角(度) | | color | string | — | 着色 | | pixelOffset | number[] | — | [x, y] 像素偏移 | | horizontalOrigin | string | 'center' | 'center'/'left'/'right' | | verticalOrigin | string | 'center' | 'center'/'top'/'bottom' | | sizeInMeters | boolean | — | 以米为单位 | | heightReference | string | — | 高度参考 | | scaleByDistance | number[] | — | NearFarScalar | | distanceDisplayCondition | number[] | — | [near, far] |

new BillboardGraphic({
  position: [116.4, 39.9, 0],
  style: {
    image: './icons/marker.png',
    width: 32, height: 32,
    verticalOrigin: 'bottom'
  }
});

LabelGraphic

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | text | string | '' | 文本 | | font | string | '14px sans-serif' | CSS 字体 | | scale | number | 1.0 | 缩放 | | fillColor | string | '#ffffff' | 填充色 | | outlineColor | string | '#000000' | 描边色 | | outlineWidth | number | 1 | 描边宽 | | showBackground | boolean | false | 显示背景 | | backgroundColor | string | — | 背景色 | | backgroundPadding | number[] | — | [x, y] 内边距 | | labelStyle | string | — | 'fill' / 'outline' / 'fillAndOutline' | | pixelOffset | number[] | — | [x, y] | | horizontalOrigin | string | 'center' | 水平对齐 | | verticalOrigin | string | 'center' | 垂直对齐 | | heightReference | string | — | 高度参考 | | scaleByDistance | number[] | — | NearFarScalar | | distanceDisplayCondition | number[] | — | [near, far] |

new LabelGraphic({
  position: [116.4, 39.9, 100],
  style: {
    text: '北京',
    font: '16px Microsoft YaHei',
    fillColor: '#ffffff',
    outlineColor: '#000000',
    outlineWidth: 2
  }
});

PolylineGraphic

额外构造参数positions: number[][](顶层,非 style 内)

可在顶层使用 widthcolorclampToGround 简写,自动合并到 style。

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | width | number | 3 | 线宽 | | color | string | '#ff0000' | 颜色 | | material | object | — | 线材质(见下) | | clampToGround | boolean | false | 贴地 | | depthFailColor | string | — | 深度测试失败时颜色 | | arcType | string | 'geodesic' | 'geodesic' / 'rhumb' / 'none' | | zIndex | number | — | 层级 | | classificationType | string | — | 'terrain' / '3dtiles' / 'both' |

线材质类型

| material.type | 参数 | 效果 | |---------------|------|------| | 'dash' | color, gapColor, dashLength | 虚线 | | 'glow' | color, glowPower | 发光 | | 'arrow' | color | 箭头 | | 'outline' | color, outlineColor, outlineWidth | 描边 |

额外方法setPositions(positions: number[][])

// 纯色线
new PolylineGraphic({
  positions: [[116.0, 39.9, 0], [117.0, 39.9, 0]],
  style: { width: 5, color: '#ff0000' }
});

// 发光箭头线
new PolylineGraphic({
  positions: [[116.0, 39.9, 0], [117.0, 40.5, 0]],
  style: { width: 8, material: { type: 'arrow', color: 'cyan' } }
});

PolygonGraphic

额外构造参数positions: number[][](外环),holes: number[][][](内孔,可选)

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | color | string | 'rgba(255,255,0,0.4)' | 填充色 | | material | object | — | 面材质 | | fill | boolean | true | 填充 | | outline | boolean | true | 描边 | | outlineColor | string | '#ffff00' | 描边色 | | outlineWidth | number | 2 | 描边宽 | | height | number | — | 拉伸底部高度 | | extrudedHeight | number | — | 拉伸顶部高度 | | perPositionHeight | boolean | false | 逐顶点高度 | | clampToGround | boolean | false | 贴地 | | heightReference | string | — | 高度参考 | | classificationType | string | — | 分类类型 | | stRotation | number | — | 纹理旋转(度) |

额外方法setPositions(positions)setHoles(holes)

// 半透明多边形
new PolygonGraphic({
  positions: [[116,39.5,0],[117,39.5,0],[117,40.5,0],[116,40.5,0]],
  style: { color: 'rgba(68,136,255,0.5)', outline: true, outlineColor: '#fff' }
});

// 拉伸体
new PolygonGraphic({
  positions: [[116,39.5,0],[117,39.5,0],[117,40.5,0],[116,40.5,0]],
  style: { color: '#4488ff', height: 0, extrudedHeight: 500 }
});

CircleGraphic

可在顶层使用 radiuscolor 简写。

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | radius | number | 1000 | 半径(米) | | color | string | 'rgba(0,255,0,0.3)' | 填充色 | | material | object | — | 面材质 | | fill / outline | boolean | true | 填充/描边 | | outlineColor | string | '#00ff00' | 描边色 | | outlineWidth | number | 2 | 描边宽 | | height / extrudedHeight | number | — | 拉伸高度 | | clampToGround | boolean | false | 贴地 | | heightReference | string | — | 高度参考 | | rotation | number | — | 旋转(度) |

额外方法setRadius(radius: number)

new CircleGraphic({
  position: [116.4, 39.9, 0],
  radius: 5000,
  style: { color: 'rgba(255,0,0,0.4)', outline: true, outlineColor: '#ff0000' }
});

RectangleGraphic

额外构造参数coordinates: [west, south, east, north](度)

style:与 PolygonGraphic 类似 — colorfilloutlineoutlineColoroutlineWidthheightextrudedHeightrotationclampToGroundheightReferenceclassificationType

额外方法setCoordinates(coordinates: number[])

new RectangleGraphic({
  coordinates: [116.0, 39.5, 117.0, 40.5],
  style: { color: 'rgba(255,255,0,0.4)', extrudedHeight: 200 }
});

WallGraphic

额外构造参数positions: number[][]

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | color | string | 'rgba(255,0,0,0.6)' | 填充色 | | material | object | — | 面材质 | | outline | boolean | false | 描边 | | outlineColor | string | '#ffffff' | 描边色 | | outlineWidth | number | 1 | 描边宽 | | maximumHeights | number[] | — | 各顶点最大高度 | | minimumHeights | number[] | — | 各顶点最小高度 |

额外方法setPositions(positions: number[][])

new WallGraphic({
  positions: [[116.0,39.9,0],[117.0,39.9,0],[117.5,40.5,0]],
  style: { maximumHeights: [500,500,500], minimumHeights: [0,0,0], color: 'rgba(0,0,255,0.6)' }
});

ModelGraphic

额外构造参数orientation: { heading, pitch, roll }(度)

style

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | url / uri | string | — | glTF/glb URL | | scale | number | 1.0 | 缩放 | | minimumPixelSize | number | 64 | 最小像素 | | maximumScale | number | — | 最大缩放 | | shadows | boolean | false | 阴影 | | runAnimations | boolean | true | 播放内嵌动画 | | silhouetteColor | string | — | 轮廓色 | | silhouetteSize | number | 2 | 轮廓大小 | | color | string | — | 着色 | | colorBlendMode | string | 'highlight' | 'highlight' / 'replace' / 'mix' | | heightReference | string | — | 高度参考 |

额外方法setOrientation({ heading, pitch, roll })

new ModelGraphic({
  position: [116.4, 39.9, 0],
  orientation: { heading: 45, pitch: 0, roll: 0 },
  style: { url: './models/car.glb', scale: 1.0, minimumPixelSize: 64 }
});

BoxGraphic / CylinderGraphic / EllipsoidGraphic / EllipseGraphic

| 图形 | 定位参数 | 核心 style 属性 | |------|----------|----------------| | BoxGraphic | position = 中心 | dimensions: [x, y, z](米,默认 [20,20,40]) | | CylinderGraphic | position = 底部中心 | length(高,默认100), topRadius(默认20), bottomRadius(默认20), slices | | EllipsoidGraphic | position = 球心 | radii: [x, y, z](米,默认 [50,50,50]), stackPartitions(32), slicePartitions(32) | | EllipseGraphic | position = 中心 | semiMajorAxis(5000m), semiMinorAxis(3000m), rotation(度) |

以上四种图形均支持 colorfilloutlineoutlineColoroutlineWidthshadowsheightReferencedistanceDisplayCondition 等通用样式。


工具类

Draw — 绘制工具

所有方法返回 Promise。左键操作,右键结束。调用 stop() 中断进行中操作(Promise resolve { cancelled: true })。

const draw = new Draw(map);

| 方法 | 返回值 | 操作方式 | |------|--------|----------| | draw.point(style?) | { position: [lng,lat,h], entity } | 左键单击 | | draw.polyline(style?) | { positions: [[lng,lat,h],...], entity } | 左键添加点,右键结束 | | draw.polygon(style?) | { positions: [...], entity } | 左键添加点(>=3),右键结束 | | draw.rectangle(style?) | { coordinates: [w,s,e,n], entity } | 左键两次(对角) | | draw.circle(style?) | { center: [lng,lat,h], radius: 米, entity } | 左键两次(圆心+半径) | | draw.stop() | Draw | 中断当前操作 | | draw.clear() | Draw | 清除所有绘制结果 | | draw.destroy() | void | 释放资源 |

完整示例

const draw = new Draw(map);

// 绘制一个点
const pointResult = await draw.point({ pixelSize: 12, color: 'red' });
console.log('点位:', pointResult.position);

// 绘制多边形
const polyResult = await draw.polygon();
console.log('顶点:', polyResult.positions);

// 右键取消、或用按钮中断
document.getElementById('cancel-btn').onclick = () => draw.stop();

// 清除所有绘制
draw.clear();

Measure — 量算工具

与 Draw 类似的 Promise API。

const measure = new Measure(map);

| 方法 | 返回值 | 说明 | |------|--------|------| | measure.distance() | { distance: 米, positions: [...] } | 距离量算(折线) | | measure.area() | { area: 平方米, positions: [...] } | 面积量算(多边形,>=3点) | | measure.height() | { height: 米, position: [lng,lat,h] } | 高度量算(单点) | | measure.angle() | { angle: 度, positions: [p1,p2,p3] } | 角度量算(三点,p2为顶点) | | measure.stop() | Measure | 中断当前操作 | | measure.clear() | Measure | 清除所有量算结果及标注 | | measure.destroy() | void | 释放资源 |

const measure = new Measure(map);

const dist = await measure.distance();
console.log(`总距离: ${dist.distance.toFixed(2)} 米`);

const area = await measure.area();
console.log(`面积: ${area.area.toFixed(2)} 平方米`);

measure.clear();

控件

Navigation

罗盘 + 缩放按钮 + 比例尺(基于 cesium-navigation-es6)。

const map = new GeoMap('map', {
  control: {
    navigation: true
    // 或: navigation: { compass: true, zoomControls: true, distanceLegend: true }
  }
});

| 方法 | 说明 | |------|------| | map.navigation.setNavigationLocked(locked) | 锁定/解锁交互 | | map.navigation.getNavigationLocked() | 查询锁定状态 | | map.navigation.getInstance() | 获取底层 CesiumNavigation | | map.navigation.destroy() | 销毁 |


NavBar

左侧垂直导航栏:罗盘、复位、2D/3D 切换、缩放。

const map = new GeoMap('map', {
  control: {
    navBar: true
    // 或: navBar: { position: 'left', showCompass: true, showHome: true, showSceneMode: true, showZoom: true, zoomFactor: 2 }
  }
});

| 方法 | 说明 | |------|------| | map.navBar.show() / hide() / toggle() | 显隐控制 | | map.navBar.destroy() | 销毁 |


Toolbar — 状态栏

底部状态栏:实时显示鼠标经纬度、投影坐标、海拔、层级、朝向、俯仰角、视高、FPS、比例尺。

const map = new GeoMap('map', { control: { toolbar: true } });

| 方法 | 返回值 | 说明 | |------|--------|------| | map.toolbar.show() | Toolbar | 显示 | | map.toolbar.hide() | Toolbar | 隐藏 | | map.toolbar.toggle() | Toolbar | 切换 | | map.toolbar.getInfo() | object | 获取当前状态快照 | | map.toolbar.destroy() | void | 销毁 |

getInfo() 返回值:

{
  lon, lat,          // 鼠标经纬度
  altitude,          // 地形海拔
  heading, pitch,    // 相机朝向/俯仰(度)
  cameraHeight,      // 相机高度(米)
  level,             // 层级 (0-22)
  fps                // 帧率
}

Toolbar 构造选项可精细控制显示项:

| 属性 | 默认 | 说明 | |------|------|------| | showLon / showLat | true | 经纬度 | | showProjection | true | Web Mercator X/Y | | showAltitude | true | 海拔 | | showLevel | true | 层级 | | showHeading / showPitch | true | 朝向/俯仰 | | showCameraHeight | true | 视高 | | showFPS | true | FPS | | showScalebar | true | 比例尺 |


管理器

EventManager — 事件

地图初始化后通过 map.events 访问,统一管理所有交互事件。

map.events.on('leftClick', (e) => {
  console.log(e.lonlat);       // [lng, lat, height]
  console.log(e.entity);       // 拾取到的 Entity
  console.log(e.pickedObject); // scene.pick() 原始结果
});

map.events.on('mouseMove', (e) => { ... });
map.events.once('leftClick', handler);
map.events.off('leftClick', handler);

鼠标事件回调参数

| 属性 | 类型 | 说明 | |------|------|------| | type | string | 事件类型名 | | raw | object | Cesium 原始 movement | | position | Cartesian2 | 屏幕坐标 | | pickedObject | object | scene.pick() 结果 | | entity | Entity | 拾取到的实体 | | primitive | object | 拾取到的图元 | | cartesian | Cartesian3 | 世界坐标 | | lonlat | number[] | [lng, lat, height] |

支持的事件名

鼠标事件:leftClickleftDoubleClickleftDownleftUprightClickrightDownrightUpmiddleClickmiddleDownmiddleUpmouseMovewheel

场景事件:cameraChangedsceneModeChangedpreRenderpostRendermorphCompletemorphStart


PopupManager — 弹窗

通过 map.popup 访问。给图形设置 popup 属性后,左键点击自动弹出。

// 声明式 — 图形自带 popup
new PointGraphic({
  position: [116.4, 39.9, 0],
  popup: '<b>北京</b><p>中国首都</p>'
});

// 命令式
map.popup.show('<b>自定义弹窗</b>', [116.4, 39.9, 0]);
map.popup.hide();

构造选项:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | auto | boolean | true | 自动拦截左键点击 | | closeButton | boolean | true | 关闭按钮 | | followCamera | boolean | true | 跟随相机移动 | | offset | number[] | [0, -10] | 像素偏移 | | className | string | 'geoglobe-popup' | CSS 类名 |


TooltipManager — 提示

通过 map.tooltip 访问。给图形设置 tooltip 属性后,鼠标悬停自动显示。

new PointGraphic({
  position: [116.4, 39.9, 0],
  tooltip: '北京市'
});

// 命令式
map.tooltip.show('提示文本', { x: 100, y: 200 });
map.tooltip.hide();

构造选项:

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | offset | number[] | [14, -14] | 像素偏移 | | className | string | 'geoglobe-tooltip' | CSS 类名 |


SpaceSkyBox — 天空盒

程序化生成星空背景,支持闪烁和流星效果。全部为静态方法

通过构造参数配置

const map = new GeoMap('map', {
  skyBox: {
    animate: true,
    speed: 2,
    starCount: 800,
    meteorInterval: 3000,
    meteorSpeed: 1,
    maxMeteors: 3
  }
});

运行时控制

// 天空盒切换
map.setSkyBox('space');
map.setSkyBox('default');
map.setSkyBox(false);
map.setSkyBox({ sources: { positiveX: '...', negativeX: '...', ... } });

// 星星闪烁动画
SpaceSkyBox.startAnimation(map.viewer, { speed: 2, starCount: 800 });
SpaceSkyBox.stopAnimation();
SpaceSkyBox.setRotationSpeed(4);

// 流星效果
SpaceSkyBox.startMeteorAnimation(map.viewer, {
  interval: 3000,
  speed: 1,
  maxMeteors: 3
});
SpaceSkyBox.stopMeteorAnimation();
SpaceSkyBox.setMeteorInterval(5000);

create() 选项

| 属性 | 类型 | 默认值 | 说明 | |------|------|--------|------| | resolution | number | 2048 | 单面纹理分辨率 | | starCount | number | 9000 | 基础星星数 | | brightStarCount | number | 30 | 亮星数(带光晕) | | nebulaIntensity | number | 0.5 | 星云亮度 (0~1) | | milkyWayIntensity | number | 0.35 | 银河带亮度 (0~1) | | backgroundColor | string | '#000005' | 背景色 |


常量与枚举

框架封装了常用 Cesium 常量,无需直接引用 Cesium 命名空间:

import {
  // 场景 & 渲染
  SceneMode, Color, HeightReference,
  HorizontalOrigin, VerticalOrigin, LabelStyle,
  ClassificationType, ArcType, ShadowMode, ColorBlendMode,

  // 坐标 & 几何
  Cartesian2, Cartesian3, Cartesian4, Cartographic,
  Rectangle, PolygonHierarchy, BoundingSphere,

  // 数学 & 变换
  CesiumMath, Quaternion, Matrix2, Matrix3, Matrix4,
  TranslationRotationScale, HeadingPitchRange, HeadingPitchRoll,

  // 可见性
  NearFarScalar, DistanceDisplayCondition,

  // 材质属性
  Material, MaterialProperty, CallbackProperty,
  ColorMaterialProperty, ImageMaterialProperty,
  CheckerboardMaterialProperty, StripeMaterialProperty, GridMaterialProperty,
  PolylineGlowMaterialProperty, PolylineOutlineMaterialProperty,
  PolylineDashMaterialProperty, PolylineArrowMaterialProperty,

  // 动画/采样
  ConstantProperty, SampledProperty, SampledPositionProperty,
  TimeIntervalCollectionProperty,

  // 时间
  JulianDate, TimeInterval, TimeIntervalCollection,
  ClockRange, ClockStep,

  // 事件
  ScreenSpaceEventType, ScreenSpaceEventHandler,

  // Primitive API
  Resource, Primitive, GeometryInstance, PolygonGeometry, MaterialAppearance,

  // 地形
  CustomHeightmapTerrainProvider, EllipsoidTerrainProvider
} from 'geoglobe-3d';

快速示例:

const red = Color.fromCssColorString('#ff0000');
const pos = Cartesian3.fromDegrees(116.4, 39.9, 100);
const rad = CesiumMath.toRadians(45);

实战案例

案例 1 — 加载 GeoJSON + Popup 交互

const map = new GeoMap('map', {
  skyBox: 'space',
  camera: { position: [104, 35, 5000000] },
  control: { toolbar: true, navBar: true }
});

const geojson = new GeoJsonLayer({
  url: './data/china.geojson',
  stroke: '#ff6600',
  strokeWidth: 2,
  fill: 'rgba(255,102,0,0.3)',
  clampToGround: true,
  onClick: (entity) => {
    const name = entity.name || '未命名';
    map.popup.show(`<b>${name}</b>`, entity.position?.getValue());
  }
});
map.addLayer(geojson);

geojson.on('load', () => {
  console.log('GeoJSON 加载完成');
  geojson.flyTo();
});

案例 2 — 3D Tiles + 图形叠加

const map = new GeoMap('map', {
  terrain: { enabled: true },
  camera: { position: [116.4, 39.9, 3000], pitch: -45 }
});

// 加载三维建筑
const tileset = new TilesetLayer({
  url: 'https://your-server/tileset.json',
  maximumScreenSpaceError: 8,
  style: { color: "color('white', 0.8)" }
});
map.addLayer(tileset);

// 在建筑旁添加标注
const marks = new GraphicLayer({ id: 'marks' });
map.addLayer(marks);

marks.addGraphics([
  new BillboardGraphic({
    position: [116.4, 39.9, 100],
    style: { image: './icons/pin.png', width: 32, height: 32, verticalOrigin: 'bottom' },
    popup: '<h3>国贸大厦</h3><p>高度: 330米</p>'
  }),
  new LabelGraphic({
    position: [116.4, 39.9, 350],
    style: { text: '国贸大厦', font: '14px Microsoft YaHei', fillColor: '#fff' }
  })
]);

案例 3 — 绘制 + 量算联动

const draw = new Draw(map);
const measure = new Measure(map);

document.getElementById('btn-draw-polygon').onclick = async () => {
  const result = await draw.polygon();
  if (!result.cancelled) {
    console.log('绘制完成,顶点数:', result.positions.length);
  }
};

document.getElementById('btn-measure-dist').onclick = async () => {
  const result = await measure.distance();
  if (!result.cancelled) {
    alert(`总距离: ${(result.distance / 1000).toFixed(2)} km`);
  }
};

document.getElementById('btn-clear').onclick = () => {
  draw.clear();
  measure.clear();
};

案例 4 — 时间动画 + CZML 轨迹

const map = new GeoMap('map', {
  control: { animation: true, timeline: true }
});

const czml = new CzmlLayer({ url: './data/satellite.czml' });
map.addLayer(czml);

czml.on('load', () => {
  czml.flyTo();
  map.setClock({
    multiplier: 100,
    clockRange: 'loop',
    animate: true
  });
});

FAQ

Q: 地图显示黑屏 检查浏览器 WebGL 2.0 支持,确保 dist/ 目录完整部署,查看控制台报错。

Q: 3D Tiles 位置偏移 使用 TilesetLayerposition / rotation 参数调整:

new TilesetLayer({
  url: '...',
  position: [lng, lat, height],
  rotation: { heading: 0, pitch: 0, roll: 0 }
});

Q: 影像图层跨域报错 服务端需配置 CORS,或通过代理转发请求。

Q: 如何访问底层 Cesium API

const viewer = map.viewer;        // Cesium.Viewer
const scene  = map.viewer.scene;  // Cesium.Scene
const globe  = scene.globe;       // Cesium.Globe

Q: 页面卸载时资源释放

window.addEventListener('beforeunload', () => map.destroy());

Q: ESM 项目 Cesium Worker 路径配置 在 Vite/Webpack 中需配置 CESIUM_BASE_URL 指向 Cesium 静态资源目录。UMD 版本框架自动处理。


项目结构

zgis-cesium/
├── src/
│   ├── index.js              # 主入口,统一导出
│   ├── constants/             # 常量与枚举封装
│   ├── core/
│   │   ├── Map.js             # GeoMap 核心类
│   │   ├── EventManager.js    # 事件管理
│   │   ├── PopupManager.js    # 弹窗管理
│   │   ├── TooltipManager.js  # 提示管理
│   │   └── SpaceSkyBox.js     # 程序化天空盒
│   ├── graphic/               # 14 种图形类
│   ├── layer/                 # 8 种图层类
│   ├── tool/                  # Draw / Measure
│   ├── control/               # Navigation / NavBar / Toolbar
│   └── utils/                 # 工具函数
├── dist/                      # 构建产物
├── examples/                  # 13 个示例 HTML
├── Build/                     # Cesium 本地源(UMD 打包用)
├── rollup.config.js           # Rollup 构建配置
└── package.json

示例列表

| 文件 | 说明 | |------|------| | base.html | 基础示例:Toolbar + 工具栏 | | advanced.html | 高级功能:图形、图层、工具综合 | | graphic-layers.html | 各类图形演示 | | layer-management.html | 图层管理与排序 | | data-layers.html | GeoJSON / KML / CZML 数据图层 | | terrain.html | 地形加载 | | terrain-custom.html | 自定义高度图地形 | | popup-tooltip.html | Popup 弹窗与 Tooltip 提示 | | measure-tools.html | 距离、面积、高度、角度量算 | | time-system.html | 时钟与时间动画系统 | | camera-scene.html | 相机控制与场景模式切换 | | imagery-layers.html | 影像图层类型演示 | | materials.html | Fabric 材质与自定义着色器 |

npm start 后访问 http://localhost:8080


geoGlobe3D — 让三维地图开发更简单