惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Secure Thoughts
罗磊的独立博客
T
The Blog of Author Tim Ferriss
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
Last Week in AI
Last Week in AI
美团技术团队
Google Online Security Blog
Google Online Security Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
D
Docker
G
Google Developers Blog
大猫的无限游戏
大猫的无限游戏
酷 壳 – CoolShell
酷 壳 – CoolShell
小众软件
小众软件
月光博客
月光博客
L
LINUX DO - 最新话题
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
W
WeLiveSecurity
H
Heimdal Security Blog
Vercel News
Vercel News
SecWiki News
SecWiki News
Forbes - Security
Forbes - Security
Blog — PlanetScale
Blog — PlanetScale
Google DeepMind News
Google DeepMind News
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
www.infosecurity-magazine.com
www.infosecurity-magazine.com
TaoSecurity Blog
TaoSecurity Blog
T
Troy Hunt's Blog
A
About on SuperTechFans
C
Check Point Blog
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
AI
AI
WordPress大学
WordPress大学
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Help Net Security
Help Net Security
博客园_首页
The Last Watchdog
The Last Watchdog
S
SegmentFault 最新的问题
Hugging Face - Blog
Hugging Face - Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
Engineering at Meta
Engineering at Meta
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
I
Intezer
K
Kaspersky official blog
M
MIT News - Artificial intelligence
J
Java Code Geeks
G
GRAHAM CLULEY
P
Palo Alto Networks Blog

博客园 - 疯子110

