DrawStraightArrow.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424
  1. import {
  2. createTooltip
  3. } from "../../../common/common.js";
  4. import {
  5. isRuntimeApp,
  6. isRuntimeWeb,
  7. createOperationMainDom,
  8. showTooltipMessage
  9. } from "../../../common/RuntimeEnvironment.js";
  10. /*
  11. 绘制直线箭头
  12. */
  13. class DrawStraightArrow {
  14. constructor(arg) {
  15. this.viewer = arg.viewer;
  16. this.Cesium = arg.Cesium;
  17. this.floatingPoint = null; //标识点
  18. this._straightArrow = null; //活动箭头
  19. this._straightArrowLast = null; //最后一个箭头
  20. this._positions = []; //活动点
  21. this._entities_point = []; //脏数据
  22. this._entities_straightArrow = []; //脏数据
  23. this._straightArrowData = null; //用于构造箭头数据
  24. this.DrawStartEvent = new Cesium.Event(); //开始绘制事件
  25. this.DrawEndEvent = new Cesium.Event(); //结束绘制事件
  26. this._tooltip = createTooltip(this.viewer.container);
  27. /* 通用参数集合 */
  28. this._param = {
  29. id: "DrawStraightArrow",
  30. polygonColor: 'rgba(0,255,0,0.5)', //面填充颜色
  31. outlineColor: 'rgba(255, 255, 255, 1)', //边框颜色
  32. outlineWidth: 1, //边框宽度
  33. }
  34. /* 创建面材质 */
  35. this.polygonMaterial = Cesium.Color.fromCssColorString(this._param.polygonColor);
  36. /* 创建线材质 */
  37. // this.outlineMaterial = new Cesium.PolylineDashMaterialProperty({//曲线
  38. // dashLength: 16,
  39. // color: Cesium.Color.fromCssColorString(this._param.outlineColor)
  40. // });
  41. this.outlineMaterial = Cesium.Color.fromCssColorString(this._param.outlineColor);
  42. }
  43. //返回箭头
  44. get straightArrow() {
  45. return this._straightArrowLast;
  46. }
  47. //返回箭头数据用于加载箭头
  48. getData() {
  49. return this._straightArrowData;
  50. }
  51. // 修改编辑调用计算
  52. computePosition(data) {
  53. var $this = this;
  54. var length = data.length;
  55. var p1 = data[0];
  56. var p2 = data[length - 1];
  57. var firstPoint = $this.cartesianToLatlng(p1);
  58. var endPoints = $this.cartesianToLatlng(p2);
  59. var arrow = [];
  60. var res = $this.fineArrow([firstPoint[0], firstPoint[1]], [endPoints[0], endPoints[1]]);
  61. for (var i = 0; i < res.length; i++) {
  62. var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
  63. arrow.push(cart3);
  64. }
  65. $this._straightArrowData = [firstPoint, endPoints];
  66. return new $this.Cesium.PolygonHierarchy(arrow);
  67. }
  68. //加载箭头
  69. addload(data) {
  70. var $this = this;
  71. if (data.length < 2) {
  72. return null;
  73. }
  74. var length = data.length;
  75. var p1 = data[0];
  76. var p2 = data[length - 1];
  77. var arrow = [];
  78. var res = $this.fineArrow([p1[0], p1[1]], [p2[0], p2[1]]);
  79. for (var i = 0; i < res.length; i++) {
  80. var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
  81. arrow.push(cart3);
  82. }
  83. var arrowEntity = $this.viewer.entities.add({
  84. Type: 'DrawStraightArrow',
  85. Position: data,
  86. id: data.id || $this.objId,
  87. polygon: {
  88. hierarchy: new $this.Cesium.PolygonHierarchy(arrow),
  89. show: true,
  90. fill: true,
  91. clampToGround: true,
  92. material: $this.polygonMaterial
  93. }
  94. });
  95. return arrowEntity;
  96. }
  97. //开始创建
  98. startCreate(drawType) {
  99. if (isRuntimeApp()) {
  100. showTooltipMessage("点击开始绘制");
  101. }
  102. var $this = this;
  103. this.drawType = drawType;
  104. this.handler = new this.Cesium.ScreenSpaceEventHandler(this.viewer.scene.canvas);
  105. //单击开始绘制
  106. this.handler.setInputAction(function(evt) {
  107. if (isRuntimeApp()) {
  108. //屏幕坐标转地形上坐标
  109. var cartesian = $this.getCatesian3FromPX(evt.position);
  110. if (!cartesian) {
  111. return;
  112. }
  113. $this.createPoint(cartesian); // 绘制点
  114. $this._positions.push(cartesian);
  115. if ($this._positions.length === 2) {
  116. showTooltipMessage("点击完成按钮,结束绘制");
  117. $this.destroy();
  118. if (!$this.Cesium.defined($this._straightArrow)) {
  119. $this._straightArrow = $this.createStraightArrow();
  120. //创建按钮
  121. createOperationMainDom();
  122. //隐藏回退按钮
  123. document.getElementById("btnDrawBackout").style.display='none';
  124. //完成绘制
  125. document.getElementById("btnDrawComplete").onclick = () => {
  126. $this._straightArrowData = $this._positions.concat();
  127. $this.viewer.entities.remove($this._straightArrow); //移除
  128. $this._straightArrow = null;
  129. $this._positions = [];
  130. var lnglatArr = [];
  131. for (var i = 0; i < $this._straightArrowData.length; i++) {
  132. var lnglat = $this.cartesianToLatlng($this._straightArrowData[i]);
  133. lnglatArr.push(lnglat)
  134. }
  135. $this._straightArrowData = lnglatArr;
  136. var straightArrow = $this.addload($this._straightArrowData); //加载
  137. $this._entities_straightArrow.push(straightArrow);
  138. $this._straightArrowLast = straightArrow;
  139. //删除关键点
  140. $this.clearPoint();
  141. $this.destroy();
  142. let buttonDiv = document.getElementById("drawButtonDiv");
  143. if (buttonDiv) {
  144. //从页面移除
  145. document.body.removeChild(buttonDiv);
  146. }
  147. }
  148. }
  149. }
  150. } else {
  151. /* 锁定点击事件 以免和双击事件冲突 */
  152. clearTimeout($this._timer);
  153. $this._timer = setTimeout(function() {
  154. console.log('监听鼠标事件', '单击')
  155. //屏幕坐标转地形上坐标
  156. var cartesian = $this.getCatesian3FromPX(evt.position);
  157. if ($this._positions.length == 0) {
  158. $this._positions.push(cartesian.clone());
  159. $this.floatingPoint = $this.createPoint(cartesian);
  160. $this._positions.push(cartesian);
  161. }
  162. if (!$this._straightArrow) {
  163. $this.createPoint(cartesian); // 绘制点
  164. } else {
  165. $this._straightArrowData = $this._positions.concat();
  166. $this.viewer.entities.remove($this._straightArrow); //移除
  167. $this._straightArrow = null;
  168. $this._positions = [];
  169. $this.floatingPoint.position.setValue(cartesian);
  170. var lnglatArr = [];
  171. for (var i = 0; i < $this._straightArrowData.length; i++) {
  172. var lnglat = $this.cartesianToLatlng($this._straightArrowData[i]);
  173. lnglatArr.push(lnglat)
  174. }
  175. $this._straightArrowData = lnglatArr;
  176. var straightArrow = $this.addload($this._straightArrowData); //加载
  177. $this._entities_straightArrow.push(straightArrow);
  178. $this._straightArrowLast = straightArrow;
  179. $this.clearPoint();
  180. $this.destroy();
  181. $this._tooltip.setVisible(false);
  182. }
  183. }, 200);
  184. }
  185. }, $this.Cesium.ScreenSpaceEventType.LEFT_CLICK);
  186. //移动时绘制面
  187. this.handler.setInputAction(function(evt) {
  188. /* 如果运行环境是App 则禁止使用鼠标移动事件 */
  189. if (isRuntimeApp()) return;
  190. $this._tooltip.showAt(evt.endPosition, "点击开始绘制");
  191. if ($this._positions.length < 2) return;
  192. $this._tooltip.showAt(evt.endPosition, "点击结束绘制");
  193. var cartesian = $this.getCatesian3FromPX(evt.endPosition);
  194. if (!$this.Cesium.defined($this._straightArrow)) {
  195. $this._straightArrow = $this.createStraightArrow();
  196. }
  197. $this.floatingPoint.position.setValue(cartesian);
  198. if ($this._straightArrow) {
  199. $this._positions.pop();
  200. $this._positions.push(cartesian);
  201. }
  202. }, $this.Cesium.ScreenSpaceEventType.MOUSE_MOVE);
  203. // this.handler.setInputAction(function(evt) {
  204. // if (!$this._straightArrow) return;
  205. // var cartesian = $this.getCatesian3FromPX(evt.position);
  206. // $this._positions.pop();
  207. // $this._positions.push(cartesian);
  208. // $this._straightArrowData = $this._positions.concat();
  209. // $this.viewer.entities.remove($this._straightArrow); //移除
  210. // $this._straightArrow = null;
  211. // $this._positions = [];
  212. // $this.floatingPoint.position.setValue(cartesian);
  213. // var lnglatArr = [];
  214. // for (var i = 0; i < $this._straightArrowData.length; i++) {
  215. // var lnglat = $this.cartesianToLatlng($this._straightArrowData[i]);
  216. // lnglatArr.push(lnglat)
  217. // }
  218. // $this._straightArrowData = lnglatArr;
  219. // var straightArrow = $this.addload($this._straightArrowData); //加载
  220. // $this._entities_straightArrow.push(straightArrow);
  221. // $this._straightArrowLast = straightArrow;
  222. // $this.clearPoint();
  223. // $this.destroy()
  224. // }, $this.Cesium.ScreenSpaceEventType.RIGHT_CLICK);
  225. }
  226. //创建直线箭头
  227. createStraightArrow() {
  228. var $this = this;
  229. var arrowEntity = $this.viewer.entities.add({
  230. polygon: {
  231. hierarchy: new $this.Cesium.CallbackProperty(
  232. function() {
  233. // return new $this.Cesium.PolygonHierarchy($this._positions);
  234. var length = $this._positions.length;
  235. var p1 = $this._positions[0];
  236. var p2 = $this._positions[length - 1];
  237. var firstPoint = $this.cartesianToLatlng(p1);
  238. var endPoints = $this.cartesianToLatlng(p2);
  239. var arrow = [];
  240. var res = $this.fineArrow([firstPoint[0], firstPoint[1]], [endPoints[0], endPoints[1]]);
  241. for (var i = 0; i < res.length; i++) {
  242. var cart3 = new $this.Cesium.Cartesian3(res[i].x, res[i].y, res[i].z);
  243. arrow.push(cart3);
  244. }
  245. return new $this.Cesium.PolygonHierarchy(arrow);
  246. }, false),
  247. show: true,
  248. fill: true,
  249. clampToGround: true,
  250. material: $this.polygonMaterial
  251. }
  252. })
  253. $this._entities_straightArrow.push(arrowEntity);
  254. return arrowEntity
  255. }
  256. //创建点
  257. createPoint(cartesian) {
  258. var $this = this;
  259. var point = this.viewer.entities.add({
  260. position: cartesian,
  261. point: {
  262. pixelSize: 10,
  263. color: $this.Cesium.Color.RED,
  264. heightReference: Cesium.HeightReference.CLAMP_TO_GROUND,
  265. }
  266. });
  267. $this._entities_point.push(point);
  268. return point;
  269. }
  270. cartesianToLatlng(cartesian) {
  271. var latlng = this.viewer.scene.globe.ellipsoid.cartesianToCartographic(cartesian);
  272. var lat = this.Cesium.Math.toDegrees(latlng.latitude);
  273. var lng = this.Cesium.Math.toDegrees(latlng.longitude);
  274. return [lng, lat];
  275. }
  276. //销毁
  277. destroy() {
  278. if (this.handler) {
  279. this.handler.destroy();
  280. this.handler = null;
  281. }
  282. }
  283. clearPoint() {
  284. this.DrawEndEvent.raiseEvent(this._straightArrowLast, this._straightArrowData, this.drawType);
  285. for (var i = 0; i < this._entities_point.length; i++) {
  286. this.viewer.entities.remove(this._entities_point[i]);
  287. }
  288. this._entities_point = []; //脏数据
  289. }
  290. //清空实体对象
  291. clear() {
  292. for (var i = 0; i < this._entities_point.length; i++) {
  293. this.viewer.entities.remove(this._entities_point[i]);
  294. }
  295. for (var i = 0; i < this._entities_straightArrow.length; i++) {
  296. this.viewer.entities.remove(this._entities_straightArrow[i]);
  297. }
  298. this.floatingPoint = null; //标识点
  299. this._straightArrow = null; //活动箭头
  300. this._straightArrowLast = null; //最后一个箭头
  301. this._positions = []; //活动点
  302. this._entities_point = []; //脏数据
  303. this._entities_straightArrow = []; //脏数据
  304. this._straightArrowData = null; //用于构造箭头数据
  305. }
  306. getCatesian3FromPX(px) {
  307. var cartesian;
  308. var ray = this.viewer.camera.getPickRay(px);
  309. if (!ray) return null;
  310. cartesian = this.viewer.scene.globe.pick(ray, this.viewer.scene);
  311. return cartesian;
  312. }
  313. // 求取箭头坐标函数/
  314. //箭头配置函数
  315. fineArrowDefualParam() {
  316. return {
  317. tailWidthFactor: 0.15,
  318. neckWidthFactor: 0.20,
  319. headWidthFactor: 0.25,
  320. headAngle: Math.PI / 8.5,
  321. neckAngle: Math.PI / 13
  322. }
  323. }
  324. fineArrow(tailPoint, headerPoint) {
  325. var $this = this;
  326. if ((tailPoint.length < 2) || (headerPoint.length < 2)) return;
  327. //画箭头的函数
  328. let tailWidthFactor = $this.fineArrowDefualParam().tailWidthFactor;
  329. let neckWidthFactor = $this.fineArrowDefualParam().neckWidthFactor;
  330. let headWidthFactor = $this.fineArrowDefualParam().headWidthFactor;
  331. let headAngle = $this.fineArrowDefualParam().headAngle;
  332. let neckAngle = $this.fineArrowDefualParam().neckAngle;
  333. var o = [];
  334. o[0] = tailPoint;
  335. o[1] = headerPoint;
  336. var e = o[0],
  337. r = o[1],
  338. n = $this.getBaseLength(o),
  339. g = n * tailWidthFactor,
  340. //尾部宽度因子
  341. i = n * neckWidthFactor,
  342. //脖子宽度银子
  343. s = n * headWidthFactor,
  344. //头部宽度因子
  345. a = $this.getThirdPoint(r, e, Math.PI / 2, g, !0),
  346. l = $this.getThirdPoint(r, e, Math.PI / 2, g, !1),
  347. u = $this.getThirdPoint(e, r, headAngle, s, !1),
  348. c = $this.getThirdPoint(e, r, headAngle, s, !0),
  349. p = $this.getThirdPoint(e, r, neckAngle, i, !1),
  350. h = $this.getThirdPoint(e, r, neckAngle, i, !0),
  351. d = [];
  352. d.push(a[0], a[1], p[0], p[1], u[0], u[1], r[0], r[1], c[0], c[1], h[0], h[1], l[0], l[1], e[0], e[1]);
  353. return $this.Cesium.Cartesian3.fromDegreesArray(d);
  354. }
  355. getBaseLength(t) {
  356. return Math.pow(this.wholeDistance(t), .99)
  357. }
  358. wholeDistance(t) {
  359. for (var o = 0, e = 0; e < t.length - 1; e++) o += this.distance(t[e], t[e + 1]);
  360. return o
  361. }
  362. distance(t, o) {
  363. return Math.sqrt(Math.pow(t[0] - o[0], 2) + Math.pow(t[1] - o[1], 2))
  364. }
  365. getThirdPoint(t, o, e, r, n) {
  366. var g = this.getAzimuth(t, o),
  367. i = n ? g + e : g - e,
  368. s = r * Math.cos(i),
  369. a = r * Math.sin(i);
  370. return [o[0] + s, o[1] + a]
  371. }
  372. getAzimuth(t, o) {
  373. var e, r = Math.asin(Math.abs(o[1] - t[1]) / this.distance(t, o));
  374. 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
  375. }
  376. }
  377. export default DrawStraightArrow