import { createTooltip } from "../../../common/common.js"; import { isRuntimeApp, isRuntimeWeb, createOperationMainDom, showTooltipMessage } from "../../../common/RuntimeEnvironment.js"; /* 九、绘制集结地 */ class DrawGatheringPlace { constructor(arg) { this.viewer = arg.viewer; this.Cesium = arg.Cesium; this.tt = 0.4; this.floatingPoint = null; //标识点 this.drawHandler = null; //画事件 this.gatheringPlace = null; //集结地 this._gatheringPlaceLast = null; //最后一个箭头 this._positions = []; //活动点 this._entities_point = []; //脏数据 this._entities_PincerArrow = []; //脏数据 this._gatheringPlaceData = null; //用于构造集结地 this.DrawStartEvent = new Cesium.Event(); //开始绘制事件 this.DrawEndEvent = new Cesium.Event(); //结束绘制事件 this._tooltip = createTooltip(this.viewer.container); /* 通用参数集合 */ 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 PincerArrow() { return this._gatheringPlaceLast; } //返回箭头数据用于加载箭头 getData() { return this._gatheringPlaceData; } // 修改编辑调用计算 computePosition(data) { var $this = this; if (data.length < 3) { return; } var gatheringPlace = []; var lonLats = []; var res = $this.fineGatheringPlace(data); for (var i = 0; i < res.length; i++) { var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z); gatheringPlace.push(cart3); } for (let q = 0; q < data.length; q++) { lonLats.push($this.cartesianToLatlng(data[q])); } this._gatheringPlaceData = lonLats; return new $this.Cesium.PolygonHierarchy(gatheringPlace); } //加载箭头 addload(data) { var $this = this; if (data.length < 3) { return; } var gatheringPlace = []; var lnglatArr = []; for (var i = 0; i < data.length; i++) { var lnglat = $this.LatlngTocartesian(data[i]); lnglatArr.push(lnglat) } var res = $this.fineGatheringPlace(lnglatArr); for (var i = 0; i < res.length; i++) { var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z); gatheringPlace.push(cart3); } var pHierarchy = new $this.Cesium.PolygonHierarchy(gatheringPlace); var arrowEntity = $this.viewer.entities.add({ Type: 'DrawGatheringPlace', Position: data, id: data.id || $this.objId, polygon: { hierarchy: pHierarchy, show: true, fill: true, clampToGround: true, material: $this.polygonMaterial } }) return arrowEntity } // 开始创建 startCreate(drawType) { if (isRuntimeApp()) { showTooltipMessage("点击开始绘制"); } var $this = this; this.drawType = drawType this.handler = new $this.Cesium.ScreenSpaceEventHandler($this.viewer.scene.canvas); //单击开始绘制 this.handler.setInputAction(function(event) { if (isRuntimeApp()) { //屏幕坐标转地形上坐标 var cartesian = $this.getCatesian3FromPX(event.position); if (!cartesian) { return; } $this.createPoint(cartesian); // 绘制点 $this._positions.push(cartesian); if ($this._positions.length < 3) { showTooltipMessage("点击添加点"); } if ($this._positions.length === 3) { showTooltipMessage("点击完成按钮,结束绘制"); $this.destroy(); if (!$this.Cesium.defined($this.gatheringPlace)) { $this.gatheringPlace = $this.createGatheringPlace(); //创建按钮 createOperationMainDom(); //隐藏回退按钮 document.getElementById("btnDrawBackout").style.display = 'none'; //完成绘制 document.getElementById("btnDrawComplete").onclick = () => { $this._gatheringPlaceData = $this._positions.concat(); $this.viewer.entities.remove($this.gatheringPlace); //移除 $this.gatheringPlace = null; var lnglatArr = []; for (var i = 0; i < $this._gatheringPlaceData.length; i++) { var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]); lnglatArr.push(lnglat) } $this._gatheringPlaceData = lnglatArr; var pincerArrow = $this.addload(lnglatArr); //加载 $this._entities_PincerArrow.push(pincerArrow); $this._gatheringPlaceLast = pincerArrow; $this.viewer.entities.remove($this.floatingPoint); $this.floatingPoint = null; //删除关键点 $this.clearPoint(); $this.destroy(); let buttonDiv = document.getElementById("drawButtonDiv"); if (buttonDiv) { //从页面移除 document.body.removeChild(buttonDiv); } } } } } else { console.log('监听鼠标事件', '单击') /* 锁定点击事件 以免和双击事件冲突 */ clearTimeout($this._timer); $this._timer = setTimeout(function() { //屏幕坐标转世界坐标 var position = event.position; if (!$this.Cesium.defined(position)) { return; } var ray = $this.viewer.camera.getPickRay(position); if (!$this.Cesium.defined(ray)) { return; } var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene); if (!$this.Cesium.defined(cartesian)) { return; } if ($this._positions.length == 0) { $this._positions.push(cartesian.clone()); $this.floatingPoint = $this.createPoint(cartesian); } if ($this._positions.length <= 2) { $this.createPoint(cartesian); // 绘制点 $this._positions.push(cartesian); } }, 200); } }, Cesium.ScreenSpaceEventType.LEFT_CLICK); //移动时绘制面 this.handler.setInputAction(function(event) { //console.log("_positions",_positions); /* 如果运行环境是App 则禁止使用鼠标移动事件 */ if (isRuntimeApp()) return; if ($this._positions.length == 0) { $this._tooltip.showAt(event.endPosition, "点击开始绘制"); } else { $this._tooltip.showAt(event.endPosition, "点击添加点"); } if ($this._positions.length < 2) { return; } if ($this._positions.length == 3) { $this._tooltip.showAt(event.endPosition, "双击结束绘制"); } //屏幕坐标转世界坐标 var position = event.endPosition; if (!$this.Cesium.defined(position)) { return; } var ray = $this.viewer.camera.getPickRay(position); if (!$this.Cesium.defined(ray)) { return; } var cartesian = $this.viewer.scene.globe.pick(ray, $this.viewer.scene); if (!$this.Cesium.defined(cartesian)) { return; } //console.log("点击地图移动采集的点:",cartesian); if (!$this.Cesium.defined($this.gatheringPlace)) { $this.gatheringPlace = $this.createGatheringPlace(); } $this.floatingPoint.position.setValue(cartesian); if ($this.gatheringPlace) { //替换最后一个点 // _positions.pop(); // _positions.push(cartesian); //替换中间点 if ($this._positions.length == 3) { $this._positions[1] = cartesian; } else { $this._positions.pop(); $this._positions.push(cartesian); } } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); //右击停止采集改为双击结束 this.handler.setInputAction(function(movement) { // if ($this._positions.length >= 3) { // $this._gatheringPlaceData = $this._positions.concat(); // $this.viewer.entities.remove($this.gatheringPlace); //移除 // $this.gatheringPlace = null; // var lnglatArr = []; // for (var i = 0; i < $this._gatheringPlaceData.length; i++) { // var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]); // lnglatArr.push(lnglat) // } // $this._gatheringPlaceData = lnglatArr; // var pincerArrow = $this.addload(lnglatArr); //加载 // $this._entities_PincerArrow.push(pincerArrow); // $this._gatheringPlaceLast = pincerArrow; // $this.viewer.entities.remove($this.floatingPoint); // $this.floatingPoint = null; // //删除关键点 // $this.clearPoint(); // $this.destroy() // } }, Cesium.ScreenSpaceEventType.RIGHT_CLICK); //双击结束 this.handler.setInputAction(function(movement) { /* 如果运行环境是App 则禁止使用鼠标双击事件 */ if (isRuntimeApp()) return; console.log('监听鼠标事件', '双击') /* 解除锁定 */ clearTimeout($this._timer); if ($this._positions.length >= 3) { $this._gatheringPlaceData = $this._positions.concat(); $this.viewer.entities.remove($this.gatheringPlace); //移除 $this.gatheringPlace = null; var lnglatArr = []; for (var i = 0; i < $this._gatheringPlaceData.length; i++) { var lnglat = $this.cartesianToLatlng($this._gatheringPlaceData[i]); lnglatArr.push(lnglat) } $this._gatheringPlaceData = lnglatArr; var pincerArrow = $this.addload(lnglatArr); //加载 $this._entities_PincerArrow.push(pincerArrow); $this._gatheringPlaceLast = pincerArrow; $this.viewer.entities.remove($this.floatingPoint); $this.floatingPoint = null; //删除关键点 $this.clearPoint(); $this.destroy(); $this._tooltip.setVisible(false); } }, Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); } //创建集结地 createGatheringPlace() { let $this = this var gatheringPlaceEntity = $this.viewer.entities.add({ polygon: { hierarchy: new $this.Cesium.CallbackProperty(function() { if ($this._positions.length < 3) { return; } var gatheringPlace = []; var res = $this.fineGatheringPlace($this._positions); for (var i = 0; i < res.length; i++) { var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z); gatheringPlace.push(cart3); } var pHierarchy = new $this.Cesium.PolygonHierarchy(gatheringPlace); var lonLats = $this.cartesianToLatlng($this._positions); pHierarchy.keyPoints = lonLats; return pHierarchy }, false), show: true, fill: true, clampToGround: true, material: $this.polygonMaterial } }) //$this._entities_gatheringPlace.push(gatheringPlaceEntity); // gatheringPlaceEntity.valueFlag = "value"; $this._entities_PincerArrow.push(gatheringPlaceEntity); return gatheringPlaceEntity } //创建点 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) { let cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); let lat = this.Cesium.Math.toDegrees(cartographic.latitude); let lng = this.Cesium.Math.toDegrees(cartographic.longitude); let alt = cartographic.height; return [lng, lat, alt]; } //销毁 destroy() { if (this.handler) { this.handler.destroy(); this.handler = null; } } clearPoint() { this.DrawEndEvent.raiseEvent(this._gatheringPlaceLast, this._gatheringPlaceData, this.drawType); 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_PincerArrow.length; i++) { this.viewer.entities.remove(this._entities_PincerArrow[i]); } this.floatingPoint = null; //标识点 this._PincerArrow = null; //活动箭头 this._PincerArrowLast = null; //最后一个箭头 this._positions = []; //活动点 this._entities_point = []; //脏数据 this._entities_PincerArrow = []; //脏数据 this._PincerArrowData = 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; } _computeTempPositions() { var _this = this; var pnts = [].concat(_this._positions); var num = pnts.length; var first = pnts[0]; var last = pnts[num - 1]; if (_this._isSimpleXYZ(first, last) == false) { pnts.push(first); num += 1; } _this.tempPositions = []; for (var i = 1; i < num; i++) { var p1 = pnts[i - 1]; var p2 = pnts[i]; var cp = _this._computeCenterPotition(p1, p2); _this.tempPositions.push(p1); _this.tempPositions.push(cp); } } _isSimpleXYZ(p1, p2) { if (p1.x == p2.x && p1.y == p2.y && p1.z == p2.z) { return true; } return false; } _computeCenterPotition(p1, p2) { var _this = this; var c1 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p1); var c2 = _this.viewer.scene.globe.ellipsoid.cartesianToCartographic(p2); var cm = new _this.Cesium.EllipsoidGeodesic(c1, c2).interpolateUsingFraction(0.5); var cp = _this.viewer.scene.globe.ellipsoid.cartographicToCartesian(cm); return cp; } /** * 笛卡尔坐标转经纬度坐标 */ getLonLat(cartesian) { var cartographic = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian); cartographic.height = this.viewer.scene.globe.getHeight(cartographic); var pos = { lon: cartographic.longitude, lat: cartographic.latitude, alt: cartographic.height }; pos.lon = this.Cesium.Math.toDegrees(pos.lon); pos.lat = this.Cesium.Math.toDegrees(pos.lat); return pos; } LatlngTocartesian(latlng) { let cartesian3 = this.Cesium.Cartesian3.fromDegrees(latlng[0], latlng[1]); return cartesian3 } ////////////////////////////////////////集结地///////////////////////////////////////////////////// fineGatheringPlace(gatherPosition) { let $this = this let points = gatherPosition.length; if (points < 2) { return false } else { let pnts = new Array(); gatherPosition.forEach(function(item) { var posLonLat = $this.getLonLat(item); pnts.push([posLonLat.lon, posLonLat.lat]); }); //console.log("pnts6666",pnts); // pnts.push(tailPoint); // pnts.push(headerPoint); if (pnts.length === 2) { let mid = $this.mid(pnts[0], pnts[1]) //let d = utils.MathDistance(pnts[0], mid) / 0.9 let d = $this.distance(pnts[0], mid) / 0.9 //console.log("d",d); let pnt = $this.getThirdPoint(pnts[0], mid, Math.PI / 2, d, true) pnts = [pnts[0], pnt, pnts[1]]; //console.log("pnt",pnt); //createPoint(Cesium.Cartesian3.fromDegrees(pnt[0], pnt[1])); } let mid = $this.mid(pnts[0], pnts[2]) pnts.push(mid, pnts[0], pnts[1]) //console.log("3333"); let [normals, pnt1, pnt2, pnt3, pList] = [ [], undefined, undefined, undefined, [] ] for (let i = 0; i < pnts.length - 2; i++) { pnt1 = pnts[i] pnt2 = pnts[i + 1] pnt3 = pnts[i + 2] let normalPoints = $this.getBisectorNormals($this.tt, pnt1, pnt2, pnt3) normals = normals.concat(normalPoints) } let count = normals.length normals = [normals[count - 1]].concat(normals.slice(0, count - 1)) for (let i = 0; i < pnts.length - 2; i++) { pnt1 = pnts[i] pnt2 = pnts[i + 1] pList = pList.concat(pnt1) for (let t = 0; t <= 100; t++) { let pnt = $this.getCubicValue(t / 100, pnt1, normals[i * 2], normals[i * 2 + 1], pnt2) pList = pList.concat(pnt) } pList = pList.concat(pnt2) } return Cesium.Cartesian3.fromDegreesArray(pList); } } mid(t, o) { return [(t[0] + o[0]) / 2, (t[1] + o[1]) / 2] } distance(t, o) { return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2)) } getThirdPoint(t, o, e, r, n) { var g = this.getAzimuth(t, o), i = n ? g + e : g - e, s = r * Math.cos(i), a = r * Math.sin(i); return [o[0] + s, o[1] + a] } getAzimuth(t, o) { var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o)); return o[1] >= t[1] && o[0] >= t[0] ? e = r + Math.PI : o[1] >= t[1] && o[0] < t[0] ? e = 2 * Math.PI - r : o[1] < t[1] && o[0] < t[0] ? e = r : o[1] < t[1] && o[0] >= t[0] && (e = Math.PI - r), e } getBisectorNormals(t, o, e, r) { var n = this.getNormal(o, e, r), g = Math.sqrt(n[0] * n[0] + n[1] * n[1]), i = n[0] / g, s = n[1] / g, a = this.distance(o, e), l = this.distance(e, r); if (g > 1e-4) if (this.isClockWise(o, e, r)) { var u = t * a, c = e[0] - u * s, p = e[1] + u * i, h = [c, p]; u = t * l, c = e[0] + u * s, p = e[1] - u * i; var d = [c, p] } else u = t * a, c = e[0] + u * s, p = e[1] - u * i, h = [c, p], u = t * l, c = e[0] - u * s, p = e[1] + u * i, d = [c, p]; else c = e[0] + t * (o[0] - e[0]), p = e[1] + t * (o[1] - e[1]), h = [c, p], c = e[0] + t * (r[0] - e[0]), p = e[1] + t * (r[1] - e[1]), d = [c, p]; return [h, d] } getNormal(t, o, e) { var r = t[0] - o[0], n = t[1] - o[1], g = Math.sqrt(r * r + n * n); r /= g, n /= g; var i = e[0] - o[0], s = e[1] - o[1], a = Math.sqrt(i * i + s * s); i /= a, s /= a; var l = r + i, u = n + s; return [l, u] } isClockWise(t, o, e) { return (e[1] - t[1]) * (o[0] - t[0]) > (o[1] - t[1]) * (e[0] - t[0]) } getCubicValue(t, o, e, r, n) { t = Math.max(Math.min(t, 1), 0); var g = 1 - t, i = t * t, s = i * t, a = g * g, l = a * g, u = l * o[0] + 3 * a * t * e[0] + 3 * g * i * r[0] + s * n[0], c = l * o[1] + 3 * a * t * e[1] + 3 * g * i * r[1] + s * n[1]; return [u, c] } } export default DrawGatheringPlace