当前位置: 首页 > news >正文

开源库入门教程 Cesium:3D地球和地图库

文章目录

    • Cesium是什么?
    • 为什么选择Cesium?
    • 快速上手Cesium
      • 安装和配置
        • 方法1:使用npm安装(适合现代前端工程)
        • 方法2:使用CDN(最简单的方式)
      • 创建你的第一个Cesium应用
    • Cesium的核心概念
      • 1. Viewer(查看器)
      • 2. Entity(实体)
      • 3. DataSource(数据源)
      • 4. Primitive(图元)
      • 5. Camera(相机)
    • 实用技巧和示例
      • 加载不同类型的影像图层
      • 添加3D建筑和城市模型
      • 绘制路径和轨迹
      • 交互事件处理
    • 性能优化建议
    • 常见问题和解决方案
      • 1. "terrain provider is not ready"错误
      • 2. 坐标转换问题
      • 3. 如何测量距离和面积
      • 4. 在线和离线部署的区别
    • 后续学习资源
    • 结语

最近在做项目时需要展示地理数据,我尝试了好几个库后才发现了Cesium这个宝藏!它让我能够在浏览器中创建惊艳的3D地球和地图应用。今天就和大家分享一下我使用Cesium的心得和入门步骤,希望对你有所帮助!

Cesium是什么?

Cesium是一个开源的JavaScript库,专门用于创建高性能的3D地球和地图应用。它最初由AGI(Analytical Graphics, Inc.)公司在2012年开发,现在由Cesium GS公司维护。

Cesium最厉害的地方在于它能在网页浏览器中渲染完整的3D地球,而且不需要任何插件(这点真的太棒了)!它直接使用WebGL技术,所以在现代浏览器中都能流畅运行。

为什么选择Cesium?

在众多地图库中,Cesium有几个突出优势:

  1. 真正的3D地球 - 不同于很多2D地图库,Cesium提供了一个完整的3D地球模型,支持从太空到街道级别的无缝缩放。

  2. 时间动态数据 - Cesium有一个内置的时间轴控件,可以展示随时间变化的数据(比如卫星轨道、天气变化等)。

  3. 精确的地理参考 - 支持各种坐标系统和地理投影,保证数据在地球上的准确位置。

  4. 海量数据处理能力 - 能够高效处理大量的地理数据,包括地形、影像和矢量数据。

  5. 活跃的社区支持 - 有完善的文档和活跃的社区,遇到问题很容易找到解决方案。

快速上手Cesium

接下来,我会带你从零开始搭建一个简单的Cesium应用。相信我,比你想象的要简单!

安装和配置

有几种方式可以在项目中使用Cesium:

方法1:使用npm安装(适合现代前端工程)
npm install cesium

安装后,还需要配置一下webpack或其他打包工具,因为Cesium包含了一些静态资源需要特殊处理。

方法2:使用CDN(最简单的方式)

如果你只是想快速尝试,直接在HTML中引入CDN链接就可以了:

<script src="https://cesium.com/downloads/cesiumjs/releases/1.104/Build/Cesium/Cesium.js"></script>
<link href="https://cesium.com/downloads/cesiumjs/releases/1.104/Build/Cesium/Widgets/widgets.css" rel="stylesheet">

注意版本号可能会更新,建议去官网查看最新版本。

创建你的第一个Cesium应用

下面是一个最基础的Cesium应用示例:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8"><title>我的第一个Cesium应用</title><script src="https://cesium.com/downloads/cesiumjs/releases/1.104/Build/Cesium/Cesium.js"></script><link href="https://cesium.com/downloads/cesiumjs/releases/1.104/Build/Cesium/Widgets/widgets.css" rel="stylesheet"><style>html, body, #cesiumContainer {width: 100%;height: 100%;margin: 0;padding: 0;overflow: hidden;}</style>
</head>
<body><div id="cesiumContainer"></div><script>// 你需要一个Cesium ion账号获取tokenCesium.Ion.defaultAccessToken = '你的Cesium ion token';// 创建Cesium查看器const viewer = new Cesium.Viewer('cesiumContainer', {terrain: Cesium.Terrain.fromWorldTerrain(),// 开启大气效果skyAtmosphere: true,// 显示底图选择器baseLayerPicker: true});// 设置初始视图为北京viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042, 15000),orientation: {heading: Cesium.Math.toRadians(0),pitch: Cesium.Math.toRadians(-90),roll: 0.0}});</script>
</body>
</html>

