Cesium学习笔记

一、创建vue3 cesium项目流程

  1. 在某个文件夹中cmd,输入:pnpm create vite 名称
  2. 选好条件后:pnpm i
  3. pnpm i cesium@1.99 vite-plugin-cesium
  4. 修改vite.config.js文件
          特定位置添加:import cesium from 'vite-plugin-cesium'   和
                                   plugins: [vue(), cesium()],
  5. 注释掉main.js里的: import './style.css' //不要默认样式了
  6. 在App.vue中引入cesium:import * as Cesium from 'cesium'
    在onMounted中挂载地图并设置样式:​​​​​​

二、初始化一个干净的地球,去除不必要的控件

const viewer = new Cesium.Viewer("cesiumContainer", {
    baseLayerPicker: false, //是否显示图层选择控件
    animation: false, //是否显示动画控件
    timeline: false,  //是否显示时间轴
    fullscreenButton: false, //是否显示全屏按钮
    geocoder: false,  //是否显搜索框
    homeButton: false, //是否显示主页按钮
    sceneModePicker: false, //是否显示投影方式按钮
    navigationHelpButton: false //是否显示帮助按钮
  })

三、手动指定影像图层(默认使用的谷歌的影像图层)

const ersi = new Cesium.ArcGisMapServerImageryProvider({		        
    url:"https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer",
})
const viewer = new Cesium.Viewer("cesiumContainer", {
	imageryProvider: ersi,
})

四、经纬度 转 笛卡尔坐标

​
​const cartesian = Cesium.Cartesian3.fromDegrees(110,20,100) //参数:经度、维度、高度

笛卡尔坐标对象:

五、笛卡尔 转 经纬度坐标

// 笛卡尔转经纬度坐标(笛卡尔坐标->弧度坐标->经纬度坐标)
const cartographic = Cesium.Cartographic.fromCartesian(cartesian)
// let lon = 180 / Math.PI * cartographic.longitude
let lon = Cesium.Math.toDegrees(cartographic.longitude)
let lat = Cesium.Math.toDegrees(cartographic.latitude)
console.log(lon, lat, cartographic.height)

弧度坐标对象:

六、相机

// 相机
// setView通过定义相机飞行目的地,直接跳转到目的地
viewer.camera.setView({
    destination: position,
    // 方向(默认分别是 0 -90 0)
    orientation: {
	    heading: Cesium.Math.toRadians(0), //左右看
	    pitch: Cesium.Math.toRadians(-90), //上下看
	    roll: Cesium.Math.toRadians(0), //歪头看
    },
})
// flyTo有飞行动画
viewer.camera.flyTo({
	destination: position,
	duration: 3, //飞行时长 单位(秒)
	orientation: {
		heading: Cesium.Math.toRadians(0), //左右看
		pitch: Cesium.Math.toRadians(0), //上下看
		roll: Cesium.Math.toRadians(0), //歪头看
	},
})
// lookAt将视角固定在设置的点位上
const position2 = Cesium.Cartesian3.fromDegrees(110, 20, 20000)
viewer.camera.lookAt(
	position2,
	new Cesium.HeadingPitchRange(
		Cesium.Math.toRadians(0),
		Cesium.Math.toRadians(-90),
		20000
	)
)

七、常用实体

​
// 点
viewer.entities.add({
	position: Cesium.Cartesian3.fromDegrees(121, 30),
	point: {
		pixelSize: 20,
		color: Cesium.Color.RED,
	},
})

// 标注
const billboard = viewer.entities.add({
	position: Cesium.Cartesian3.fromDegrees(116, 40, 1000),
	billboard: {
		image: "/src/assets/img/点位.png",
		scale: 0.9, //控制图片大小
		// color: Cesium.Color.YELLOWGREEN                //封装好的颜色
		color: Cesium.Color.fromCssColorString("#fff"), //也可以自定义颜色
	},
    // 文本
	label: {
		text: "测试文字",
		showBackground: true, //开启背景色
		backgroundColor: Cesium.Color.BLACK.withAlpha(0.5), //颜色+开启透明度
		pixelOffset: new Cesium.Cartesian2(0, -40),
	},
})

// 线
const polyline = viewer.entities.add({
	polyline: {
		// positions: Cesium.Cartesian3.fromDegreesArray([100, 20, 100, 25, 115, 20]), //如果线是不需要高度的 就用这个
		positions: Cesium.Cartesian3.fromDegreesArrayHeights([
			100, 20, 5000, 100, 25, 5000, 115, 20, 500000,
		]),       //如果想让线有高度 就用这个
		width: 10,
		material: Cesium.Color.RED,
	},
})

// 多边形
const ploygon = viewer.entities.add({
	polygon: {
		hierarchy: {
			positions: Cesium.Cartesian3.fromDegreesArray([
				101, 21, 101, 26, 116, 21,
			]),
		},
		material: Cesium.Color.BLUE,
		height: 100000,
		extrudedHeight: 200000, //向上挤出高度
		outline: true,
		outlineColor: Cesium.Color.WHITE, //描边 外线
		fill: true, //是否填充
	},
})

