Cesium 点击绘制圆形(动态绘制圆形)

这里重点说一下:CallbackProperty是一个类,其值由回调函数延迟计算。也就是说它在不断地自我调用,每当其返回的对象有改变时,就会抛出改变后的值。利用这种特性,我们就可以在定义semiMinorAxissemiMajorAxis时,用CallbackProperty生成动态的值赋值给semiMinorAxissemiMajorAxis参数,就可以得到动态绘制圆形的效果。

使用方法:调用 click_draw_circle() 方法就可以

var handler = null;
var circle_center_entity = null;  // 圆心点 entity
var temporary_circle_entity = null;  // 临时圆形entity
var circle_entity = null; // 结果圆形entity
var circle_end_point = null;  // 结束点
var circle_center_point = null;  // 圆心点

function click_draw_circle() {
	// 再次点击的时候,清除已绘制的中心点,临时圆和结果圆,初始化参数
	if (circle_entity !== null) {
		viewer.entities.remove(circle_center_entity);
		viewer.entities.remove(temporary_circle_entity);
		viewer.entities.remove(circle_entity);
		circle_center_entity = null;
		temporary_circle_entity = null;
		circle_entity = null;
		circle_end_point = null;
		circle_center_point = null;
	}

	// 清除所有点击事件
	if (handler) {
		handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
		handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
	}

	handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);

	// 鼠标点击左键
	handler.setInputAction(event => {
		// 屏幕坐标转为世界坐标
		let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.position), viewer.scene);
		let ellipsoid = viewer.scene.globe.ellipsoid;
		let cartographic = ellipsoid.cartesianToCartographic(cartesian);
		let lon = Cesium.Math.toDegrees(cartographic.longitude);	// 经度
		let lat = Cesium.Math.toDegrees(cartographic.latitude);	// 纬度

		// 判断圆心是否已经绘制,如果绘制了,再次点击左键的时候,就是绘制最终结果圆形
		if (circle_center_entity) {
			// 设置最终点
			circle_end_point = {
				lon: lon,
				lat: lat,
				height: 0
			}
			// 绘制结果多边形
			draw_circle();
			// 清除事件
			handler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_CLICK);
			handler.removeInputAction(Cesium.ScreenSpaceEventType.MOUSE_MOVE);
			// 清除 绘制的中心点和临时圆
			viewer.entities.remove(circle_center_entity);
			viewer.entities.remove(temporary_circle_entity);
		} else {
			// 设置中心点坐标和结束点坐标
			circle_end_point = circle_center_point = {
				lon: lon,
				lat: lat,
				height: 0
			}
			// 绘制圆心点
			create_circle_center_point([lon, lat]);
			// 开始绘制动态圆形
			draw_dynamic_circle(circle_center_point);

			// 鼠标移动--实时绘制圆形
			handler.setInputAction((event) => {
				// 屏幕坐标转为世界坐标
				let cartesian = viewer.scene.globe.pick(viewer.camera.getPickRay(event.endPosition), viewer.scene);
				let ellipsoid = viewer.scene.globe.ellipsoid;
				let cartographic = ellipsoid.cartesianToCartographic(cartesian);
				let lon = Cesium.Math.toDegrees(cartographic.longitude);  // 经度
				let lat = Cesium.Math.toDegrees(cartographic.latitude);   // 纬度

				if (temporary_circle_entity) {
					// 修改结束点-用于动态绘制圆形
					circle_end_point = {
						lon: lon,
						lat: lat,
						height: 0
					}
				}
			}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
		}

	}, Cesium.ScreenSpaceEventType.LEFT_CLICK)
}

// 创建圆心点
function create_circle_center_point(point_arr) {
	circle_center_entity = viewer.entities.add({
		// fromDegrees(经度,纬度,高度)以度为单位的经度和纬度值返回Cartesian3位置
		position: Cesium.Cartesian3.fromDegrees(point_arr[0], point_arr[1], 100),
		point: {
			// 点的大小(像素)
			pixelSize: 5,
			// 点位颜色,fromCssColorString 可以直接使用CSS颜色
			color: Cesium.Color.WHITE,
			// 边框颜色
			outlineColor: Cesium.Color.fromCssColorString('#fff'),
			// 边框宽度(像素)
			outlineWidth: 2,
			// 是否显示
			show: true
		}
	});
}

// 绘制动态圆
function draw_dynamic_circle(point) {
	temporary_circle_entity = viewer.entities.add({
		position: Cesium.Cartesian3.fromDegrees(point.lon, point.lat),
		ellipse: {
			// 半短轴(画圆:半短轴和半长轴一致即可)
			semiMinorAxis: new Cesium.CallbackProperty(() => {
				// PolygonHierarchy 定义多边形及其孔的线性环的层次结构(空间坐标数组)
				return two_points_distance(point, circle_end_point);
			}, false),
			// 半长轴
			semiMajorAxis: new Cesium.CallbackProperty(() => {
				// PolygonHierarchy 定义多边形及其孔的线性环的层次结构(空间坐标数组)
				return two_points_distance(point, circle_end_point);
			}, false),
			// 填充色
			material: Cesium.Color.RED.withAlpha(0.5),
			// 是否有边框
			outline: true,
			// 边框颜色
			outlineColor: Cesium.Color.WHITE,
			// 边框宽度
			outlineWidth: 4
		},
	});
}

// 绘制结果圆形
function draw_circle() {
	circle_entity = viewer.entities.add({
		position: Cesium.Cartesian3.fromDegrees(circle_center_point.lon, circle_center_point.lat),
		ellipse: {
			// 半短轴(画圆:半短轴和半长轴一致即可)
			semiMinorAxis: two_points_distance(circle_center_point, circle_end_point),
			// 半长轴
			semiMajorAxis: two_points_distance(circle_center_point, circle_end_point),
			// 填充色
			material: Cesium.Color.RED.withAlpha(0.5),
			// 是否有边框
			outline: true,
			// 边框颜色
			outlineColor: Cesium.Color.WHITE,
			// 边框宽度
			outlineWidth: 4
		},
	});
}

// 根据经纬度计算两点之前的直线距离
function two_points_distance(start_point, end_point) {
	// 经纬度转换为世界坐标
	var start_position = Cesium.Cartesian3.fromDegrees(start_point.lon, start_point.lat, start_point.height);
	var end_position = Cesium.Cartesian3.fromDegrees(end_point.lon, end_point.lat, end_point.height);
	// 返回两个坐标的距离(单位:米)
	return Cesium.Cartesian3.distance(start_position, end_position);
}

绘制中:
在这里插入图片描述

绘制完毕:
在这里插入图片描述

  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值