// DrawSector /* 九、绘制扇形 */ class DrawSector { constructor(arg) { this.viewer = arg.viewer; this.Cesium = arg.Cesium; this.floatingPoint = null;//标识点 this._sector = null; //活动扇形 this._sectorLast = null; //最后一个扇形 this._positions = []; //活动点 this._entities_point = []; //脏数据 this._entities_sector = []; //脏数据 this._sectorData = null; //用于构造扇形数据 this.DrawStartEvent = new Cesium.Event(); //开始绘制事件 this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 /* 通用参数集合 */ this._param = { id: "DrawStraightArrow", polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色 outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色 outlineWidth: 1, //边框宽度 } /* 创建面材质 */ this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor); /* 创建线材质 */ // this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线 // dashLength: 16, // color: Cesium.Color.fromCssColorString(this._param.outlineColor) // }); this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor); } //返回扇形 get sector() { return this._sectorLast; } //返回扇形数据用于加载扇形 getData() { return this._sectorData; } // 修改编辑调用计算 computePosition(data){ let $this = this; let pnts = data; let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0])); let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1])); let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2])); var radius = $this.MathDistance(pnt2, center); var startAngle = $this.getAzimuth(pnt2, center); var endAngle = $this.getAzimuth(pnt3, center); var pList = $this.getArcPoints(center, radius, startAngle, endAngle); pList.push(pnts[0], pList[0]); let arrow = []; for (var i = 0; i < pList.length; i++) { var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z); arrow.push(cart3); } var lnglatArr = []; for (var d = 0; d < data.length; d++){ lnglatArr.push($this.cartesianToLatlng(data[d])) } $this._sectorData = lnglatArr; return new $this.Cesium.PolygonHierarchy(arrow) } //加载扇形 addload(data) { var $this = this; let pnts = data; let center = $this.lonLatToMercator(pnts[0]); let pnt2 = $this.lonLatToMercator(pnts[1]); let pnt3 = $this.lonLatToMercator(pnts[2]); var radius = $this.MathDistance(pnt2, center); var startAngle = $this.getAzimuth(pnt2, center); var endAngle = $this.getAzimuth(pnt3, center); var pList = $this.getArcPoints(center, radius, startAngle, endAngle); let pntsc = $this.Cesium.Cartesian3.fromDegrees(pnts[0][0], pnts[0][1]) pList.push(pntsc, pList[0]); let arrow = []; for (var i = 0; i < pList.length; i++) { var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z); arrow.push(cart3); } var arrowEntity = $this.viewer.entities.add({ Type: 'DrawSector', Position: data, id: data.id || $this.objId, polygon: { hierarchy: new $this.Cesium.PolygonHierarchy(arrow), show: true, fill: true, clampToGround: true, material: $this.Cesium.Color.AQUA.withAlpha(0.9) } }); return arrowEntity; } //开始创建 startCreate() { var $this = this; this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas); this.handler.setInputAction(function (evt) { //单机开始绘制 //屏幕坐标转地形上坐标 var cartesian = $this.getCatesian3FromPX(evt.position); // if($this._positions.length == 3) return if ($this._positions.length < 3) { $this.floatingPoint = $this.createPoint(cartesian); $this._positions.push(cartesian); } if (!$this._sector) { // $this.createPoint(cartesian);// 绘制点 } }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK); this.handler.setInputAction(function (evt) { //移动时绘制面 if ($this._positions.length < 2) return; var cartesian = $this.getCatesian3FromPX(evt.endPosition); if ($this._positions.length == 2) { $this._positions.push(cartesian); } if ($this._positions.length == 3) { $this._positions.pop(); $this._positions.push(cartesian); if (!$this.Cesium.defined($this._sector)) { $this._sector = $this.createsector(); } } }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE); this.handler.setInputAction(function (evt) { if (!$this._sector) return; var cartesian = $this.getCatesian3FromPX(evt.position); $this._positions.pop(); $this._positions.push(cartesian); $this._sectorData = $this._positions.concat(); $this.viewer.entities.remove($this._sector); //移除 $this._sector = null; $this._positions = []; $this.floatingPoint.position.setValue(cartesian); var lnglatArr = []; for (var i = 0; i < $this._sectorData.length; i++) { var lnglat = $this.cartesianToLatlng($this._sectorData[i]); lnglatArr.push(lnglat) } $this._sectorData = lnglatArr; var sector = $this.addload(lnglatArr); //加载 $this._entities_sector.push(sector); $this._sectorLast = sector; $this.clearPoint(); $this.destroy() }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK); } //创建直线扇形 createsector() { // console.log(this._positions) var $this = this; var arrowEntity = $this.viewer.entities.add({ polygon: { hierarchy: new $this.Cesium.CallbackProperty( function () { // if(this._positions.length < 3) return let pnts = $this._positions; let center = $this.lonLatToMercator($this.cartesianToLatlng(pnts[0])); let pnt2 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[1])); let pnt3 = $this.lonLatToMercator($this.cartesianToLatlng(pnts[2])); var radius = $this.MathDistance(pnt2, center); var startAngle = $this.getAzimuth(pnt2, center); var endAngle = $this.getAzimuth(pnt3, center); var pList = $this.getArcPoints(center, radius, startAngle, endAngle); pList.push(pnts[0], pList[0]); let arrow = []; for (var i = 0; i < pList.length; i++) { var cart3 = new $this.Cesium.Cartesian3(pList[i].x, pList[i].y, pList[i].z); arrow.push(cart3); } return new $this.Cesium.PolygonHierarchy(pList); }, false), show: true, fill: true, clampToGround: true, material: $this.Cesium.Color.AQUA.withAlpha(0.5) } } ) $this._entities_sector.push(arrowEntity); return arrowEntity } //创建点 createPoint(cartesian) { var $this = this; var point = this.viewer.entities.add({ position: cartesian, point: { pixelSize: 10, color: $this.Cesium.Color.RED, heightReference: Cesium.HeightReference.CLAMP_TO_GROUND, } }); $this._entities_point.push(point); return point; } cartesianToLatlng(cartesian) { var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); var lat = this.Cesium.Math.toDegrees(latlng.latitude); var lng = this.Cesium.Math.toDegrees(latlng.longitude); return [lng, lat]; } /** * 经纬度坐标转墨卡托坐标 */ // 墨卡托坐标系:展开地球,赤道作为x轴,向东为x轴正方,本初子午线作为y轴,向北为y轴正方向。 // 数字20037508.34是地球赤道周长的一半:地球半径6378137米,赤道周长2*PI*r = 2 * 20037508.3427892,墨卡托坐标x轴区间[-20037508.3427892,20037508.3427892] lonLatToMercator(Latlng) { var E = Latlng[0]; var N = Latlng[1]; var x = E * 20037508.34 / 180; var y = Math.log(Math.tan((90 + N) * Math.PI / 360)) / (Math.PI / 180); y = y * 20037508.34 / 180; return [x, y] } WebMercator2lonLat(mercator) { let x = mercator[0] / 20037508.34 * 180; let ly = mercator[1] / 20037508.34 * 180; let y = 180 / Math.PI * (2 * Math.atan(Math.exp(ly * Math.PI / 180)) - Math.PI / 2) return [x, y]; } //销毁 destroy() { if (this.handler) { this.handler.destroy(); this.handler = null; } } clearPoint() { this.DrawEndEvent.raiseEvent(this._sectorLast, this._sectorData); for (var i = 0; i < this._entities_point.length; i++) { this.viewer.entities.remove(this._entities_point[i]); } this._entities_point = []; //脏数据 } //清空实体对象 clear() { for (var i = 0; i < this._entities_point.length; i++) { this.viewer.entities.remove(this._entities_point[i]); } for (var i = 0; i < this._entities_sector.length; i++) { this.viewer.entities.remove(this._entities_sector[i]); } this.floatingPoint = null;//标识点 this._sector = null; //活动扇形 this._sectorLast = null; //最后一个扇形 this._positions = []; //活动点 this._entities_point = []; //脏数据 this._entities_sector = []; //脏数据 this._sectorData = null; //用于构造扇形数据 } getCatesian3FromPX(px) { var cartesian; var ray = this.viewer.camera.getPickRay(px); if (!ray) return null; cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene); return cartesian; } // 求取扇形坐标函数/ //扇形配置函数 MathDistance(pnt1, pnt2) { return Math.sqrt(Math.pow(pnt1[0] - pnt2[0], 2) + Math.pow(pnt1[1] - pnt2[1], 2)); } getAzimuth(startPoint, endPoint) { var azimuth; var angle = Math.asin(Math.abs(endPoint[1] - startPoint[1]) / this.MathDistance(startPoint, endPoint)); if (endPoint[1] >= startPoint[1] && endPoint[0] >= startPoint[0]) { azimuth = angle + Math.PI; } else if (endPoint[1] >= startPoint[1] && endPoint[0] < startPoint[0]) { azimuth = Math.PI * 2 - angle; } else if (endPoint[1] < startPoint[1] && endPoint[0] < startPoint[0]) { azimuth = angle; } else if (endPoint[1] < startPoint[1] && endPoint[0] >= startPoint[0]) { azimuth = Math.PI - angle; } return azimuth; } getArcPoints(center, radius, startAngle, endAngle) { var x = null, y = null, z = null, pnts = [], angleDiff = endAngle - startAngle; angleDiff = angleDiff < 0 ? angleDiff + Math.PI * 2 : angleDiff; for (var i = 0; i <= 100; i++) { var angle = startAngle + angleDiff * i / 100; x = center[0] + radius * Math.cos(angle); y = center[1] + radius * Math.sin(angle); let latlon = this.WebMercator2lonLat([x, y]) pnts.push(this.Cesium.Cartesian3.fromDegrees(latlon[0], latlon[1])); } return pnts; } } export default DrawSector