// 盒子(立方体)
const box = viewer.entities.add({
	position: Cesium.Cartesian3.fromDegrees(119, 30, 3000),
	box: {
		dimensions: new Cesium.Cartesian3(2000, 1000, 3000),
		material: new Cesium.Color(1, 1, 0),
	},
})

// 椭圆
const ellipse = viewer.entities.add({
	position: Cesium.Cartesian3.fromDegrees(118, 30),
	ellipse: {
		semiMajorAxis: 500, //半长轴
		semiMinorAxis: 300, //半短轴
		material: Cesium.Color.YELLOW,
		rotation: Math.PI / 2, //旋转角度
	},
})

// 矩形
const rectangle = viewer.entities.add({
	rectangle: {
		coordinates: Cesium.Rectangle.fromDegrees(120, 40, 123, 45),
		material: "/src/assets/img/点位.png",  //也可以使用图片填充
		extrudedHeight: 30000
	},
})

​

八、动态实体

// CallbackProperty 生成一个动态实体
let lon, lat,num = 0
const line = viewer.entities.add({
	polyline: {
		// CallbackProperty会产生一个死循环 持续输出Cesium.Cartesian3.fromDegreesArray
		positions: new Cesium.CallbackProperty(() => {
			console.log(1)
			num += 0.005
			lon = 120 + num
			lat = 30 + num
			if (lon < 121) {
				return Cesium.Cartesian3.fromDegreesArray([120, 30, lon, lat])
			} else {
				// 跳不出死循环
				// return Cesium.Cartesian3.fromDegreesArray([
				// 	120, 30, 121, 31,
				// ])

				// 跳出死循环  (给positions赋值一个新的对象,不再需要CallbackProperty提供)
				line.polyline.positions =
					Cesium.Cartesian3.fromDegreesArray([120, 30, 121, 31])
			}
		}, false),
		material: Cesium.Color.YELLOW,
		width: 5,
	},
})

九、加载不同格式的数据dataSource

// 加载geojson格式的线
const linestring = turf.lineString([
 	[-24, 63],
 	[-23, 60],
 	[-25, 65],
 	[-20, 69],
])
const promise = Cesium.GeoJsonDataSource.load(linestring)
console.log(promise)
promise.then((res) => {
 	const entity = res.entities.values[0]
 	viewer.entities.add(entity)
})

// 加载geojson格式的多条线
const multiLine = turf.multiLineString([
 	[
 		[0, 0],
 		[4, 4],
 	],
 	[
 		[6, 6],
 		[10, 10],
 	],
])
const promise = Cesium.GeoJsonDataSource.load(multiLine)
promise.then((res) => {
    data = res
 	viewer.dataSources.add(res)
 	console.log(viewer.dataSources)
})

// 加载geojson格式的多边形
let polygon = turf.polygon([
 	[
		[-5, 52],
		[-4, 56],
 		[-2, 51],
 		[-5, 52],
 	],
])
const promise = Cesium.GeoJsonDataSource.load(polygon)
// 可以不用.then 直接加
viewer.dataSources.add(promise)
viewer.zoomTo(promise)

// 加载topojson格式数据
const promise = Cesium.GeoJsonDataSource.load("/src/assets/usa.topojson")
viewer.dataSources.add(promise)
viewer.zoomTo(promise)

// 加载Kml(kmz)格式的数据
const promise = Cesium.KmlDataSource.load("/src/assets/gdp2008.kmz")
viewer.dataSources.add(promise)
viewer.zoomTo(promise)

// 加载Czml格式的数据
const promise = Cesium.CzmlDataSource.load("/src/assets/Vehicle.czml")
promise.then((res) => {
	viewer.dataSources.add(res)
	let entity = res.entities.getById("Vehicle")
	viewer.trackedEntity = entity // trackedEntity 可以实现一直移动相机跟踪entity目标
})

十、加载3D瓦片的两种方式

1、使用Ion资源加载3DTiles数据:
const tileset1 = viewer.scene.primitives.add(
	new Cesium.Cesium3DTileset({
		url: Cesium.IonResource.fromAssetId(69380), //75343
	})
)

2、加载本地中的3DTiles数据:
const tileset2 = viewer.scene.primitives.add(
	new Cesium.Cesium3DTileset({
		url: '/src/assets/b3dm/tileset.json', //tileset.json是入口文件
	})
)

十一、鼠标点击事件

​
//1、点击地图某个位置添加一个点
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction((event)=>{
	// 获取点击位置的笛卡尔坐标
	let position = viewer.scene.pickPosition(event.position)
	// 如果有这个坐标 则添加一个点
	if(Cesium.defined(position)){
		viewer.entities.add({
			position: position,
			point: {
				color: Cesium.Color.RED,
				pixelSize: 30
			}
		})
	}
},Cesium.ScreenSpaceEventType.LEFT_CLICK)

//2、点击拾取的对象,变为蓝点
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction((event)=>{
	let pick = viewer.scene.pick(event.position)
	if(pick && pick.id){
		pick.id.point.color = Cesium.Color.BLUE
	}
},Cesium.ScreenSpaceEventType.LEFT_CLICK)