这段代码会创建一个基本的3D地球,并将视角定位到北京上空。你需要注册一个Cesium ion账号来获取免费的token,这样才能访问Cesium提供的地形和影像服务。

Cesium的核心概念

在开始创建复杂应用前,有必要了解Cesium的几个核心概念:

1. Viewer(查看器)

Viewer是Cesium应用的核心组件,它包含了3D地球和一系列控件。创建一个Viewer非常简单:

const viewer = new Cesium.Viewer('cesiumContainer');

Viewer提供了很多配置选项,例如:

const viewer = new Cesium.Viewer('cesiumContainer', {terrain: Cesium.Terrain.fromWorldTerrain(), // 加载全球地形timeline: true, // 显示时间轴animation: true, // 显示动画控件baseLayerPicker: true, // 显示底图选择器sceneModePicker: true, // 显示场景模式选择器navigationHelpButton: true, // 显示帮助按钮infoBox: true, // 显示信息框fullscreenButton: true // 显示全屏按钮
});

2. Entity(实体)

Entity是Cesium中表示地理对象的基本方式,可以是点、线、面、模型等。例如,添加一个点标记:

viewer.entities.add({position: Cesium.Cartesian3.fromDegrees(116.4074, 39.9042),point: {pixelSize: 10,color: Cesium.Color.RED},label: {text: '北京',font: '14pt sans-serif',pixelOffset: new Cesium.Cartesian2(0, -20)}
});

3. DataSource(数据源)

DataSource用于加载和管理大量实体数据,支持多种格式如GeoJSON、KML、CZML等:

// 加载GeoJSON数据
const dataSource = Cesium.GeoJsonDataSource.load('data/china.geojson', {stroke: Cesium.Color.BLUE,fill: Cesium.Color.BLUE.withAlpha(0.5),strokeWidth: 3
});
viewer.dataSources.add(dataSource);

4. Primitive(图元)

Primitive是更底层的渲染对象,比Entity性能更高,适合渲染大量图形:

// 创建一个蓝色矩形
const instance = new Cesium.GeometryInstance({geometry: new Cesium.RectangleGeometry({rectangle: Cesium.Rectangle.fromDegrees(115, 39, 117, 41),vertexFormat: Cesium.PerInstanceColorAppearance.VERTEX_FORMAT}),attributes: {color: Cesium.ColorGeometryInstanceAttribute.fromColor(Cesium.Color.BLUE.withAlpha(0.5))}
});viewer.scene.primitives.add(new Cesium.Primitive({geometryInstances: instance,appearance: new Cesium.PerInstanceColorAppearance()
}));

5. Camera(相机)

Camera控制视角,可以通过编程方式控制飞行和视角:

// 飞行到特定位置
viewer.camera.flyTo({destination: Cesium.Cartesian3.fromDegrees(121.5, 31.2, 10000), // 上海orientation: {heading: Cesium.Math.toRadians(30), // 朝向pitch: Cesium.Math.toRadians(-45), // 俯仰角roll: 0 // 翻滚角},duration: 3 // 飞行时间(秒)
});

实用技巧和示例

下面分享几个实用的Cesium功能和示例,这些在实际项目中超级有用!

加载不同类型的影像图层

Cesium支持多种影像服务:

// 添加Bing地图影像
viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({url: 'https://dev.virtualearth.net',key: '你的Bing Maps API密钥',mapStyle: Cesium.BingMapsStyle.AERIAL_WITH_LABELS})
);// 添加WMS服务
viewer.imageryLayers.addImageryProvider(new Cesium.WebMapServiceImageryProvider({url: 'https://某WMS服务地址',layers: '图层名',parameters: {format: 'image/png',transparent: true}})
);

添加3D建筑和城市模型

3D Tiles是Cesium的一项重要技术,用于流式加载大规模3D模型:

