Cesium手动绘制线段与多边形(官网的方法)

var viewer = new Cesium.Viewer("cesiumContainer", {
	selectionIndicator: false,
	infoBox: false,
	/**
	 * 开启世界图形,防止图形错位
	 * 如果不开启则使用:
	 * 几何图形要依附于模型必须开启depthTestAgainstTerrain
     * viewer.scene.globe.depthTestAgainstTerrain = true
	 * */
	terrainProvider: Cesium.createWorldTerrain(),
  });
  // 防止双击放大球体
  viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(
	Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK
  );
  // 创建一个点
  function createPoint(worldPosition) {
	var point = viewer.entities.add({
	  position: worldPosition,
	  point: {
		color: Cesium.Color.WHITE,
		// 大小
		pixelSize: 5,
		heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
	  },
	});
	return point;
  }
  var drawingMode = "line";
  // 绘制
  function drawShape(positionData) {
	var shape;
	if (drawingMode === "line") {
	  shape = viewer.entities.add({
		  // 线段
		polyline: {
		  positions: positionData,
		  clampToGround: true,
		  width: 3,
		},
	  });
	} else if (drawingMode === "polygon") {
	  // 多边形
	  shape = viewer.entities.add({
		polygon: {
		  hierarchy: positionData,
		  material: new Cesium.ColorMaterialProperty(
			Cesium.Color.WHITE.withAlpha(0.7)
		  ),
		},
	  });
	}
	return shape;
  }
  // 所有活动点的实体
  var activeShapePoints = [];
  // 绘制图形
  var activeShape;
  // 第一个活动点
  var floatingPoint;
  // 创建鼠标事件
  var handler = new Cesium.ScreenSpaceEventHandler(viewer.canvas);
  handler.setInputAction(function (event) {
	// 获取鼠标当前位置 viewer.scene.pickPosition 将位置转化为笛卡尔单位
	var earthPosition = viewer.scene.pickPosition(event.position);
	if (Cesium.defined(earthPosition)) {
	  if (activeShapePoints.length === 0) {
		// 创建第一个点
		floatingPoint = createPoint(earthPosition);
		activeShapePoints.push(earthPosition);
		// 最重要的一步,绘制过程中图形会动态跟着鼠标移动
		// CallbackProperty返回一个回调函数 当activeShapePoints改变时会触发
		// 不管activeShapePoints是增加还是删除都会动态改变图形的形状
		// 在绘制结束必须重置activeShapePoints = [] 不然 CallbackProperty 一直处于回调中,严重消耗性能
		var dynamicPositions = new Cesium.CallbackProperty(function () {
		  if (drawingMode === "polygon") {
			// 多边形的position需要用 PolygonHierarchy进行转化
			return new Cesium.PolygonHierarchy(activeShapePoints);
		  }
		  return activeShapePoints;
		}, false);
		activeShape = drawShape(dynamicPositions);
	  }
	  activeShapePoints.push(earthPosition);
	  createPoint(earthPosition);
	}
	// 鼠标左键点击事件 LEFT_CLICK
  }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
  
  handler.setInputAction(function (event) {
	  // 判断是否存在
	if (Cesium.defined(floatingPoint)) {
	  var newPosition = viewer.scene.pickPosition(event.endPosition);
	  if (Cesium.defined(newPosition)) {
		// 动态改变活动点的位置与鼠标当前位置保持一致
		floatingPoint.position.setValue(newPosition);
		activeShapePoints.pop();
		activeShapePoints.push(newPosition);
	  }
	}
	// 鼠标左键移动事件 MOUSE_MOVE
  }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  // 重新绘制形状,使其不是动态的,然后删除动态形状.
  function terminateShape() {
	// 删除最后一个点
	activeShapePoints.pop();
	// 绘制完整的图形
	drawShape(activeShapePoints);
	// 删除创建的第一个点和处于活动状态的实体
	viewer.entities.remove(floatingPoint);
	viewer.entities.remove(activeShape);
	// 格式化
	floatingPoint = undefined;
	activeShape = undefined;
	activeShapePoints = [];
  }
  // 结束绘制
  handler.setInputAction(function (event) {
	terminateShape();
	// 鼠标右键点击事件 RIGHT_CLICK
  }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

  // Sandcastle 百度解决,不用也行,只是在cesium上挂载组件
  var options = [
	{
	  text: "Draw Lines",
	  onselect: function () {
		if (!Cesium.Entity.supportsPolylinesOnTerrain(viewer.scene)) {
		  window.alert(
			"This browser does not support polylines on terrain."
		  );
		}
  
		terminateShape();
		drawingMode = "line";
	  },
	},
	{
	  text: "Draw Polygons",
	  onselect: function () {
		terminateShape();
		drawingMode = "polygon";
	  },
	},
  ];
  
  Sandcastle.addToolbarMenu(options);
  // Zoom in to an area with mountains
  viewer.camera.lookAt(
	Cesium.Cartesian3.fromDegrees(-122.2058, 46.1955, 1000.0),
	new Cesium.Cartesian3(5000.0, 5000.0, 5000.0)
  );
  viewer.camera.lookAtTransform(Cesium.Matrix4.IDENTITY);
  

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值