​//3、画线
let arr = []
const line = viewer.entities.add({
	polyline: {
		positions: [],
		material: Cesium.Color.YELLOW,
		width: 5,
		clampToGround: true
	}
})

handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction((event)=>{
	let position = viewer.scene.pickPosition(event.position)
	if(Cesium.defined(position)){
		const point = viewer.entities.add({
			position: position,
			name: 'point',
			point: {
				color: Cesium.Color.RED,
				pixelSize: 30
			}
		})
		arr.push(position)
		pointList.push(point)
		line.polyline.positions = arr
	}
}, Cesium.ScreenSpaceEventType.LEFT_CLICK)

handler.setInputAction(()=>{
	// 结束所有事件 且只保留一条线  
	handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK)
	handler.removeInputAction(Cesium.ScreenSpaceEventType.RIGHT_CLICK)
	pointList.forEach((item) => {
		viewer.entities.remove(item)
	})
	pointList = []
},Cesium.ScreenSpaceEventType.RIGHT_CLICK)

十二、鼠标移动事件

// 鼠标移到哪个要素上哪个要素变红
let lastPick
let handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas)
handler.setInputAction((event)=>{
	let pick = viewer.scene.pick(event.endPosition) 
	if(pick){
		if(lastPick){
			lastPick.color = Cesium.Color.WHITE
		}
		pick.color = Cesium.Color.ORANGERED
		lastPick = pick
	}
},Cesium.ScreenSpaceEventType.MOUSE_MOVE)

十三、三维模型

const position = Cesium.Cartesian3.fromDegrees(114,30,300)
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
	position,
	Cesium.HeadingPitchRoll.fromDegrees(0,0,0)
)

const entity = viewer.entities.add({
	position, //位置
	orientation, //方向
	model: {
		uri: '/src/assets/Cesium_Air.glb',
		minimumPixelSize: 200  //模型最小像素
	}
})

十四、粒子效果

//粒子效果
viewer.scene.primitives.add(new Cesium.ParticleSystem({
	image: '/src/assets/img/fire.png',
	imageSize: new Cesium.Cartesian2(20,20), //尺寸
	startScale: 1.0, //初始大小
	endScale: 4.0, //最后大小
	particleLife: 3.0, //设置每一个粒子存在的时间
	speed: 5.0, //发射粒子的速度
	emitter: new Cesium.CircleEmitter(2), //设置发射器(圆形发射器)
	// emitter: new Cesium.BoxEmitter(new Cesium.Cartesian3(10,10,10)),
	emissionRate: 5, //粒子发射数量
	modelMatrix: entity.computeModelMatrix(
		viewer.clock.startTime, //时间空间中的起始时间
		new Cesium.Matrix4() //4*4矩阵数据
	), //设置位置
	lifetime: 16, //生命期属性为所需的持续时间
	// loop: false, //只循环一次
}))

十五、点聚合

let viewer,data
const toDel = () =>{
	viewer.dataSources.remove(data)
}

const pinBuilder = new Cesium.PinBuilder();
  const pin300 = pinBuilder
    .fromText("300+", Cesium.Color.RED, 48)
    .toDataURL();
  const pin100 = pinBuilder
    .fromText("100+", Cesium.Color.ORANGE, 48)
    .toDataURL();
  const pin50 = pinBuilder
    .fromText("50+", Cesium.Color.YELLOW, 48)
    .toDataURL();
  const pin30 = pinBuilder
    .fromText("30+", Cesium.Color.GREEN, 48)
    .toDataURL();
  const pin10 = pinBuilder
    .fromText("10+", Cesium.Color.BLUE, 48)
    .toDataURL();

onMounted(() => {
	Cesium.Ion.defaultAccessToken =
		"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI4NWNkMTZkYy1hY2I5LTQwNDgtYjM5ZC0yNTY5NTc3NDUwMDAiLCJpZCI6MTgxMTUzLCJpYXQiOjE3MDExNDM4ODB9.MT-iAoFv-Ok7r1DIM-zd-8fsrah5iK2wMeNoftoPNig"
	viewer = new Cesium.Viewer("cesiumContainer", {})

	Cesium.GeoJsonDataSource.load('/src/assets/camera.json').then(res => {
		data = res
		res.clustering.enabled = true;
    	res.clustering.pixelRange = 30;
    	res.clustering.minimumClusterSize = 3;
		res.clustering.clusterEvent.addEventListener((clusteredEntities, cluster)=>{
			cluster.billboard.show = true
			cluster.label.show = false
			if (clusteredEntities.length >= 300) {
				cluster.billboard.image = pin300
			} else if (clusteredEntities.length >= 100) {
				cluster.billboard.image = pin100
			} else if (clusteredEntities.length >= 50) {
				cluster.billboard.image = pin50
			} else if (clusteredEntities.length >= 30) {
				cluster.billboard.image = pin30
			} else if (clusteredEntities.length >= 10) {
				cluster.billboard.image = pin10
			}
		})

		viewer.dataSources.add(res)
		res.entities.values.forEach(item=>{
			item.billboard.image = '/src/assets/img/点位.png'
			// item.billboard.scale = 0.15
		})
		viewer.flyTo(res)
	})
})

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值