// 加载3D建筑模型
const tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({url: Cesium.IonResource.fromAssetId(96188) // 这是纽约的3D建筑模型ID})
);// 设置样式,例如根据建筑高度着色
tileset.style = new Cesium.Cesium3DTileStyle({color: {conditions: [['${height} >= 300', 'color("red")'],['${height} >= 200', 'color("orange")'],['${height} >= 100', 'color("yellow")'],['true', 'color("white")']]}
});

绘制路径和轨迹

可以使用Entity创建动态路径:

// 定义路径点
const positions = [];
for (let i = 0; i < 100; i++) {const longitude = 116.4 + Math.random() * 0.1;const latitude = 39.9 + Math.random() * 0.1;positions.push(Cesium.Cartesian3.fromDegrees(longitude, latitude, 0));
}// 创建路径实体
const path = viewer.entities.add({polyline: {positions: positions,width: 5,material: new Cesium.PolylineGlowMaterialProperty({glowPower: 0.2,color: Cesium.Color.BLUE})}
});// 创建沿路径移动的点
const point = viewer.entities.add({position: new Cesium.CallbackProperty(function(time) {// 计算当前时间在路径上的位置const seconds = Cesium.JulianDate.secondsDifference(time, viewer.clock.startTime);const index = Math.floor(seconds * 5) % positions.length;return positions[index];}, false),point: {pixelSize: 15,color: Cesium.Color.RED}
});// 设置时钟开始运行
viewer.clock.shouldAnimate = true;

交互事件处理

Cesium提供了丰富的事件系统,例如鼠标点击:

// 添加鼠标点击事件处理
const handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function(click) {// 将屏幕坐标转换为地球表面坐标const pickedObject = viewer.scene.pick(click.position);if (Cesium.defined(pickedObject) && pickedObject.id) {// 点击了某个实体console.log('点击了实体:', pickedObject.id);} else {// 将屏幕坐标转换为地球表面坐标const cartesian = viewer.scene.pickPosition(click.position);if (Cesium.defined(cartesian)) {const cartographic = Cesium.Cartographic.fromCartesian(cartesian);const longitude = Cesium.Math.toDegrees(cartographic.longitude);const latitude = Cesium.Math.toDegrees(cartographic.latitude);const height = cartographic.height;console.log(`点击位置:经度=${longitude}, 纬度=${latitude}, 高度=${height}`);}}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

性能优化建议

使用Cesium开发大型应用时,需要注意性能问题,这里有几个实用的优化技巧:

  1. 使用Entity还是Primitive?

    • 少量对象(<1000):使用Entity,开发更简单
    • 大量对象(>1000):使用Primitive,性能更好
  2. 限制可见性

    • 使用tileset.maximumScreenSpaceError控制3D Tiles的细节级别
    • 设置entity.showprimitive.show根据距离显示或隐藏对象
  3. 使用地形和影像的分层细节(LOD)

    • 设置适当的viewer.scene.screenSpaceCameraController.maximumZoomDistance
    • 根据距离切换不同分辨率的影像
  4. 避免频繁更新位置

    • 使用viewer.scene.requestRender()而不是每帧更新
    • 对于动画,使用Cesium的时钟系统和CallbackProperty
  5. 使用BatchTable和GPU批处理

    • 对于大量相似的对象,使用BatchTable进行批处理
    • 考虑使用Cesium的BatchedInstancedFeatures

常见问题和解决方案

在使用Cesium过程中,我遇到过这些常见问题,分享给大家:

1. "terrain provider is not ready"错误

这通常是因为地形提供者还没有完全加载。解决方法是在使用地形之前先检查其就绪状态:

Cesium.Terrain.fromWorldTerrain().readyPromise.then(function(terrain) {viewer.terrainProvider = terrain;// 现在可以安全地使用地形了});

2. 坐标转换问题

Cesium中有多种坐标系统,常见的有:

  • 经纬度坐标(度)
  • Cartesian3(笛卡尔坐标)
  • Cartographic(弧度表示的经纬度)

它们之间的转换方式:

// 经纬度转Cartesian3
const position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);// Cartesian3转经纬度
const cartographic = Cesium.Cartographic.fromCartesian(position);
const longitude = Cesium.Math.toDegrees(cartographic.longitude);
const latitude = Cesium.Math.toDegrees(cartographic.latitude);
const height = cartographic.height;

3. 如何测量距离和面积

使用Cesium的空间计算功能:

// 计算两点距离
const point1 = Cesium.Cartesian3.fromDegrees(116.4, 39.9);
const point2 = Cesium.Cartesian3.fromDegrees(121.5, 31.2);
const distance = Cesium.Cartesian3.distance(point1, point2); // 米// 计算多边形面积
const positions = [Cesium.Cartesian3.fromDegrees(116.0, 40.0),Cesium.Cartesian3.fromDegrees(117.0, 40.0),Cesium.Cartesian3.fromDegrees(117.0, 39.0),Cesium.Cartesian3.fromDegrees(116.0, 39.0)
];// 需要手动计算面积,Cesium没有直接的API
// 可以使用turf.js等库辅助计算

4. 在线和离线部署的区别

在线模式需要Cesium ion账号和互联网连接,而离线部署需要:

  • 下载并本地托管Cesium静态资源
  • 准备本地地形和影像数据
  • 配置适当的本地数据提供者
// 使用本地地形
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({url: './terrain'
});// 使用本地影像
viewer.imageryLayers.addImageryProvider(new Cesium.TileMapServiceImageryProvider({url: './imagery'})
);

后续学习资源

如果你想深入学习Cesium,这些资源非常有用:

  1. Cesium官方文档
  2. Cesium Sandcastle示例
  3. Cesium社区论坛
  4. Cesium GitHub仓库

结语

Cesium是一个功能强大的3D地球和地图库,它让我们能够创建令人惊叹的地理可视化应用。从简单的地图展示到复杂的时空数据分析,Cesium都能胜任。

虽然刚开始学习时有一定的门槛,但一旦掌握了基本概念,你就能快速开发出专业级的地理应用。希望这篇入门教程能够帮助你迈出第一步!

最后的建议是——多看官方示例,多动手实践,遇到问题就去查官方文档和社区。Cesium的世界很大,探索起来非常有趣!

记得,地图和地理数据可视化不仅仅是技术,更是一门艺术。用Cesium,让你的数据在3D世界中活起来吧!

http://www.dtcms.com/a/434537.html

相关文章:

  • WSL2 的 Ubuntu 系统从 G 盘移动到 F 盘
  • ubuntu20.04编译qt源码5.15.3
  • 保定哪家公司做网站安徽优化推广
  • 网站服务器租赁费用表格网络营销的效果表现在哪几个方面
  • HarmonyOS应用深度开发:ArkTS语法精解与状态管理实践
  • 开源 C# 快速开发(十六)数据库--sqlserver增删改查
  • 在相亲网站认识了一个做红酒生意的深圳做品牌网站
  • AI Agent 设计模式:从理论到实践的完整指南
  • 池州网站开发公司招聘外贸公司大全
  • WSL的安装与使用详解
  • 内网横向移动技术与防御详解
  • PYTHON:Python 新版本下载安装更新py文件Pycharm运行指南
  • Kubernetes中的service
  • Coze源码分析-资源库-编辑工作流-后端源码-流程/技术/总结
  • 医院网站建设招标公告惠州网站建设科技有限公司
  • 英语学习-Saints043-1
  • 大模型提示学习与思维链
  • 在线公司logo设计河南seo优化
  • 滑动窗口题目:最小覆盖子串
  • 【读书笔记】《深奥的简洁》
  • 支付宝手机网站支付贵阳门户网站
  • macOS 终端配置全攻略:zsh、bash_profile、zprofile、zshrc 到 nvm 配置的完整科普
  • Matlab通过GUI实现点云的Loss配准
  • 用户体验最好的网站做网站 参考文献
  • 离散与连续随机变量
  • 自适应网站好吗电子商务seo名词解释
  • 深入剖析 MySQL 中 binlog 与 redolog:区别、联系及在数据更新中的作用​
  • tensor转numpy,numpy转tensor
  • [创业之路-653]:社会产品与服务的分类
  • 洛谷题解P1249 最大乘积