EditScence.ts 32 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030
  1. import { SMouseEvent, SUndoStack } from "@saga-web/base";
  2. import { SGraphScene, SGraphLayoutType, SAnchorItem } from '@saga-web/graph/lib';
  3. import { SFloorParser, SLineItem, SPolylineItem, SItemStatus, ItemOrder, STooltipItem } from "@saga-web/big";
  4. import { SGraphItem, SLineStyle, SImageItem, STextItem, SGraphPointListInsert, SGraphPointListDelete, SGraphPointListUpdate, SGraphAddCommand } from "@saga-web/graph/lib";
  5. import { SZoneLegendItem } from "@/lib/items/SZoneLegendItem";
  6. import { SSCPZZoneLegendItem } from "@/lib/items/SSCPZZoneLegendItem";
  7. import { SFHFQZoneLegendItem } from "@/lib/items/SFHFQZoneLegendItem";
  8. import { SImageLegendItem } from "@/lib/items/SImageLegendItem";
  9. import { TipelineItem } from "@/lib/items/TipelineItem";
  10. import { SImageMarkerItem } from "@/lib/items/SImageMarkerItem"
  11. import { SPoint, SFont, SColor, SRect } from '@saga-web/draw/lib';
  12. import { Legend } from '@/lib/types/Legend';
  13. import { Relation } from '@/lib/types/Relation';
  14. import { uuid } from "@/components/mapClass/until";
  15. import { STextMarkerItem } from '@/lib/items/STextMarkerItem';
  16. import { SLineMarkerItem } from '@/lib/items/SLineMarkerItem';
  17. import { SSpaceItem } from '@saga-web/big/lib/items/floor/SSpaceItem';
  18. import { SMathUtil } from '@saga-web/big/lib/utils/SMathUtil';
  19. import { MinDis } from '@saga-web/big/lib/types/MinDis';
  20. import { HighlightItem } from '@/lib/items/HighlightItem';
  21. /**
  22. * 在线绘图
  23. *
  24. * @author 韩耀龙
  25. */
  26. export class EditScence extends SGraphScene {
  27. undoStack = new SUndoStack();
  28. /** 命令 1 绘制直线 */
  29. private cmd = 'choice';
  30. /** 获取当前状态 */
  31. get getCmd(): string {
  32. return this.cmd;
  33. }
  34. /** 编辑当前状态 */
  35. set setCmd(cmd: string) {
  36. if (cmd == 'choice') {
  37. this.grabItem = null;
  38. }
  39. this.cmd = cmd;
  40. if (this.focusItem) {
  41. // 取消操作
  42. this.focusItem.cancelOperate();
  43. this.focusItem = null;
  44. // this.selectContainer.
  45. }
  46. if (this.view) {
  47. this.view.update();
  48. }
  49. };
  50. /** 绘制区域时 是否为点选 */
  51. isSelecting: boolean = false;
  52. /** 是否开启吸附 */
  53. isAbsorbing: boolean = false;
  54. /** 吸附展示item */
  55. highLight: HighlightItem | null = null;
  56. /** 当前选中焦点Item */
  57. focusItem: SGraphItem | null = null;
  58. /**图例节点 */
  59. Nodes: any = []; // 图例节点,所有与工程信息化相关的图例(图标类型与区域)
  60. /**图例节点 */ // 与工程信息无关的标识对象(增加文本注释,图上的图片说明)
  61. Markers: any = [];
  62. /** 管线对象 */
  63. Relations: any = [];
  64. constructor() {
  65. super();
  66. // // 选择绑定选额item事件
  67. this.selectContainer.connect("listChange", this, this.listChange);
  68. }
  69. /** 绘制图例样式 */
  70. _legend: any | null = null;
  71. get getlegend(): any {
  72. return this._legend;
  73. };
  74. set setlegend(obj: any) {
  75. this._legend = obj;
  76. console.log('aaaaaa', obj)
  77. }
  78. /** fid=>item映射,由解析器存入 */
  79. fidToItem = {}
  80. /**
  81. * 监听变化
  82. * @param obj 变化后的对象
  83. */
  84. listChange(obj: any) {
  85. let itemType: string = 'equipment';
  86. if (obj.itemList[0] instanceof STextMarkerItem) {
  87. itemType = 'baseText'
  88. } else if (obj.itemList[0] instanceof SImageMarkerItem) {
  89. itemType = 'baseImage'
  90. } else if (obj.itemList[0] instanceof SLineMarkerItem) {
  91. itemType = 'baseLine'
  92. } else if (obj.itemList[0] instanceof SZoneLegendItem) {
  93. itemType = 'Zone'
  94. } else if (obj.itemList[0] instanceof SFHFQZoneLegendItem) {
  95. itemType = 'Zone'
  96. } else if (obj.itemList[0] instanceof SSCPZZoneLegendItem) {
  97. itemType = 'Zone'
  98. } else if (obj.itemList[0] instanceof SImageLegendItem) {
  99. itemType = 'Image'
  100. } else if (obj.itemList[0] instanceof TipelineItem) {
  101. itemType = 'Line'
  102. } else if (obj.itemList[0] instanceof SSpaceItem) { // 点选
  103. this.clickToAddArea(obj.itemList[0]);
  104. return
  105. } else {
  106. itemType = ''
  107. };
  108. if (obj.itemList.length == 1) {
  109. // 获取聚焦item
  110. this.focusItem = obj.itemList[0]
  111. }
  112. let msg = {
  113. itemList: obj.itemList,
  114. itemType,
  115. }
  116. this.emitChange(msg)
  117. }
  118. emitChange(msg: any) {
  119. }
  120. /**
  121. * 增加线段item
  122. */
  123. addLine(event: SMouseEvent): boolean {
  124. const data = {
  125. /** ID */
  126. ID: uuid(),
  127. /** 名称 */
  128. Name: '直线',
  129. /** 图标(Image),线类型(Line) */
  130. Type: "Line",
  131. /** 位置 */
  132. Pos: { X: 0, Y: 0 },
  133. /** 由应用自己定义 */
  134. Properties: {
  135. IconUrl: require("../../assets/images/t-line-hover.png"),
  136. Line: [{ X: event.x, Y: event.y }],
  137. LineWidth: 2
  138. }
  139. }
  140. const item = new SLineMarkerItem(null, data);
  141. item.status = SItemStatus.Create;
  142. item.zOrder = ItemOrder.lineOrder;
  143. item.selectable = true;
  144. this.addItem(item);
  145. this.Markers.push(item);
  146. item.connect("finishCreated", this, this.finishCreated);
  147. this.grabItem = item;
  148. this.focusItem = item;
  149. this.scenceUpdate(this);
  150. // this.undoStack.push(new SGraphAddCommand(this, item));
  151. // item.connect("onMove", this, this.onItemMove.bind(this));
  152. return true
  153. }
  154. /**
  155. * 增加折线item
  156. */
  157. addPolylineItem(event: SMouseEvent): boolean {
  158. const point = new SPoint(event.x, event.y)
  159. const item = new TipelineItem(null, [point]);
  160. //设置状态
  161. item.selectable = true;
  162. item.status = SItemStatus.Create;
  163. item.zOrder = ItemOrder.polylineOrder
  164. this.addItem(item);
  165. item.connect("finishCreated", this, this.finishCreated);
  166. // this.undoStack.push(new SGraphAddCommand(this, item));
  167. this.grabItem = item;
  168. this.focusItem = item;
  169. return true
  170. }
  171. /**
  172. * 增加管道 lenged
  173. */
  174. addTipelineItem(event: SMouseEvent): boolean {
  175. const anc = this.clickIsAnchor(event);
  176. if (anc) {
  177. const p = anc.mapToScene(0, 0)
  178. anc.isConnected = true;
  179. event.x = p.x;
  180. event.y = p.y;
  181. }
  182. const LegendData: Relation = {
  183. ID: uuid(),
  184. Name: this._legend.Name,
  185. GraphElementId: this._legend.Id,
  186. PointList: [{ X: event.x, Y: event.y }],
  187. LineType: "Line",
  188. Properties: {
  189. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  190. LineDash: this._legend.LineDash,
  191. LineWidth: this._legend.LineWidth,
  192. Color: this._legend.Color,
  193. },
  194. }
  195. const item = new TipelineItem(null, LegendData);
  196. //设置状态
  197. item.selectable = true;
  198. item.status = SItemStatus.Create;
  199. item.zOrder = ItemOrder.polylineOrder
  200. this.addItem(item);
  201. this.Relations.push(item);
  202. item.connect("finishCreated", this, this.finishCreated);
  203. // this.undoStack.push(new SGraphAddCommand(this, item));
  204. this.grabItem = item;
  205. this.focusItem = item;
  206. // 起始锚点
  207. item.startAnchor = anc;
  208. if (anc) {
  209. anc.parent?.connect('changePos', item, item.changePos)
  210. }
  211. this.scenceUpdate(this);
  212. return true
  213. }
  214. /**
  215. * 增加多边形item lenged
  216. */
  217. addPolygonItem(event: SMouseEvent): void {
  218. const SubType = this._legend.SubType ? this._legend.SubType : ''
  219. const LegendData: Legend = {
  220. ID: uuid(),
  221. Name: this._legend.Name,
  222. GraphElementType: this._legend.Type,
  223. Num: 1,
  224. GraphElementId: this._legend.Id,
  225. AttachObjectIds: [],
  226. Type: "Zone",
  227. Pos: { X: event.x, Y: event.y },
  228. OutLine: [{ X: event.x, Y: event.y }],
  229. SubType: SubType,
  230. Properties: {
  231. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  232. StrokeColor: this._legend.Color,
  233. FillColor: this._legend.FillColor,
  234. LineDash: this._legend.LineDash,
  235. LineWidth: this._legend.LineWidth,
  236. font: 0,
  237. color: '',
  238. TextPos: { X: 0, Y: 0 }
  239. },
  240. }
  241. let Polylines = null;
  242. if (SubType == "SCPZ") {
  243. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  244. } else if (SubType == "FHFQ") {
  245. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  246. } else {
  247. Polylines = new SZoneLegendItem(null, LegendData);
  248. }
  249. Polylines.selectable = true;
  250. //设置状态
  251. Polylines.status = SItemStatus.Create;
  252. Polylines.zOrder = ItemOrder.polygonOrder;
  253. // Polylines.moveable = true;
  254. this.addItem(Polylines);
  255. this.Nodes.push(Polylines);
  256. Polylines.connect("finishCreated", this, this.finishCreated);
  257. this.grabItem = Polylines;
  258. this.focusItem = Polylines;
  259. this.scenceUpdate(this);
  260. }
  261. /**
  262. * 点选创建区域
  263. */
  264. clickToAddArea(item: SSpaceItem): void {
  265. if (this.cmd != 'Zone') {
  266. return
  267. }
  268. if (this.isSelecting && this._legend) {
  269. //@ts-ignore
  270. item.isExtracted = true
  271. const SubType = this._legend.SubType ? this._legend.SubType : ''
  272. const LegendData: Legend = {
  273. ID: uuid(),
  274. Name: this._legend.Name,
  275. GraphElementType: this._legend.Type,
  276. Num: 1,
  277. GraphElementId: this._legend.Id,
  278. AttachObjectIds: [],
  279. Type: "Zone",
  280. Pos: { X: item.x, Y: item.y },
  281. OutLine: item.pointArr[0],
  282. SubType: SubType,
  283. Properties: {
  284. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  285. StrokeColor: this._legend.Color,
  286. FillColor: this._legend.FillColor,
  287. LineDash: this._legend.LineDash,
  288. LineWidth: this._legend.LineWidth,
  289. font: 12,
  290. color: '',
  291. FID: item.data.SourceId,
  292. TextPos: { X: item.data.Location.Points[0].X, Y: -item.data.Location.Points[0].Y }
  293. },
  294. }
  295. let Polylines = null;
  296. if (SubType == "SCPZ") {
  297. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  298. } else if (SubType == "FHFQ") {
  299. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  300. } else {
  301. Polylines = new SZoneLegendItem(null, LegendData);
  302. }
  303. Polylines.selectable = true;
  304. //设置状态
  305. Polylines.status = SItemStatus.Normal;
  306. this.addItem(Polylines);
  307. this.Nodes.push(Polylines);
  308. Polylines.connect("finishCreated", this, this.finishCreated);
  309. this.finishCreated(Polylines)
  310. this.focusItem = Polylines;
  311. this.scenceUpdate(this);
  312. }
  313. }
  314. /**
  315. * 增加图片Item mark
  316. */
  317. addImgItem(event: SMouseEvent) {
  318. const data = {
  319. /** ID */
  320. ID: uuid(),
  321. /** 名称 */
  322. Name: '图片',
  323. Num: 1,
  324. /** 图标(Image),线类型(Line) */
  325. Type: "Image",
  326. /** 位置 */
  327. Pos: { X: event.x, Y: event.y },
  328. /** 由应用自己定义 */
  329. Properties: {
  330. IconUrl: require(`../../assets/images/t-img-hover.png`),
  331. Url: '',
  332. }
  333. }
  334. const item = new SImageMarkerItem(null, data);
  335. item.zOrder = ItemOrder.imageOrder;
  336. item.selectable = true;
  337. item.moveable = true;
  338. this.addItem(item);
  339. this.Markers.push(item);
  340. this.grabItem == null;
  341. this.focusItem = item;
  342. this.cmd = 'choice';
  343. this.scenceUpdate(this);
  344. }
  345. /**
  346. * 增加文字item
  347. */
  348. addTextItem(event: SMouseEvent): void {
  349. const data = {
  350. /** ID */
  351. ID: uuid(),
  352. /** 名称 */
  353. Name: '文本',
  354. /** 图标 */
  355. Type: "Text",
  356. /** 位置 */
  357. Pos: { X: event.x, Y: event.y },
  358. /** 由应用自己定义 */
  359. Properties: {
  360. IconUrl: require(`../../assets/images/t-text-hover.png`),
  361. Text: '请在右侧属性栏输入文字!',
  362. Color: '',
  363. Font: 12,
  364. BackgroundColor: ''
  365. }
  366. }
  367. const item = new STextMarkerItem(null, data);
  368. item.moveTo(event.x, event.y);
  369. item.selectable = true;
  370. item.moveable = true;
  371. item.zOrder = ItemOrder.textOrder;
  372. this.addItem(item);
  373. this.Markers.push(item);
  374. this.grabItem = item;
  375. this.focusItem = item;
  376. this.cmd = 'choice';
  377. this.scenceUpdate(this);
  378. }
  379. /**
  380. * 增加图标lenged图标
  381. */
  382. addIconItem(event: SMouseEvent): void {
  383. const LegendData: Legend = {
  384. ID: uuid(),
  385. Name: this._legend.Name,
  386. GraphElementType: this._legend.Type,
  387. Num: 1,
  388. GraphElementId: this._legend.Id,
  389. AttachObjectIds: [],
  390. Pos: { X: event.x, Y: event.y },
  391. Scale: { X: 1, Y: 1, Z: 1 }, // 缩放
  392. Rolate: { X: 0, Y: 0, Z: 0 },
  393. Size: { Width: 0, Height: 0 }, // 大小
  394. Properties: {
  395. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  396. Url: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  397. Num: 1, // 此num与信息工程化得num无关
  398. sWidth: 24, //icon 的宽
  399. sHeight: 24, //icon 的高
  400. font: 12, //font
  401. color: '', //字体颜色
  402. },
  403. }
  404. const item = new SImageLegendItem(null, LegendData);
  405. this.cmd = 'choice';
  406. item.selectable = true;
  407. item.moveable = true;
  408. item.zOrder = ItemOrder.markOrder;
  409. this.addItem(item);
  410. this.Nodes.push(item);
  411. this.grabItem = item;
  412. this.focusItem = item;
  413. this.scenceUpdate(this);
  414. }
  415. /**
  416. * 更改item对应属性
  417. */
  418. editItemStatus(): void {
  419. }
  420. /**
  421. * 更改文本对应属性
  422. * @param str string 文字内容
  423. */
  424. updatedText(str: string): void {
  425. if (this.focusItem) {
  426. const old = this.focusItem.text;
  427. this.focusItem.text = str;
  428. this.scenceUpdate(this);
  429. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", old, str));
  430. }
  431. }
  432. /**
  433. * 更改文本fontSize属性
  434. * @param size number 文字大小
  435. */
  436. updatedFontSize(size: number): void {
  437. if (this.focusItem) {
  438. let old = new SFont(this.focusItem.font);
  439. let font = new SFont(this.focusItem.font);
  440. font.size = size;
  441. this.focusItem.font = font;
  442. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font));
  443. }
  444. }
  445. /**
  446. * 更改线宽属性
  447. * @param lineWidth number 线宽大小
  448. */
  449. updatedLineWidth(lineWidth: number): void {
  450. if (this.focusItem) {
  451. // let old = new SFont(this.focusItem.font);
  452. // let font = new SFont(this.focusItem.font);
  453. // font.size = size;
  454. this.focusItem.lineWidth = lineWidth;
  455. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font));
  456. }
  457. }
  458. /**
  459. * 更改文本颜色属性
  460. * @param str string 颜色
  461. */
  462. updatedFontColor(color: string): void {
  463. if (this.focusItem) {
  464. let old = this.focusItem.color;
  465. this.focusItem.color = new SColor(color);
  466. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  467. }
  468. }
  469. /**
  470. * 更改border颜色
  471. * @param color string 颜色
  472. */
  473. updatedBorderColor(color: string): void {
  474. if (this.focusItem) {
  475. if (this.focusItem instanceof SZoneLegendItem || this.focusItem instanceof SSCPZZoneLegendItem || this.focusItem instanceof SFHFQZoneLegendItem) {
  476. this.focusItem.strokeColor = new SColor(color);
  477. } else {
  478. // let old = this.focusItem.strokeColor;
  479. this.focusItem.strokeColor = new SColor(color);
  480. }
  481. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  482. }
  483. }
  484. /**
  485. * 更改item宽
  486. * @param width number 颜色
  487. */
  488. updatedWidth(width: number): void {
  489. if (this.focusItem) {
  490. // let old = this.focusItem.width;
  491. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  492. this.focusItem.sWidth = width;
  493. } else {
  494. this.focusItem.width = width;
  495. }
  496. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  497. }
  498. }
  499. /**
  500. * 更改item高
  501. * @param height number 颜色
  502. */
  503. updatedHeight(height: number): void {
  504. if (this.focusItem) {
  505. // let old = this.focusItem.width;
  506. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  507. this.focusItem.sHeight = height;
  508. } else {
  509. this.focusItem.height = height;
  510. }
  511. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  512. }
  513. }
  514. /**
  515. * 更改item坐标
  516. * @param x number x x坐标
  517. * @param y number y y坐标
  518. */
  519. updatedPosition(x: number, y: number): void {
  520. if (this.focusItem) {
  521. let p = this.focusItem.mapFromScene(x, y)
  522. // newx - oldx = newleft - oldleft
  523. // 要求的值(新的x坐标) - 旧的x坐标 = 新的左边界(用户输入的值) - 旧的左边界
  524. this.focusItem.x = p.x - this.focusItem.boundingRect().left + this.focusItem.x;
  525. this.focusItem.y = p.y - this.focusItem.boundingRect().top + this.focusItem.y;
  526. }
  527. }
  528. /**
  529. * 更改item 背景色坐标
  530. * @param color string 颜色color
  531. */
  532. updatedbackColor(color: string): void {
  533. if (this.focusItem) {
  534. this.focusItem.backgroundColor = new SColor(color);
  535. }
  536. }
  537. /**
  538. * 更改item Url
  539. * @param url string 图片key
  540. */
  541. upadataImageUrl(url: string): void {
  542. if (this.focusItem) {
  543. this.focusItem.url = '/serve/topology-wanda/Picture/query/' + url;
  544. }
  545. }
  546. /**
  547. * 更改item border
  548. * @param val string border类型
  549. */
  550. upadataBorder(val: string): void {
  551. if (this.focusItem) {
  552. let borderStyle = null
  553. if (val == 'dashed') {
  554. borderStyle = SLineStyle.Dashed
  555. } else if (val == 'dotted') {
  556. borderStyle = SLineStyle.Dotted
  557. } else if (val == 'solid') {
  558. borderStyle = SLineStyle.Soild
  559. }
  560. this.focusItem.lineStyle = borderStyle;
  561. }
  562. }
  563. /**
  564. * 更改item 名称
  565. * @param val string border类型
  566. */
  567. upadataLengedName(val: string): void {
  568. if (this.focusItem && this.focusItem.data) {
  569. this.focusItem.text = val;
  570. this.scenceUpdate(this);
  571. }
  572. }
  573. /**
  574. * 更改item Num数量
  575. * @param num number item数量 (只对icon设备类)
  576. */
  577. upadatImageNum(num: number): void {
  578. if (this.focusItem && this.focusItem.num) {
  579. this.focusItem.num = num;
  580. }
  581. }
  582. /**
  583. * 更改item Num数量
  584. * @param num number item数量 (只对icon设备类)
  585. */
  586. upadatfillColor(fillColor: string): void {
  587. if (this.focusItem && this.focusItem.fillColor) {
  588. this.focusItem.fillColor = new SColor(fillColor);
  589. }
  590. }
  591. /**
  592. * 更改图例说
  593. * @param num number
  594. */
  595. upadatitemExplain(ItemExplain: string): void {
  596. if (this.focusItem) {
  597. this.focusItem.data.Properties.ItemExplain = ItemExplain;
  598. }
  599. }
  600. /**
  601. * 删除指定item
  602. */
  603. deleiteItem(): void {
  604. if (this.focusItem) {
  605. if ((this.focusItem instanceof SZoneLegendItem ||
  606. this.focusItem instanceof SSCPZZoneLegendItem ||
  607. this.focusItem instanceof SFHFQZoneLegendItem ||
  608. this.focusItem instanceof TipelineItem) &&
  609. this.focusItem.curIndex != -1
  610. ) {
  611. this.focusItem.deletePoint(this.focusItem.curIndex);
  612. } else {
  613. this.removeItem(this.focusItem);
  614. let a = -1
  615. this.Nodes.forEach((item: any, index: number) => {
  616. if (item.id == this.focusItem.id) {
  617. a = index
  618. }
  619. });
  620. if (a > -1) {
  621. this.Nodes.splice(a, 1);
  622. }
  623. let b = -1;
  624. this.Markers.forEach((item: any, index: number) => {
  625. if (item.id == this.focusItem.id) {
  626. b = index
  627. }
  628. });
  629. if (b > -1) {
  630. this.Markers.splice(b, 1);
  631. }
  632. let c = -1;
  633. this.Relations.forEach((item: any, index: number) => {
  634. if (item.id == this.focusItem.id) {
  635. c = index
  636. }
  637. });
  638. if (c > -1) {
  639. this.Relations.splice(c, 1);
  640. }
  641. this.focusItem = null;
  642. if (this.view) {
  643. this.view.update();
  644. }
  645. this.scenceUpdate(this);
  646. }
  647. }
  648. }
  649. scenceUpdate(scence: any) { }
  650. /**
  651. * 对齐指定item
  652. * @param v
  653. */
  654. changeAlignItem(v: any): void {
  655. this.selectContainer.layout(v);
  656. }
  657. /**
  658. * 提取item
  659. */
  660. extractItem(): void {
  661. console.log(this)
  662. }
  663. /**
  664. * 保存数据
  665. */
  666. saveMsgItem(): any {
  667. const Nodes: any = [];
  668. const Markers: any = [];
  669. const Relations: any = [];
  670. this.Nodes.forEach(e => {
  671. Nodes.push(e.toData())
  672. });
  673. this.Markers.forEach(e => {
  674. Markers.push(e.toData())
  675. });
  676. this.Relations.forEach(e => {
  677. Relations.push(e.toData())
  678. });
  679. let element = {
  680. Nodes, Markers, Relations
  681. }
  682. return element
  683. }
  684. /**
  685. * 锁住item
  686. */
  687. lockItem(): void {
  688. }
  689. /**
  690. * 执行取消操作
  691. */
  692. redo(): void {
  693. this.undoStack.undo();
  694. }
  695. /**
  696. * 执行重做操作执行
  697. */
  698. undo(): void {
  699. this.undoStack.redo();
  700. }
  701. /**
  702. * 完成事件创建的回调函数
  703. */
  704. finishCreated(item: any) {
  705. this.setCmd = 'choice';
  706. this.focusItem = item;
  707. this.selectContainer.toggleItem(item)
  708. }
  709. ////////////////////////
  710. // 以下为鼠标键盘操作事件
  711. onMouseDown(event: SMouseEvent): any {
  712. // 判断是否开启吸附,并且有吸附的点
  713. if (
  714. this.isAbsorbing &&
  715. this.highLight &&
  716. this.highLight.visible
  717. ) {
  718. event.x = this.highLight.point.x;
  719. event.y = this.highLight.point.y;
  720. }
  721. if (this.grabItem) {
  722. // if (this.grabItem instanceof TipelineItem) {
  723. // this.setTipeEndanchor(event)
  724. // return true;
  725. // }
  726. return this.grabItem.onMouseDown(event);
  727. }
  728. switch (this.cmd) {
  729. case 'baseLine':
  730. this.addLine(event);
  731. break;
  732. case 'baseText':
  733. this.addTextItem(event);
  734. break;
  735. case 'baseImage':
  736. this.addImgItem(event)
  737. break;
  738. case 'Zone':
  739. if (!this.isSelecting) {
  740. this.addPolygonItem(event);
  741. } else {
  742. // 点选创建区域
  743. return super.onMouseDown(event)
  744. }
  745. break;
  746. case 'Image':
  747. this.addIconItem(event);
  748. break;
  749. case 'Line':
  750. this.addTipelineItem(event);
  751. break;
  752. default:
  753. return super.onMouseDown(event);
  754. }
  755. }
  756. onMouseMove(event: SMouseEvent): boolean {
  757. if (this.isAbsorbing) {
  758. if (!this.highLight) {
  759. this.highLight = new HighlightItem(null);
  760. this.addItem(this.highLight);
  761. }
  762. this.highLight.visible = false;
  763. this.absorbSpace(event);
  764. }
  765. return super.onMouseMove(event)
  766. }
  767. /**
  768. * 键盘事件
  769. *
  770. * @param event 事件参数
  771. * @return boolean
  772. */
  773. onKeyDown(event: KeyboardEvent): any {
  774. if (this.grabItem) {
  775. this.grabItem.onKeyDown(event);
  776. }
  777. // if (event.key == "Enter") {
  778. // this.cmd = 0
  779. // }
  780. return false
  781. }
  782. /**
  783. * 设置结束锚点
  784. *
  785. */
  786. setTipeEndanchor(event: SMouseEvent): void {
  787. if (this.grabItem instanceof TipelineItem) {
  788. const anc = this.clickIsAnchor(event);
  789. if (anc) {
  790. const p = anc.mapToScene(0, 0)
  791. anc.isConnected = true;
  792. event.x = p.x;
  793. event.y = p.y;
  794. if (this.grabItem.pointList.length) {
  795. this.grabItem.endAnchor = anc;
  796. anc.parent?.connect('changePos', this.grabItem, this.grabItem.changePos)
  797. }
  798. this.grabItem.status = SItemStatus.Normal;
  799. }
  800. this.grabItem.onMouseDown(event)
  801. }
  802. }
  803. /**
  804. * 划线时点击位置是否是锚点
  805. *
  806. * @param event 事件
  807. * @param len 限制距离
  808. * @return 点击的锚点
  809. * */
  810. clickIsAnchor(event: SMouseEvent): SAnchorItem | null {
  811. let minAnchor = null;
  812. let len: number = -1;
  813. this.Nodes.forEach(image => {
  814. if (image.anchorList && image.anchorList.length) {
  815. image.anchorList.forEach(anchor => {
  816. let anchorPoint = anchor.mapToScene(0, 0);
  817. let dis = SMathUtil.pointDistance(
  818. event.x,
  819. event.y,
  820. anchorPoint.x,
  821. anchorPoint.y
  822. );
  823. if (len < 0) {
  824. len = anchor.sceneDis;
  825. }
  826. if (dis < len) {
  827. minAnchor = anchor;
  828. len = dis;
  829. }
  830. })
  831. }
  832. })
  833. console.log('-----------------------')
  834. console.log(minAnchor)
  835. console.log('-----------------------')
  836. return minAnchor;
  837. }
  838. /**
  839. * 点是否在吸附区域内
  840. *
  841. * @param p 要判断的点
  842. * @param minX 空间区域
  843. * @param minY 空间区域
  844. * @param maxX 空间区域
  845. * @param maxY 空间区域
  846. */
  847. static isPointInAbsorbArea(
  848. p: SPoint,
  849. minX: number,
  850. maxX: number,
  851. minY: number,
  852. maxY: number
  853. ): boolean {
  854. let rect = new SRect(
  855. minX - 1000,
  856. minY - 1000,
  857. maxX - minX + 2000,
  858. maxY - minY + 2000
  859. );
  860. return rect.contains(p.x, p.y);
  861. } // Function isPointInAbsorbArea()
  862. /**
  863. * 吸附空间
  864. *
  865. * @param event 鼠标事件对象
  866. * @return boolean 是否找到吸附的对象
  867. */
  868. absorbSpace(event: SMouseEvent): boolean {
  869. if (!this.highLight) {
  870. return false;
  871. }
  872. let absorbLen = 1000;
  873. if (this.view) {
  874. absorbLen = 10 / this.view.scale;
  875. }
  876. let P = this.absorbSpacePoint(event, absorbLen);
  877. if (P.Point) {
  878. this.highLight.distance = P.MinDis;
  879. this.highLight.point = new SPoint(P.Point.X, -P.Point.Y);
  880. this.highLight.visible = true;
  881. return true;
  882. } else {
  883. let L = this.absorbSpaceLine(event, absorbLen);
  884. if (L.Line && L.Point) {
  885. this.highLight.distance = L.MinDis;
  886. this.highLight.point = L.Point;
  887. this.highLight.line = L.Line;
  888. this.highLight.visible = true;
  889. return true;
  890. }
  891. return false;
  892. }
  893. } // Function absorbSpace()
  894. /**
  895. * 吸附空间点
  896. *
  897. * @param event 鼠标事件对象
  898. * @param absorbLen 吸附距离
  899. * @return MinDis 吸附的点
  900. */
  901. absorbSpacePoint(event: SMouseEvent, absorbLen: number): MinDis {
  902. let minPointDis = Number.MAX_SAFE_INTEGER;
  903. let Point;
  904. this.spaceList.map((space): void => {
  905. if (
  906. EditScence.isPointInAbsorbArea(
  907. new SPoint(event.x, event.y),
  908. space.minX,
  909. space.maxX,
  910. space.minY,
  911. space.maxY
  912. )
  913. ) {
  914. space.data.OutLine.forEach((item): void => {
  915. let minDis = SMathUtil.getMinDisPoint(
  916. new SPoint(event.x, event.y),
  917. item
  918. );
  919. if (
  920. minDis &&
  921. minDis.MinDis < absorbLen &&
  922. minDis.MinDis < minPointDis
  923. ) {
  924. minPointDis = minDis.MinDis;
  925. Point = minDis.Point;
  926. }
  927. });
  928. }
  929. });
  930. return {
  931. MinDis: minPointDis,
  932. Point: Point
  933. };
  934. } // Function absorbSpacePoint()
  935. /**
  936. * 吸附空间线
  937. *
  938. * @param event 鼠标事件对象
  939. * @param absorbLen 吸附距离
  940. * @return PointToLine 吸附的线
  941. */
  942. absorbSpaceLine(event: SMouseEvent, absorbLen: number): PointToLine {
  943. let minPointDis = Number.MAX_SAFE_INTEGER;
  944. let Point, Line;
  945. this.spaceList.forEach((space): void => {
  946. if (
  947. EditScence.isPointInAbsorbArea(
  948. new SPoint(event.x, event.y),
  949. space.minX,
  950. space.maxX,
  951. space.minY,
  952. space.maxY
  953. )
  954. ) {
  955. space.data.OutLine.forEach((item): void => {
  956. let minDisLine = SMathUtil.getMinDisLine(
  957. new SPoint(event.x, event.y),
  958. item
  959. );
  960. if (
  961. minDisLine &&
  962. minDisLine.MinDis < absorbLen &&
  963. minDisLine.MinDis < minPointDis
  964. ) {
  965. minPointDis = minDisLine.MinDis;
  966. Point = minDisLine.Point;
  967. Line = minDisLine.Line;
  968. }
  969. });
  970. }
  971. });
  972. return {
  973. MinDis: minPointDis,
  974. Point: Point,
  975. Line: Line
  976. };
  977. } // Function absorbSpaceLine()
  978. }