123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576 |
- import {
- createTooltip
- } from "../../../common/common.js";
- import {
- isRuntimeApp,
- isRuntimeWeb,
- createOperationMainDom,
- showTooltipMessage
- } from "../../../common/RuntimeEnvironment.js";
- /*
- 七、绘制攻击箭头
- */
- class DrawAttackArrow {
- constructor(arg) {
- //设置唯一id 备用
- this.objId = Number((new Date()).getTime() + "" + Number(Math.random() * 1000).toFixed(0));
- this.viewer = arg.viewer;
- this.Cesium = arg.Cesium;
- // this.callback=arg.callback;
- this.floatingPoint = null; //标识点
- this._AttackArrow = null; //活动箭头
- this._AttackArrowLast = null; //最后一个箭头
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_AttackArrow = []; //脏数据
- this._AttackArrowData = 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 AttackArrow() {
- return this._AttackArrowLast;
- }
- //返回箭头数据用于加载箭头
- getData() {
- return this._AttackArrowData;
- }
- //加载箭头
- addload(data) {
- var $this = this;
- if (data.length < 3) {
- return null;
- }
- var res = $this.fineArrow(data);
- var returnData = res.polygonalPoint;
- var arrowEntity = $this.viewer.entities.add({
- Type: 'DrawAttackArrow',
- Position: data,
- id: data.id || $this.objId,
- polygon: {
- hierarchy: new $this.Cesium.PolygonHierarchy(returnData),
- show: true,
- fill: true,
- clampToGround: true,
- material: $this.polygonMaterial
- }
- });
- return arrowEntity
- }
- // 修改编辑调用计算
- computePosition(data) {
- //计算面
- let $this = this
- var lnglatArr = [];
- for (var i = 0; i < data.length; i++) {
- var lnglat = $this.cartesianToLatlng(data[i]);
- lnglatArr.push(lnglat)
- }
- $this._AttackArrowData = lnglatArr;
- var res = $this.fineArrow(lnglatArr);
- var returnData = res.polygonalPoint;
- return new $this.Cesium.PolygonHierarchy(returnData)
- }
- //开始创建
- 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(evt) {
- if (isRuntimeApp()) {
- //屏幕坐标转地形上坐标
- var cartesian = $this.getCatesian3FromPX(evt.position);
- if (!cartesian) {
- return;
- }
- $this.createPoint(cartesian); // 绘制点
- $this._positions.push(cartesian);
- if ($this._positions.length <= 2) {
- showTooltipMessage("点击添加点");
- } else {
- showTooltipMessage("点击添加点,点击完成按钮,结束绘制");
- if ($this._positions.length === 3) {
- if (!$this.Cesium.defined($this._AttackArrow)) {
- $this._AttackArrow = $this.createAttackArrow();
- //创建按钮
- createOperationMainDom();
- //隐藏回退按钮
- document.getElementById("btnDrawBackout").style.display = 'none';
- //完成绘制
- document.getElementById("btnDrawComplete").onclick = () => {
- $this._AttackArrowData = $this._positions.concat();
- $this.viewer.entities.remove($this._AttackArrow); //移除
- $this._AttackArrow = null;
- $this._positions = [];
- let lnglatArr = [];
- for (var i = 0; i < $this._AttackArrowData.length; i++) {
- var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
- lnglatArr.push(lnglat)
- }
- $this._AttackArrowData = lnglatArr;
- var straightArrow = $this.addload(lnglatArr); //加载
- $this._entities_AttackArrow.push(straightArrow);
- $this._AttackArrowLast = straightArrow;
- $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 cartesian = $this.getCatesian3FromPX(evt.position);
- if (!cartesian) {
- return;
- }
- if ($this._positions.length == 0) {
- // $this._positions.push(cartesian.clone());
- $this.floatingPoint = $this.createPoint(cartesian);
- $this.createPoint(cartesian); // 绘制点
- }
- if ($this._positions.length == 1) {
- $this._positions.push(cartesian.clone());
- $this.createPoint(cartesian); // 绘制点
- }
- $this._positions.push(cartesian);
- }, 200);
- }
- }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
- //移动时绘制面
- this.handler.setInputAction(function(evt) {
- /* 如果运行环境是App 则禁止使用鼠标移动事件 */
- if (isRuntimeApp()) return;
- // console.log('监听鼠标事件', '移动')
- if ($this._positions.length == 0) {
- $this._tooltip.showAt(evt.endPosition, "点击开始绘制");
- } else {
- $this._tooltip.showAt(evt.endPosition, "点击添加点");
- }
- if ($this._positions.length < 3) return;
- // $this._tooltip.showAt(evt.endPosition, "点击添加点,右键删除点,双击结束绘制");
- $this._tooltip.showAt(evt.endPosition, "点击添加点,双击结束绘制");
- if (!$this.Cesium.defined($this._AttackArrow)) {
- $this._AttackArrow = $this.createAttackArrow();
- }
- var cartesian = $this.getCatesian3FromPX(evt.endPosition);
- if (!cartesian) {
- return;
- }
- $this.floatingPoint.position.setValue(cartesian);
- if ($this._AttackArrow) {
- $this._positions.pop();
- $this._positions.push(cartesian);
- }
- }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
- //右键结束改为双击结束
- this.handler.setInputAction(function(evt) {
- // var cartesian = $this.getCatesian3FromPX(evt.position);
- // $this._positions.pop();
- // // $this._positions.push(cartesian);
- // $this._AttackArrowData = $this._positions.concat();
- // $this.viewer.entities.remove($this._AttackArrow); //移除
- // $this._AttackArrow = null;
- // $this._positions = [];
- // $this.floatingPoint.position.setValue(cartesian);
- // let lnglatArr = [];
- // for (var i = 0; i < $this._AttackArrowData.length; i++) {
- // var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
- // lnglatArr.push(lnglat)
- // }
- // $this._AttackArrowData = lnglatArr;
- // var straightArrow = $this.addload(lnglatArr); //加载
- // $this._entities_AttackArrow.push(straightArrow);
- // $this._AttackArrowLast = straightArrow;
- // $this.clearPoint();
- // $this.destroy()
- }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
- //双击结束
- this.handler.setInputAction(function(evt) {
- /* 如果运行环境是App 则禁止使用鼠标双击事件 */
- if (isRuntimeApp()) return;
- console.log('监听鼠标事件', '双击')
- /* 解除锁定 */
- clearTimeout($this._timer);
- var cartesian = $this.getCatesian3FromPX(evt.position);
- $this._positions.pop();
- $this._positions.push(cartesian);
- $this._AttackArrowData = $this._positions.concat();
- $this.viewer.entities.remove($this._AttackArrow); //移除
- $this._AttackArrow = null;
- $this._positions = [];
- $this.floatingPoint.position.setValue(cartesian);
- let lnglatArr = [];
- for (var i = 0; i < $this._AttackArrowData.length; i++) {
- var lnglat = $this.cartesianToLatlng($this._AttackArrowData[i]);
- lnglatArr.push(lnglat)
- }
- $this._AttackArrowData = lnglatArr;
- var straightArrow = $this.addload(lnglatArr); //加载
- $this._entities_AttackArrow.push(straightArrow);
- $this._AttackArrowLast = straightArrow;
- $this.clearPoint();
- $this.destroy();
- $this._tooltip.setVisible(false);
- }, $this.Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
- }
- //创建攻击箭头
- createAttackArrow() {
- var $this = this;
- var arrowEntity = $this.viewer.entities.add({
- polygon: {
- hierarchy: new $this.Cesium.CallbackProperty(
- function() {
- //计算面
- var lnglatArr = [];
- for (var i = 0; i < $this._positions.length; i++) {
- var lnglat = $this.cartesianToLatlng($this._positions[i]);
- lnglatArr.push(lnglat)
- }
- var res = $this.fineArrow(lnglatArr);
- var returnData = res.polygonalPoint;
- return new $this.Cesium.PolygonHierarchy(returnData);
- }, false),
- show: true,
- fill: true,
- clampToGround: true,
- material: $this.polygonMaterial
- }
- })
- $this._entities_AttackArrow.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,
- }
- });
- point.objId = this.objId;
- $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._AttackArrowLast, this._AttackArrowData, 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_AttackArrow.length; i++) {
- this.viewer.entities.remove(this._entities_AttackArrow[i]);
- }
- this.floatingPoint = null; //标识点
- this._AttackArrow = null; //活动箭头
- this._AttackArrowLast = null; //最后一个箭头
- this._positions = []; //活动点
- this._entities_point = []; //脏数据
- this._entities_AttackArrow = []; //脏数据
- this._AttackArrowData = 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;
- }
- ////////////////////////////////////////求取箭头坐标函数/////////////////////////////////////////////////////
- //箭头配置函数
- fineArrowDefualParam() {
- return {
- headHeightFactor: .18,
- headWidthFactor: .3,
- neckHeightFactor: .85,
- neckWidthFactor: .15,
- tailWidthFactor: .1,
- headTailFactor: .8,
- swallowTailFactor: 1
- }
- }
- fineArrow(inputPoint) {
- var $this = this;
- inputPoint = $this.dereplication(inputPoint);
- let tailWidthFactor = $this.fineArrowDefualParam().tailWidthFactor;
- let swallowTailFactor = $this.fineArrowDefualParam().swallowTailFactor;
- let swallowTailPnt = $this.fineArrowDefualParam().swallowTailPnt;
- //控制点
- var result = {
- controlPoint: null,
- polygonalPoint: null
- };
- result.controlPoint = inputPoint;
- var t = inputPoint.length;
- if (!(2 > t)) {
- if (2 == inputPoint.length) {
- result.polygonalPoint = inputPoint;
- return result;
- }
- var o = inputPoint,
- e = o[0],
- r = o[1];
- $this.isClockWise(o[0], o[1], o[2]) && (e = o[1], r = o[0]);
- var n = $this.mid(e, r),
- g = [n].concat(o.slice(2)),
- i = $this.getAttackArrowHeadPoints(g, e, r, $this.fineArrowDefualParam()),
- s = i[0],
- a = i[4],
- l = $this.distance(e, r),
- u = $this.getBaseLength(g),
- c = u * tailWidthFactor * swallowTailFactor;
- swallowTailPnt = $this.getThirdPoint(g[1], g[0], 0, c, !0);
- var p = l / u,
- h = $this.getAttackArrowBodyPoints(g, s, a, p),
- t = h.length,
- d = [e].concat(h.slice(0, t / 2));
- d.push(s);
- var f = [r].concat(h.slice(t / 2, t));
- var newArray = [];
- f.push(a),
- d = $this.getQBSplinePoints(d),
- f = $this.getQBSplinePoints(f),
- newArray = $this.array2Dto1D(d.concat(i, f.reverse(), [swallowTailPnt, d[0]]));
- result.polygonalPoint = $this.Cesium.Cartesian3.fromDegreesArray(newArray);
- }
- return result;
- }
- getArrowBodyPoints(t, o, e, r) {
- var $this = this;
- for (var n = $this.wholeDistance(t), g = $this.getBaseLength(t), i = g * r, s = $this.distance(o, e), a = (i - s) / 2, l = 0, u = [], c = [], p = 1; p < t.length - 1; p++) {
- var h = $this.getAngleOfThreePoints(t[p - 1], t[p], t[p + 1]) / 2;
- l += $this.distance(t[p - 1], t[p]);
- var d = (i / 2 - l / n * a) / Math.sin(h),
- f = $this.getThirdPoint(t[p - 1], t[p], Math.PI - h, d, !0),
- E = $this.getThirdPoint(t[p - 1], t[p], h, d, !1);
- u.push(f),
- c.push(E)
- }
- return u.concat(c)
- }
- getAttackArrowHeadPoints(t, o, e, defaultParam) {
- var $this = this;
- let headHeightFactor = defaultParam.headHeightFactor;
- let headTailFactor = defaultParam.headTailFactor;
- let headWidthFactor = defaultParam.headWidthFactor;
- let neckWidthFactor = defaultParam.neckWidthFactor;
- let neckHeightFactor = defaultParam.neckHeightFactor;
- var r = $this.getBaseLength(t),
- n = r * headHeightFactor,
- g = t[t.length - 1];
- r = $this.distance(g, t[t.length - 2]);
- var i = $this.distance(o, e);
- n > i * headTailFactor && (n = i * headTailFactor);
- var s = n * headWidthFactor,
- a = n * neckWidthFactor;
- n = n > r ? r : n;
- var l = n * neckHeightFactor,
- u = $this.getThirdPoint(t[t.length - 2], g, 0, n, !0),
- c = $this.getThirdPoint(t[t.length - 2], g, 0, l, !0),
- p = $this.getThirdPoint(g, u, Math.PI / 2, s, !1),
- h = $this.getThirdPoint(g, u, Math.PI / 2, s, !0),
- d = $this.getThirdPoint(g, c, Math.PI / 2, a, !1),
- f = $this.getThirdPoint(g, c, Math.PI / 2, a, !0);
- return [d, p, g, h, f]
- }
- getAttackArrowBodyPoints = function(t, o, e, r) {
- var $this = this;
- for (var n = $this.wholeDistance(t), g = $this.getBaseLength(t), i = g * r, s = $this.distance(o, e), a = (i - s) / 2, l = 0, u = [], c = [], p = 1; p < t.length - 1; p++) {
- var h = $this.getAngleOfThreePoints(t[p - 1], t[p], t[p + 1]) / 2;
- l += $this.distance(t[p - 1], t[p]);
- var d = (i / 2 - l / n * a) / Math.sin(h),
- f = $this.getThirdPoint(t[p - 1], t[p], Math.PI - h, d, !0),
- E = $this.getThirdPoint(t[p - 1], t[p], h, d, !1);
- u.push(f),
- c.push(E)
- }
- return u.concat(c)
- }
- getAngleOfThreePoints(t, o, e) {
- var r = this.getAzimuth(o, t) - this.getAzimuth(o, e);
- return 0 > r ? r + Math.PI * 2 : r
- }
- dereplication(array) {
- var last = array[array.length - 1];
- var change = false;
- var newArray = [];
- newArray = array.filter(function(i) {
- if (i[0] != last[0] && i[1] != last[1]) {
- return i;
- }
- change = true;
- });
- if (change) newArray.push(last);
- return newArray;
- }
- getBaseLength(t) {
- return Math.pow(this.wholeDistance(t), .99)
- }
- wholeDistance(t) {
- for (var o = 0, e = 0; e < t.length - 1; e++) o += this.distance(t[e], t[e + 1]);
- return o
- }
- 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
- }
- isClockWise(t, o, e) {
- return (e[1] - t[1]) * (o[0] - t[0]) > (o[1] - t[1]) * (e[0] - t[0])
- }
- mid(t, o) {
- return [(t[0] + o[0]) / 2, (t[1] + o[1]) / 2]
- }
- getQBSplinePoints = function(t) {
- if (t.length <= 2) return t;
- var o = 2,
- e = [],
- r = t.length - o - 1,
- y = 0;
- e.push(t[0]);
- for (var n = 0; r >= n; n++)
- for (var g = 0; 1 >= g; g += .05) {
- for (var i = y = 0, s = 0; o >= s; s++) {
- var a = this.getQuadricBSplineFactor(s, g);
- i += a * t[n + s][0], y += a * t[n + s][1]
- }
- e.push([i, y])
- }
- return e.push(t[t.length - 1]), e
- }
- getQuadricBSplineFactor = function(t, o) {
- return 0 == t ? Math.pow(o - 1, 2) / 2 : 1 == t ? (-2 * Math.pow(o, 2) + 2 * o + 1) / 2 : 2 == t ? Math.pow(o, 2) / 2 : 0
- }
- array2Dto1D = function(array) {
- var newArray = [];
- array.forEach(function(elt) {
- newArray.push(elt[0]);
- newArray.push(elt[1]);
- });
- return newArray;
- }
- }
- export default DrawAttackArrow
|