Vue3 + Vite + Ts 报错:Property ‘ ‘ does not exist on type ‘never‘ activiti部署流程后act_re_procdef表中无流程定义信息 【转】openEuler欧拉系统重置密码 【转】nginx开启https导致springboot无法获取正确浏览器请求地址问题 【转】SLF4J(W): No SLF4J providers were found. 解决方法 vue项目放在springboot项目里后,刷新页面会显示whitelabel error page Vue3 echarts tooltip添加点击事件(最简版) Vue3富文本编辑器wangEditor 5使用总结【转载】 解决 vue3 中 Proxy(Object) 对象无法直接读取或使用 centos7-分区2T以上大硬盘[转】 关于mybatis进行sql查询字段值为null而不显示问题解决办法 Vue3 - 项目中使用 debugger 在 chrome 谷歌浏览器中失效 vue项目error Unexpected ‘debugger‘ statement no-debugger报错 vue项目中 报错 error ‘xxx‘ is assigned a value but never used 在vue中使用leaflet加载地图【转载】 无法加载文件 D:\Program Files\xxxxx\vue.ps1,因为在此系统上禁止运行脚本”的解决方法 - 疯子110 Vue3安装配置+VSCode开发环境搭建,超详细保姆级教程(图文) 【转】将postgresql表名和字段名统一转换为小写 【cesium】修改底图颜色为蓝色科技范儿
【cesium重新梳理】1.cesium知识整理
疯子110 · 2024-11-26 · via 博客园 - 疯子110

之前零零碎碎学过、用过cesium,但也没做记录,现在重新整理一下,方便学习回顾。

1.cesium简介

CesiumJS是一个开源JavaScript库,用于创建具有最佳性能、精度、视觉质量和易用性的世界级3D地球仪和地图。从航空航天到智能城市再到无人机,各行各业的开发人员都使用CesiumJS创建交互式Web应用程序来共享动态地理空间数据。

cesium官网链接

可以在官网下载cesium 的源码,也可以用npm下载依赖包

npm install cesium

2.vue3.2中使用cesium

2.1初始化地球

创建vue项目,用包管理工具下载好cesium,在node_modules中找到下面的4个资源,复制粘贴到public文件夹下,当然,Widgets文件夹里都是css资源,可以放在src里面,方便后续调用。

准备一个div,给定id值,用来承接cesium的展示

<div id="cesiumContainer" ref="cesiumContainer"></div>

然后引入cesium和相关css资源

import * as Cesium from "cesium";
import "./Widgets/widgets.css";
<template>
  <div id="cesiumContainer" ref="cesiumContainer"></div>
</template>

<script setup>
import * as Cesium from "cesium";
import "./Widgets/widgets.css";
import { onMounted } from "vue";

展示出地球

ceisum提供了一些默认的交互方式,例如:

·按住鼠标左键拖曳:拖动相机在三维地球平面平移。

·按住鼠标右键拖曳:缩放相机。

·使用鼠标滚轮(即鼠标中键)滑动:缩放相机。

·按住鼠标滚轮拖曳:根据当前地球的屏幕中点,旋转相机。

2.2基础配置(默认控件)

cesium有一些默认的控件,我们可以去设置控件的显示隐藏。

var viewer = new Cesium.Viewer("cesiumContainer", {
    

3.天空盒子

cesium中有天空盒的概念,其实就是在一个立方体盒子的六个面上贴图,当然这些贴图是同一个场景下的,然后将【相机】,也就是观察视角,放在盒子的中心位置,这样无论朝哪个方向去看,都能收获三维立体的沉浸感。

如下图所示:

如何操作天空盒?主要是用到SkyBox类

实现方法:

var viewer = new Cesium.Viewer("cesiumContainer", {
    skyBox: new Cesium.SkyBox({
      sources: {
        positiveX: "./texture/sky/px.jpg",
        negativeX: "./texture/sky/nx.jpg",
        positiveY: "./texture/sky/ny.jpg",
        negativeY: "./texture/sky/py.jpg",
        positiveZ: "./texture/sky/pz.jpg",
        negativeZ: "./texture/sky/nz.jpg",
      },
    }),
  });

具体的参数对应关系如下

序号参数含义
1 negativeX left
2 positiveX right
3 negativeY front
4 positiveY back
5 negativeZ down
6 positiveZ up

4.地图加载

cesium提供了非常强大且全面的API用来加载数据、地图,这个可以专门写一篇文章详细说明,这里只罗列一些常见地图的加载。可以使用imageryProvider来加载地图。

4.1天地图

加载天地图影像地图

var viewer = new Cesium.Viewer("cesiumContainer", {
    imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
        url: "http://t0.tianditu.com/vec_w/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=vec&tileMatrixSet=w&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=申请的K值",
        layer: "tdtBasicLayer",
        style: "default",
        format: "image/jpeg",
        tileMatrixSetID: "GoogleMapsCompatible",

还可以继续加载地图(或地图注记),实现地图的叠加展示,使用viewer.imageryLayers.addImageryProvider。

//地图叠加:下面这个图层是 放在上层的图层
  var imageryLayers = viewer.imageryLayers;
  var layer = imageryLayers.addImageryProvider(
    new Cesium.UrlTemplateImageryProvider({
      url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
      layer: "tdtVecBasicLayer",
      style: "default",
      format: "image/png",
      tileMatrixSetID: "GoogleMapsCompatible",
    })
  );

后加入的地图默认会覆盖前面的地图。

4.2高德地图

var viewer = new Cesium.Viewer("cesiumContainer", {
    imageryProvider: new Cesium.UrlTemplateImageryProvider({
      url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",
      layer: "tdtVecBasicLayer",
      style: "default",
      format: "image/png",
      tileMatrixSetID: "GoogleMapsCompatible",
    }),
     }),
  });

4.3 OSM

这里用的是Cesium.OpenStreetMapImageryProvider

var viewer = new Cesium.Viewer("cesiumContainer", {
 

当然,还有非常多地图需要加载,这会后续可以专门总结一篇。

5.地形的加载

5.1在线加载地形

这是用到了cesium自带的方法,在线加载地形。

var viewer = new Cesium.Viewer("cesiumContainer", {

5.2本地加载地形

提前准备好地形数据,这里我用的是广州某区域的地形切片。

var viewer = new Cesium.Viewer("cesiumContainer", {

6.坐标系与转换

cesium中常见的坐标系有这些

1.WGS-84地理坐标系

2.屏幕坐标系(笛卡尔平面直角坐标)

3.笛卡尔空间直角坐标系

6.1.WGS-84地理坐标系

通过new Cesium.Cartographic(longitude,latitude,height)来创建,三个参数分别代表经度,纬度,高度

6.2.屏幕坐标系(笛卡尔平面直角坐标)

屏幕坐标系即二维笛卡尔坐标系,Cesium中使用Cartesian2来描述,屏幕左上角为原点(0,0),单位为像素值,屏幕水平方向为X轴,向右为正,垂直方向为Y轴,向下为正。通过new Cesium.Cartesian2 (x,y)创建对象,其中的(x,y)代表平面坐标系中的坐标。

6.3.笛卡尔空间直角坐标系(世界坐标系)

又叫做世界坐标系。 标系(Cartesian3)。笛卡儿空间直角坐标系的原点就是椭球体的中心点。由于我们在计算机上绘图时不方便参照经纬度直接进行绘制,所以通常会先将坐标系转换为笛卡儿空间直角坐标系,再进行绘制。如图所示,笛卡儿空间直角坐标系的3个分量x、y、z,可 以被看作以椭球体中心点为原点的空间直角坐标系中的某一个点的坐标。

用法:

在Cesium中,使用Cartesian3类,通过new Cesium.Cartesian3 (x,y,z)创建对象,其中的(x,y,z)代表笛卡儿空间直角坐标系中的坐标。

6.4 坐标转换

1.角度与弧度的转换

WGS84坐标的经纬度有弧度、角度两种形式,可以使用cesium提供的数学方法进行转换,弧度转角度,角度转弧度。

 // 角度转为弧度
  var radians = Cesium.Math.toRadians(90);
  console.log(radians);
  

当然,经纬度转弧度也可以用Cesium.Cartographic.fromDegrees

//WGS84经纬度坐标 转 弧度坐标
var radians = Cesium.Cartographic.fromDegrees(
    longitude,
    latitude,
    height
);

2.屏幕坐标转世界坐标(Cartesian2转Cartesian3)

首先要用如下代码,来实现鼠标点击获取屏幕坐标

创建变量handler,并实例化一个ScreenSpaceEventHandler对象,然后使用该对象的setInputAction方法设置要在输入事件上执行的功能。

var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
    

关于世界坐标,还有一些需要区分的地方,主要是三种情况,主要看这个点位是否考虑地形、模型、倾斜摄影等等。

(1)场景坐标,包括地形、倾斜摄影模型等的坐标

Cesium中的Camera提供了pickEllipsoid方法

//屏幕坐标 转 世界坐标(场景坐标,包括地形、倾斜摄影模型等的坐标)

var cartesian3 = viewer.scene.pickPosition(movement.position); 

(2)地表坐标,包括地形但不包括模型、倾斜摄影等

通过相机与屏幕点位连线来求取坐标。

var ray = viewer.camera.getPickRay(movement.position);
var cartesian3 = viewer.scene.globe.pick(ray, viewer.scene);
console.log("屏幕坐标转世界坐标(地表):", cartesian3);

(3)椭球面坐标,不包括地形、模型、倾斜摄影等

var cartesian3 = viewer.scene.camera.pickEllipsoid(
        movement.position
);
console.log("屏幕坐标转世界坐标(椭球面):", cartesian3);

3.世界坐标转屏幕坐标

可以通过Cesium.SceneTransforms.wgs84ToWindowCoordinates方法将世界坐标系转换为平面坐标系。该方法需要传入两个参数,分别为scene和position,其中:scene为当前场景,即viewer. scene; position为世界坐标系中的坐标。

//世界坐标 转 屏幕坐标
var cartesian2 =
    Cesium.SceneTransforms.wgs84ToWindowCoordinates(
            viewer.scene,
            cartesian3
    );
console.log("世界坐标转屏幕坐标:", cartesian2);

4.世界坐标转WGS84

//世界坐标 转 WGS84坐标,结果为弧度形式
var cartographic =
        Cesium.Cartographic.fromCartesian(cartesian3);
console.log("世界坐标转WGS84弧度坐标:", cartographic);

5.WGS坐标转世界坐标

//WGS84经纬度坐标 转 世界坐标
var position = Cesium.Cartesian3.fromDegrees(
        longitude,
        latitude,
        height
);
console.log("WGS84经纬度转世界坐标", position);

7.相机

cesium通过相机来控制视域,当我们进行交互,实现地图的放大缩小、视角的转换 等等操作时,实际上是相机在转换、移动。

ceisum提供了一些默认的交互方式,例如:

·按住鼠标左键拖曳:拖动相机在三维地球平面平移。

·按住鼠标右键拖曳:缩放相机。

·使用鼠标滚轮(即鼠标中键)滑动:缩放相机。

·按住鼠标滚轮拖曳:根据当前地球的屏幕中点,旋转相机。

7.1相机参数

如何设置相机?主要是借助于viewer.camera.setView


  var position = Cesium.Cartesian3.fromDegrees(116.393428, 39.90923, 100);
  viewer.camera.setView({
    

pitch、heading、row三个参数表示相机的姿态,使用position表示相机位置。

heading:默认方向为正北,正角度为向东旋转,即水平旋转,也叫偏航角。

pitch:默认角度为-90,即朝向地面,正角度在平面之上,负角度为平面下,即上下旋转,也叫俯仰角。

roll:默认旋转角度为0,左右旋转,正角度向右,负角度向左,也叫翻滚角。

7.2相机动画

可以让画面飞向指定的位置,并设置好相应的视角

  // flyto,让相机飞往某个地方
  viewer.camera.flyTo({
    destination: position,
    orientation: {
      heading: Cesium.Math.toRadians(0),
      pitch: Cesium.Math.toRadians(-20),
      roll: 0,
    },
  });

7.3 键盘操控相机

我们可以给键盘绑定一个监听函数,来控制相机的移动、旋转。这里主要用到的就是相机身上自带的一系列方法

// 通过按键移动相机
	document.addEventListener("keydown", e => {
		

8.添加物体

这一部分涉及entity和Primitive,关于这两者的联系和区别,适合单独开一篇文章详写,在这里就不过多解释,先列举一些常见小案例。

8.1添加点

使用entities.add,添加一个点实体,并配置好点的位置、大小、颜色等信息。

  var point = viewer.entities.add({
    

8.2添加一个文字标签

还是使用entities的add方法,来添加物体,其中label代表文字部分,在配置项中设置好相关属性;billboard是广告牌的意思,可以显示图片图标。

// 添加文字标签和广告牌
  var label = viewer.entities.add({
    position: Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 750),
    label: {
      text: "广州塔",
      font: "24px sans-serif",
      fillColor: Cesium.Color.WHITE,
      outlineColor: Cesium.Color.BLACK,
      outlineWidth: 4,
      

效果如下:

8.3 添加飞机模型

添加一个3D飞机模型

// 添加3D模型
const airplane = viewer.entities.add({
    name: "Airplane",
    position: Cesium.Cartesian3.fromDegrees(113.3191, 23.109, 1500),
    model: {
            uri: "./model/Air.glb",
            

8.4 添加一个矩形

传入2个点位参数,就能添加矩形

  // 使用entity创建矩形
  var rectangle = viewer.entities.add({
    rectangle: {
      coordinates: Cesium.Rectangle.fromDegrees(
        

8.5 Primitive绘制图形

Primitive绘制的图形由两部分组成:

第一部分为几何形状(Geometry) ,用于定义Primitive图形的绐构,如面、椭圆、线条等;

第二部分为外观(Appearance),主要用于定义Primitive图形的渲染着色,通俗 来讲,就是定义Primitive图形的外观材质。

.

下面我们先绘制一个线条:


//绘制线

当然,我们可以在设置外观的时候,自定义color

//给color添加配置项
var polylineAppearance = new Cesium.PolylineMaterialAppearance({
        material: Cesium.Material.fromType("Color", {
                color: new Cesium.Color(1.0, 1.0, 0.0, 1.0),
        }),
});

绘制一个四边形

//绘制面
//定义几何形状
var polygon = new Cesium.GeometryInstance({
        geometry: new Cesium.PolygonGeometry({
                polygonHierarchy: new Cesium.PolygonHierarchy(
                        Cesium.Cartesian3.fromDegreesArray([
                                108, 45, 109, 48, 104, 48, 103, 45,
                        ])
                ),
        }),
});