EditScence.ts 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  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, ItemColor } 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. /** 当前选中焦点ItemList */
  59. focusItemList:SGraphItem[] | null = null;
  60. /**图例节点 */
  61. Nodes: any = []; // 图例节点,所有与工程信息化相关的图例(图标类型与区域)
  62. /**图例节点 */ // 与工程信息无关的标识对象(增加文本注释,图上的图片说明)
  63. Markers: any = [];
  64. /** 管线对象 */
  65. Relations: any = [];
  66. _isEditStatus: Boolean = true; // 是否可编辑
  67. set isEditStatus(bol: Boolean): void {
  68. this._isEditStatus = bol;
  69. }
  70. get isEditStatus(): Boolean {
  71. return this._isEditStatus
  72. }
  73. constructor() {
  74. super();
  75. // // 选择绑定选额item事件
  76. this.selectContainer.connect("listChange", this, this.listChange);
  77. ItemColor.spaceColor = new SColor("#A4ABB22B")
  78. ItemColor.wallColor = new SColor("#A7AEB3FF")
  79. ItemColor.columnColor = new SColor("#A7AEB3FF")
  80. ItemColor.virtualWallColor = new SColor("#A7AEB3FF")
  81. ItemColor.selectColor = new SColor("#84A0BB2B")
  82. ItemColor.spaceBorderColor = new SColor("#A7AEB3FF")
  83. }
  84. /** 绘制图例样式 */
  85. _legend: any | null = null;
  86. get getlegend(): any {
  87. return this._legend;
  88. };
  89. set setlegend(obj: any) {
  90. this._legend = obj;
  91. console.log('aaaaaa', obj)
  92. }
  93. /** fid=>item映射,由解析器存入 */
  94. fidToItem = {}
  95. /**
  96. * 监听变化
  97. * @param obj 变化后的对象
  98. */
  99. listChange(obj: any) {
  100. let itemType: string = 'equipment';
  101. this.focusItemList = obj.itemList;
  102. if (obj.itemList[0] instanceof STextMarkerItem) {
  103. itemType = 'baseText'
  104. } else if (obj.itemList[0] instanceof SImageMarkerItem) {
  105. itemType = 'baseImage'
  106. } else if (obj.itemList[0] instanceof SLineMarkerItem) {
  107. itemType = 'baseLine'
  108. } else if (obj.itemList[0] instanceof SZoneLegendItem) {
  109. itemType = 'Zone'
  110. } else if (obj.itemList[0] instanceof SFHFQZoneLegendItem) {
  111. itemType = 'Zone'
  112. } else if (obj.itemList[0] instanceof SSCPZZoneLegendItem) {
  113. itemType = 'Zone'
  114. } else if (obj.itemList[0] instanceof SImageLegendItem) {
  115. itemType = 'Image'
  116. } else if (obj.itemList[0] instanceof TipelineItem) {
  117. itemType = 'Line'
  118. } else if (obj.itemList[0] instanceof SSpaceItem) { // 点选
  119. this.clickToAddArea(obj.itemList[0]);
  120. return
  121. } else {
  122. itemType = ''
  123. };
  124. if (obj.itemList.length == 1) {
  125. // 获取聚焦item
  126. this.focusItem = obj.itemList[0]
  127. }else{
  128. this.focusItem = null
  129. }
  130. let msg = {
  131. itemList: obj.itemList,
  132. itemType,
  133. }
  134. this.emitChange(msg)
  135. }
  136. emitChange(msg: any) {
  137. }
  138. /**
  139. * 增加线段item
  140. */
  141. addLine(event: SMouseEvent): boolean {
  142. const clickItem = this.clickIsItem(event);
  143. if (clickItem) {
  144. let centerPoint = clickItem.boundingRect().center();
  145. const p = clickItem.mapToScene(centerPoint.x, centerPoint.y);
  146. event.x = p.x;
  147. event.y = p.y;
  148. }
  149. const data = {
  150. /** ID */
  151. ID: uuid(),
  152. /** 名称 */
  153. Name: '直线',
  154. /** 图标(Image),线类型(Line) */
  155. Type: "Line",
  156. /** 位置 */
  157. Pos: { X: 0, Y: 0 },
  158. /** 由应用自己定义 */
  159. Properties: {
  160. IconUrl: require("../../assets/images/t-line-hover.png"),
  161. Line: [{ X: event.x, Y: event.y }],
  162. LineWidth: 2
  163. }
  164. }
  165. const item = new SLineMarkerItem(null, data);
  166. item.status = SItemStatus.Create;
  167. item.zOrder = ItemOrder.lineOrder;
  168. item.selectable = true;
  169. this.addItem(item);
  170. this.Markers.push(item);
  171. item.connect("finishCreated", this, this.finishCreated);
  172. this.grabItem = item;
  173. this.focusItem = item;
  174. // 起始item点
  175. item.startItem = clickItem;
  176. if (clickItem) {
  177. clickItem.connect('onMove', item, item.changePos);
  178. }
  179. this.scenceUpdate(this);
  180. // this.undoStack.push(new SGraphAddCommand(this, item));
  181. // item.connect("onMove", this, this.onItemMove.bind(this));
  182. return true
  183. }
  184. /**
  185. * 增加折线item
  186. */
  187. addPolylineItem(event: SMouseEvent): boolean {
  188. const point = new SPoint(event.x, event.y)
  189. const item = new TipelineItem(null, [point]);
  190. //设置状态
  191. item.selectable = true;
  192. item.status = SItemStatus.Create;
  193. item.zOrder = ItemOrder.polylineOrder
  194. this.addItem(item);
  195. item.connect("finishCreated", this, this.finishCreated);
  196. // this.undoStack.push(new SGraphAddCommand(this, item));
  197. this.grabItem = item;
  198. this.focusItem = item;
  199. return true
  200. }
  201. /**
  202. * 增加管道 lenged
  203. */
  204. addTipelineItem(event: SMouseEvent): boolean {
  205. const anc = this.clickIsAnchor(event);
  206. if (anc) {
  207. const p = anc.mapToScene(0, 0)
  208. anc.isConnected = true;
  209. event.x = p.x;
  210. event.y = p.y;
  211. }
  212. const LegendData: Relation = {
  213. ID: uuid(),
  214. Name: this._legend.Name,
  215. GraphElementId: this._legend.Id,
  216. PointList: [{ X: event.x, Y: event.y }],
  217. LineType: "Line",
  218. Properties: {
  219. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  220. LineDash: this._legend.LineDash,
  221. LineWidth: this._legend.LineWidth,
  222. Color: this._legend.Color,
  223. },
  224. }
  225. const item = new TipelineItem(null, LegendData);
  226. //设置状态
  227. item.selectable = true;
  228. item.status = SItemStatus.Create;
  229. item.zOrder = ItemOrder.polylineOrder
  230. this.addItem(item);
  231. this.Relations.push(item);
  232. item.connect("finishCreated", this, this.finishCreated);
  233. // this.undoStack.push(new SGraphAddCommand(this, item));
  234. this.grabItem = item;
  235. this.focusItem = item;
  236. // 起始锚点
  237. item.startAnchor = anc;
  238. if (anc) {
  239. anc.parent ?.connect('changePos', item, item.changePos)
  240. item.anchor1ID = anc.id;
  241. item.node1Id = anc.parent.id;
  242. }
  243. this.scenceUpdate(this);
  244. return true
  245. }
  246. /**
  247. * 增加多边形item lenged
  248. */
  249. addPolygonItem(event: SMouseEvent): void {
  250. const SubType = this._legend.SubType ? this._legend.SubType : '';
  251. const LegendData: Legend = {
  252. ID: uuid(),
  253. Name: this._legend.Name,
  254. GraphElementType: this._legend.Type,
  255. Num: 1,
  256. GraphElementId: this._legend.Id,
  257. AttachObjectIds: [],
  258. Type: "Zone",
  259. Pos: { X: event.x, Y: event.y },
  260. OutLine: [{ X: event.x, Y: event.y }],
  261. SubType: SubType,
  262. Properties: {
  263. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  264. StrokeColor: this._legend.Color,
  265. FillColor: this._legend.FillColor,
  266. LineDash: this._legend.LineDash,
  267. LineWidth: this._legend.LineWidth,
  268. font: 0,
  269. color: '',
  270. TextPos: { X: 0, Y: 0 }
  271. },
  272. }
  273. let Polylines = null;
  274. if (SubType == "SCPZ") {
  275. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  276. } else if (SubType == "FHFQ") {
  277. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  278. } else {
  279. Polylines = new SZoneLegendItem(null, LegendData);
  280. }
  281. Polylines.selectable = true;
  282. //设置状态
  283. Polylines.status = SItemStatus.Create;
  284. Polylines.zOrder = ItemOrder.polygonOrder;
  285. // Polylines.moveable = true;
  286. this.addItem(Polylines);
  287. this.Nodes.push(Polylines);
  288. Polylines.connect("finishCreated", this, this.finishCreated);
  289. this.grabItem = Polylines;
  290. this.focusItem = Polylines;
  291. this.scenceUpdate(this);
  292. }
  293. /**
  294. * 点选创建区域
  295. */
  296. clickToAddArea(item: SSpaceItem): void {
  297. if (this.cmd != 'Zone') {
  298. return
  299. }
  300. if (this.isSelecting && this._legend) {
  301. //@ts-ignore
  302. item.isExtracted = true
  303. const SubType = this._legend.SubType ? this._legend.SubType : '';
  304. const LegendData: Legend = {
  305. ID: uuid(),
  306. Name: this._legend.Name,
  307. GraphElementType: this._legend.Type,
  308. Num: 1,
  309. GraphElementId: this._legend.Id,
  310. AttachObjectIds: [],
  311. Type: "Zone",
  312. Pos: { X: item.x, Y: item.y },
  313. OutLine: item.pointArr[0],
  314. SubType: SubType,
  315. Properties: {
  316. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  317. StrokeColor: this._legend.Color,
  318. FillColor: this._legend.FillColor,
  319. LineDash: this._legend.LineDash,
  320. LineWidth: this._legend.LineWidth,
  321. font: 12,
  322. color: '',
  323. FID: item.data.SourceId,
  324. TextPos: { X: item.data.Location.Points[0].X, Y: -item.data.Location.Points[0].Y }
  325. },
  326. }
  327. let Polylines = null;
  328. if (SubType == "SCPZ") {
  329. Polylines = new SSCPZZoneLegendItem(null, LegendData);
  330. } else if (SubType == "FHFQ") {
  331. Polylines = new SFHFQZoneLegendItem(null, LegendData);
  332. } else {
  333. Polylines = new SZoneLegendItem(null, LegendData);
  334. }
  335. Polylines.selectable = true;
  336. //设置状态
  337. Polylines.status = SItemStatus.Normal;
  338. this.addItem(Polylines);
  339. this.Nodes.push(Polylines);
  340. Polylines.connect("finishCreated", this, this.finishCreated);
  341. this.finishCreated(Polylines)
  342. this.focusItem = Polylines;
  343. this.scenceUpdate(this);
  344. }
  345. }
  346. /**
  347. * 增加图片Item mark
  348. */
  349. addImgItem(event: SMouseEvent) {
  350. const data = {
  351. /** ID */
  352. ID: uuid(),
  353. /** 名称 */
  354. Name: '图片',
  355. Num: 1,
  356. /** 图标(Image),线类型(Line) */
  357. Type: "Image",
  358. /** 位置 */
  359. Pos: { X: event.x, Y: event.y },
  360. /** 由应用自己定义 */
  361. Properties: {
  362. IconUrl: require(`../../assets/images/t-img-hover.png`),
  363. Url: '',
  364. }
  365. }
  366. const item = new SImageMarkerItem(null, data);
  367. item.zOrder = ItemOrder.imageOrder;
  368. item.selectable = true;
  369. item.moveable = true;
  370. this.addItem(item);
  371. this.Markers.push(item);
  372. this.grabItem == null;
  373. this.focusItem = item;
  374. this.cmd = 'choice';
  375. this.scenceUpdate(this);
  376. }
  377. /**
  378. * 增加文字item
  379. */
  380. addTextItem(event: SMouseEvent): void {
  381. const data = {
  382. /** ID */
  383. ID: uuid(),
  384. /** 名称 */
  385. Name: '文本',
  386. /** 图标 */
  387. Type: "Text",
  388. /** 位置 */
  389. Pos: { X: event.x, Y: event.y },
  390. /** 由应用自己定义 */
  391. Properties: {
  392. IconUrl: require(`../../assets/images/t-text-hover.png`),
  393. Text: '请在右侧属性栏输入文字!',
  394. Color: '',
  395. Font: 12,
  396. BackgroundColor: '#f7f9fa'
  397. }
  398. }
  399. const item = new STextMarkerItem(null, data);
  400. item.moveTo(event.x, event.y);
  401. item.selectable = true;
  402. item.moveable = true;
  403. item.zOrder = ItemOrder.textOrder;
  404. this.addItem(item);
  405. this.Markers.push(item);
  406. this.grabItem = item;
  407. this.focusItem = item;
  408. this.cmd = 'choice';
  409. this.scenceUpdate(this);
  410. }
  411. /**
  412. * 增加图标lenged图标
  413. */
  414. addIconItem(event: SMouseEvent): void {
  415. //获取信息工程化相关参数
  416. const LegendData: Legend = {
  417. ID: uuid(),
  418. Name: this._legend.Name,
  419. GraphElementType: this._legend.Type,
  420. Num: 1,
  421. GraphElementId: this._legend.Id,
  422. AttachObjectIds: [],
  423. Pos: { X: event.x, Y: event.y },
  424. Scale: { X: 1, Y: 1, Z: 1 }, // 缩放
  425. Rolate: { X: 0, Y: 0, Z: 0 },
  426. Size: { Width: 0, Height: 0 }, // 大小
  427. Type: this._legend.Type,
  428. Properties: {
  429. IconUrl: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  430. Url: '/serve/topology-wanda/Picture/query/' + this._legend.Url,
  431. Num: 1, // 此num与信息工程化得num无关
  432. sWidth: 24, //icon 的宽
  433. sHeight: 24, //icon 的高
  434. font: 12, //font
  435. color: '', //字体颜色
  436. GraphCategoryId: this._legend.GraphCategoryId
  437. },
  438. }
  439. const item = new SImageLegendItem(null, LegendData);
  440. this.cmd = 'choice';
  441. item.selectable = true;
  442. item.moveable = true;
  443. item.zOrder = ItemOrder.markOrder;
  444. this.addItem(item);
  445. this.Nodes.push(item);
  446. this.grabItem = item;
  447. this.focusItem = item;
  448. this.scenceUpdate(this);
  449. }
  450. /**
  451. * 更改item对应属性
  452. */
  453. editItemStatus(): void {
  454. }
  455. /**
  456. * 更改文本对应属性
  457. * @param str string 文字内容
  458. */
  459. updatedText(str: string): void {
  460. if (this.focusItem) {
  461. const old = this.focusItem.text;
  462. this.focusItem.text = str;
  463. this.scenceUpdate(this);
  464. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "text", old, str));
  465. }
  466. }
  467. /**
  468. * 更改文本fontSize属性
  469. * @param size number 文字大小
  470. */
  471. updatedFontSize(size: number): void {
  472. if (this.focusItem) {
  473. let old = new SFont(this.focusItem.font);
  474. let font = new SFont(this.focusItem.font);
  475. font.size = size;
  476. this.focusItem.font = font;
  477. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font));
  478. }
  479. }
  480. /**
  481. * 更改线宽属性
  482. * @param lineWidth number 线宽大小
  483. */
  484. updatedLineWidth(lineWidth: number): void {
  485. if (this.focusItem) {
  486. // let old = new SFont(this.focusItem.font);
  487. // let font = new SFont(this.focusItem.font);
  488. // font.size = size;
  489. this.focusItem.lineWidth = lineWidth;
  490. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "font", old, font));
  491. }
  492. }
  493. /**
  494. * 更改文本颜色属性
  495. * @param str string 颜色
  496. */
  497. updatedFontColor(color: string): void {
  498. if (this.focusItem) {
  499. let old = this.focusItem.color;
  500. this.focusItem.color = new SColor(color);
  501. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  502. }
  503. }
  504. /**
  505. * 更改border颜色
  506. * @param color string 颜色
  507. */
  508. updatedBorderColor(color: string): void {
  509. if (this.focusItem) {
  510. if (this.focusItem instanceof SZoneLegendItem || this.focusItem instanceof SSCPZZoneLegendItem || this.focusItem instanceof SFHFQZoneLegendItem) {
  511. this.focusItem.strokeColor = new SColor(color);
  512. } else {
  513. // let old = this.focusItem.strokeColor;
  514. this.focusItem.strokeColor = new SColor(color);
  515. }
  516. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  517. }
  518. }
  519. /**
  520. * 更改item宽
  521. * @param width number 颜色
  522. */
  523. updatedWidth(width: number): void {
  524. if (this.focusItem) {
  525. // let old = this.focusItem.width;
  526. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  527. this.focusItem.sWidth = width;
  528. } else {
  529. this.focusItem.width = width;
  530. }
  531. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  532. }
  533. }
  534. /**
  535. * 更改item高
  536. * @param height number 颜色
  537. */
  538. updatedHeight(height: number): void {
  539. if (this.focusItem) {
  540. // let old = this.focusItem.width;
  541. if (this.focusItem.data && this.focusItem.data.GraphElementType && this.focusItem.data.GraphElementType == "Image") {
  542. this.focusItem.sHeight = height;
  543. } else {
  544. this.focusItem.height = height;
  545. }
  546. // this.undoStack.push(new SGraphPropertyCommand(this, this.focusItem, "color", old, color));
  547. }
  548. }
  549. /**
  550. * 更改item坐标
  551. * @param x number x x坐标
  552. * @param y number y y坐标
  553. */
  554. updatedPosition(x: number, y: number): void {
  555. if (this.focusItem) {
  556. let p = this.focusItem.mapFromScene(x, y)
  557. // newx - oldx = newleft - oldleft
  558. // 要求的值(新的x坐标) - 旧的x坐标 = 新的左边界(用户输入的值) - 旧的左边界
  559. this.focusItem.x = p.x - this.focusItem.boundingRect().left + this.focusItem.x;
  560. this.focusItem.y = p.y - this.focusItem.boundingRect().top + this.focusItem.y;
  561. }
  562. }
  563. /**
  564. * 更改item 背景色坐标
  565. * @param color string 颜色color
  566. */
  567. updatedbackColor(color: string): void {
  568. if (this.focusItem) {
  569. this.focusItem.backgroundColor = new SColor(color);
  570. }
  571. }
  572. /**
  573. * 更改item Url
  574. * @param url string 图片key
  575. */
  576. upadataImageUrl(url: string): void {
  577. if (this.focusItem) {
  578. this.focusItem.url = '/serve/topology-wanda/Picture/query/' + url;
  579. }
  580. }
  581. /**
  582. * 更改item border
  583. * @param val string border类型
  584. */
  585. upadataBorder(val: string): void {
  586. if (this.focusItem) {
  587. let borderStyle = null;
  588. if (val == 'dashed') {
  589. borderStyle = SLineStyle.Dashed;
  590. } else if (val == 'dotted') {
  591. borderStyle = SLineStyle.Dotted;
  592. } else if (val == 'solid') {
  593. borderStyle = SLineStyle.Soild;
  594. }
  595. this.focusItem.lineStyle = borderStyle;
  596. }
  597. }
  598. /**
  599. * 更改item 名称
  600. * @param val string border类型
  601. */
  602. upadataLengedName(val: string): void {
  603. if (this.focusItem && this.focusItem.data) {
  604. this.focusItem.text = val;
  605. this.scenceUpdate(this);
  606. }
  607. }
  608. /**
  609. * 更改item Num数量
  610. * @param num number item数量 (只对icon设备类)
  611. */
  612. upadatImageNum(num: number): void {
  613. if (this.focusItem && this.focusItem.num) {
  614. this.focusItem.num = num;
  615. }
  616. }
  617. /**
  618. * 更改item Num数量
  619. * @param num number item数量 (只对icon设备类)
  620. */
  621. upadatfillColor(fillColor: string): void {
  622. if (this.focusItem && this.focusItem.fillColor) {
  623. this.focusItem.fillColor = new SColor(fillColor);
  624. }
  625. }
  626. /**
  627. * 更改图例说
  628. * @param num number
  629. */
  630. upadatitemExplain(ItemExplain: string): void {
  631. if (this.focusItem) {
  632. this.focusItem.data.Properties.ItemExplain = ItemExplain;
  633. }
  634. }
  635. /**
  636. * 更新工程信息化的相关数据
  637. * @param AttachObjectIds Array
  638. */
  639. upadatAttachObjectIds(AttachObjectIds: []): void {
  640. console.log('AttachObjectIds',AttachObjectIds)
  641. if (this.focusItem) {
  642. this.focusItem.data.AttachObjectIds = AttachObjectIds;
  643. }
  644. }
  645. /**
  646. * 删除指定item
  647. */
  648. deleiteItem(): void {
  649. if (this.focusItem) {
  650. if ((this.focusItem instanceof SZoneLegendItem ||
  651. this.focusItem instanceof SSCPZZoneLegendItem ||
  652. this.focusItem instanceof SFHFQZoneLegendItem ||
  653. this.focusItem instanceof TipelineItem) &&
  654. this.focusItem.curIndex != -1
  655. ) {
  656. this.focusItem.deletePoint(this.focusItem.curIndex);
  657. } else {
  658. this.removeItem(this.focusItem);
  659. let a = -1
  660. this.Nodes.forEach((item: any, index: number) => {
  661. if (item.id == this.focusItem.id) {
  662. a = index
  663. }
  664. });
  665. if (a > -1) {
  666. this.Nodes.splice(a, 1);
  667. }
  668. let b = -1;
  669. this.Markers.forEach((item: any, index: number) => {
  670. if (item.id == this.focusItem.id) {
  671. b = index
  672. }
  673. });
  674. if (b > -1) {
  675. this.Markers.splice(b, 1);
  676. }
  677. let c = -1;
  678. this.Relations.forEach((item: any, index: number) => {
  679. if (item.id == this.focusItem.id) {
  680. c = index
  681. }
  682. });
  683. if (c > -1) {
  684. this.Relations.splice(c, 1);
  685. }
  686. this.focusItem = null;
  687. if (this.view) {
  688. this.view.update();
  689. }
  690. this.scenceUpdate(this);
  691. }
  692. }else{
  693. //批量删除
  694. if(!this.focusItemList){
  695. return
  696. }
  697. this.focusItemList.forEach((focusItem)=>{
  698. this.removeItem(focusItem);
  699. let a = -1
  700. this.Nodes.forEach((item: any, index: number) => {
  701. if (item.id == focusItem.id) {
  702. a = index
  703. }
  704. });
  705. if (a > -1) {
  706. this.Nodes.splice(a, 1);
  707. }
  708. let b = -1;
  709. this.Markers.forEach((item: any, index: number) => {
  710. if (item.id == focusItem.id) {
  711. b = index
  712. }
  713. });
  714. if (b > -1) {
  715. this.Markers.splice(b, 1);
  716. }
  717. let c = -1;
  718. this.Relations.forEach((item: any, index: number) => {
  719. if (item.id == focusItem.id) {
  720. c = index
  721. }
  722. });
  723. if (c > -1) {
  724. this.Relations.splice(c, 1);
  725. }
  726. });
  727. this.focusItemList = [];
  728. if (this.view) {
  729. this.view.update();
  730. }
  731. this.scenceUpdate(this);
  732. }
  733. }
  734. scenceUpdate(scence: any) { }
  735. /**
  736. * 对齐指定item
  737. * @param v
  738. */
  739. changeAlignItem(v: any): void {
  740. this.selectContainer.layout(v);
  741. }
  742. /**
  743. * 提取item
  744. */
  745. extractItem(): void {
  746. console.log(this)
  747. }
  748. /**
  749. * 保存数据
  750. */
  751. saveMsgItem(): any {
  752. const Nodes: any = [];
  753. const Markers: any = [];
  754. const Relations: any = [];
  755. this.Nodes.forEach(e => {
  756. Nodes.push(e.toData())
  757. });
  758. this.Markers.forEach(e => {
  759. Markers.push(e.toData())
  760. });
  761. this.Relations.forEach(e => {
  762. Relations.push(e.toData())
  763. });
  764. let element = {
  765. Nodes, Markers, Relations
  766. }
  767. return element
  768. }
  769. /**
  770. * 锁住item
  771. */
  772. lockItem(): void {
  773. }
  774. /**
  775. * 执行取消操作
  776. */
  777. redo(): void {
  778. this.undoStack.undo();
  779. }
  780. /**
  781. * 执行重做操作执行
  782. */
  783. undo(): void {
  784. this.undoStack.redo();
  785. }
  786. /**
  787. * 完成事件创建的回调函数
  788. */
  789. finishCreated(item: any) {
  790. this.setCmd = 'choice';
  791. this.focusItem = item;
  792. this.selectContainer.toggleItem(item)
  793. }
  794. ////////////////////////
  795. // 以下为鼠标键盘操作事件
  796. onMouseDown(event: SMouseEvent): any {
  797. if (!this.isEditStatus) {
  798. return super.onMouseDown(event);
  799. }
  800. // 判断是否开启吸附,并且有吸附的点
  801. if (
  802. this.isAbsorbing &&
  803. this.highLight &&
  804. this.highLight.visible
  805. ) {
  806. event.x = this.highLight.point.x;
  807. event.y = this.highLight.point.y;
  808. }
  809. if (this.grabItem) {
  810. if (this.grabItem instanceof TipelineItem) {
  811. this.setTipeEndanchor(event)
  812. return true;
  813. } else if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Create) {
  814. this.setLineItem(event)
  815. return true;
  816. }
  817. return this.grabItem.onMouseDown(event);
  818. }
  819. switch (this.cmd) {
  820. case 'baseLine':
  821. this.addLine(event);
  822. break;
  823. case 'baseText':
  824. this.addTextItem(event);
  825. break;
  826. case 'baseImage':
  827. this.addImgItem(event)
  828. break;
  829. case 'Zone':
  830. if (!this.isSelecting) {
  831. this.addPolygonItem(event);
  832. } else {
  833. // 点选创建区域
  834. return super.onMouseDown(event)
  835. }
  836. break;
  837. case 'Image':
  838. this.addIconItem(event);
  839. break;
  840. case 'Line':
  841. this.addTipelineItem(event);
  842. break;
  843. default:
  844. return super.onMouseDown(event);
  845. }
  846. }
  847. onMouseMove(event: SMouseEvent): boolean {
  848. if (!this.isEditStatus) {
  849. return super.onMouseMove(event);
  850. }
  851. if (this.isAbsorbing) {
  852. if (!this.highLight) {
  853. this.highLight = new HighlightItem(null);
  854. this.addItem(this.highLight);
  855. }
  856. this.highLight.visible = false;
  857. this.absorbSpace(event);
  858. }
  859. return super.onMouseMove(event)
  860. }
  861. onMouseUp(event: SMouseEvent): boolean {
  862. if (this.grabItem) {
  863. if (this.grabItem instanceof SLineMarkerItem && this.grabItem.status == SItemStatus.Edit) {
  864. this.setLineItem(event)
  865. return true;
  866. }
  867. return this.grabItem.onMouseUp(event);
  868. }
  869. return super.onMouseUp(event)
  870. }
  871. /**
  872. * 键盘事件
  873. *
  874. * @param event 事件参数
  875. * @return boolean
  876. */
  877. onKeyDown(event: KeyboardEvent): any {
  878. if (!this.isEditStatus) {
  879. return super.onKeyDown(event);
  880. }
  881. if (this.grabItem) {
  882. this.grabItem.onKeyDown(event);
  883. if (event.code == "Escape") {
  884. const item = this.grabItem;
  885. this.grabItem = null
  886. this.removeItem(item);
  887. if (this.view) {
  888. this.view.update()
  889. }
  890. this.setCmd = 'choice'
  891. }
  892. }
  893. // if (event.key == "Enter") {
  894. // this.cmd = 0
  895. // }
  896. return false
  897. }
  898. /**
  899. * 鼠标双击事件
  900. *
  901. * @param event 事件参数
  902. * @return boolean
  903. */
  904. onDoubleClick(event: SMouseEvent): boolean {
  905. if (!this.isEditStatus) {
  906. return true
  907. }else{
  908. return super.onDoubleClick(event);
  909. }
  910. } // Function onDoubleClick()
  911. /**
  912. * 设置管线结束锚点
  913. *
  914. */
  915. setTipeEndanchor(event: SMouseEvent): void {
  916. if (this.grabItem instanceof TipelineItem) {
  917. if (this.grabItem.status == SItemStatus.Create) {
  918. const anc = this.clickIsAnchor(event);
  919. if (anc) {
  920. const p = anc.mapToScene(0, 0)
  921. anc.isConnected = true;
  922. event.x = p.x;
  923. event.y = p.y;
  924. if (this.grabItem.pointList.length) {
  925. this.grabItem.endAnchor = anc;
  926. anc.parent ?.connect('changePos', this.grabItem, this.grabItem.changePos)
  927. }
  928. this.grabItem.anchor2ID = anc.id
  929. this.grabItem.node2Id = anc.parent.id
  930. this.grabItem.onMouseDown(event)
  931. this.grabItem.status = SItemStatus.Normal;
  932. this.finishCreated(this.grabItem)
  933. return
  934. }
  935. }
  936. this.grabItem.onMouseDown(event)
  937. }
  938. }
  939. /**
  940. * 设置直线结束Item
  941. *
  942. */
  943. setLineItem(event: SMouseEvent): void {
  944. if (this.grabItem instanceof SLineMarkerItem) {
  945. const item = this.clickIsItem(event);
  946. // 鼠标点是否在某个item内
  947. if (item) {
  948. let scenePoint = item.boundingRect().center();
  949. const p = item.mapToScene(scenePoint.x, scenePoint.y);
  950. event.x = p.x;
  951. event.y = p.y;
  952. if (this.grabItem.status == SItemStatus.Create) {
  953. // 点击在item内、创建状态且端点列表不为空时将直线结束端点和item绑定
  954. if (this.grabItem.line.length) {
  955. if (this.grabItem.startItem?.id == item.id) {
  956. this.grabItem.endItem = null;
  957. } else {
  958. this.grabItem.endItem = item;
  959. this.grabItem.line[1] = new SPoint(event.x, event.y);
  960. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  961. }
  962. }
  963. this.grabItem.onMouseDown(event);
  964. return
  965. } else if (this.grabItem.status == SItemStatus.Edit) {
  966. // 点击在item内、编辑状态且点击的为结束端点时
  967. if (this.grabItem.curIndex == 1) {
  968. // 直线关联的起始item是直线结束端点所在的item时,不吸附在点击item中心并将直线关联的结束item置为null
  969. if (this.grabItem.startItem?.id == item.id) {
  970. this.grabItem.endItem = null;
  971. } else {// 反正吸附,关联
  972. this.grabItem.endItem = item;
  973. this.grabItem.line[1] = new SPoint(event.x, event.y);
  974. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  975. }
  976. } else if (this.grabItem.curIndex == 0) {
  977. if (this.grabItem.endItem?.id == item.id) {
  978. this.grabItem.startItem = null;
  979. } else {
  980. this.grabItem.startItem = item;
  981. this.grabItem.line[0] = new SPoint(event.x, event.y);
  982. item.connect('onMove', this.grabItem, this.grabItem.changePos);
  983. }
  984. }
  985. }
  986. } else {
  987. // 如果不在item内且点击的是直线的某个端点,将端点的关联item置为null
  988. if (this.grabItem.line.length && this.grabItem.curIndex != -1) {
  989. if (this.grabItem.curIndex == 1) {
  990. this.grabItem.endItem = null;
  991. } else if (this.grabItem.curIndex == 0) {
  992. this.grabItem.startItem = null;
  993. }
  994. } else {
  995. this.grabItem.onMouseDown(event);
  996. return
  997. }
  998. }
  999. // if (this.grabItem.status == SItemStatus.Create) {
  1000. // // 鼠标点是否在某个item内
  1001. // if (item) {
  1002. // let scenePoint = item.boundingRect().center();
  1003. // const p = item.mapToScene(scenePoint.x, scenePoint.y);
  1004. // event.x = p.x;
  1005. // event.y = p.y;
  1006. // if (this.grabItem.line.length && this.grabItem.curIndex == -1) {
  1007. // this.grabItem.endItem = item;
  1008. // this.grabItem.line[1] = new SPoint(event.x, event.y);
  1009. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1010. // }
  1011. // this.grabItem.onMouseDown(event);
  1012. // return
  1013. // } else {
  1014. // if (this.grabItem.line.length && this.grabItem.curIndex != -1) {
  1015. // if (this.grabItem.curIndex == 1) {
  1016. // this.grabItem.endItem = null;
  1017. // } else if (this.grabItem.curIndex == 0) {
  1018. // this.grabItem.startItem = null;
  1019. // }
  1020. // }
  1021. // }
  1022. // } else if (this.grabItem.status == SItemStatus.Edit) {
  1023. // if (this.grabItem.curIndex == 1) {
  1024. // this.grabItem.endItem = item;
  1025. // this.grabItem.line[1] = new SPoint(event.x, event.y);
  1026. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1027. // } else if (this.grabItem.curIndex == 0) {
  1028. // this.grabItem.startItem = item;
  1029. // this.grabItem.line[0] = new SPoint(event.x, event.y);
  1030. // item.connect('onMove', this.grabItem, this.grabItem.changePos);
  1031. // }
  1032. // }
  1033. this.grabItem.onMouseUp(event);
  1034. }
  1035. }
  1036. /**
  1037. * 划线时点击位置是否是锚点
  1038. *
  1039. * @param event 事件
  1040. * @param len 限制距离
  1041. * @return 点击的锚点
  1042. * */
  1043. clickIsAnchor(event: SMouseEvent): SAnchorItem | null {
  1044. let minAnchor = null;
  1045. let len: number = -1;
  1046. this.Nodes.forEach(image => {
  1047. if (image.anchorList && image.anchorList.length) {
  1048. image.anchorList.forEach(anchor => {
  1049. let anchorPoint = anchor.mapToScene(0, 0);
  1050. let dis = SMathUtil.pointDistance(
  1051. event.x,
  1052. event.y,
  1053. anchorPoint.x,
  1054. anchorPoint.y
  1055. );
  1056. if (len < 0) {
  1057. len = anchor.sceneDis;
  1058. }
  1059. if (dis < len) {
  1060. minAnchor = anchor;
  1061. len = dis;
  1062. }
  1063. })
  1064. }
  1065. })
  1066. console.log('-----------------------')
  1067. console.log(minAnchor)
  1068. console.log('-----------------------')
  1069. return minAnchor;
  1070. }
  1071. /**
  1072. * 划线时点击位置是在文本,图片,,区域内
  1073. *
  1074. * @param event 事件
  1075. * @return 点击的item
  1076. * */
  1077. clickIsItem(event: SMouseEvent): SGraphItem | null {
  1078. let minIten = null;
  1079. let len: number = -1;
  1080. let itemList = this.Nodes.concat(this.Markers);
  1081. itemList.forEach(item => {
  1082. if (
  1083. item instanceof STextMarkerItem ||
  1084. item instanceof SImageMarkerItem ||
  1085. item instanceof SZoneLegendItem ||
  1086. item instanceof SFHFQZoneLegendItem ||
  1087. item instanceof SSCPZZoneLegendItem
  1088. ) {
  1089. let scenePoint = item.mapFromScene(event.x, event.y);
  1090. if (item.contains(scenePoint.x, scenePoint.y)) {
  1091. let dis = SMathUtil.pointDistance(
  1092. scenePoint.x,
  1093. scenePoint.y,
  1094. item.boundingRect().center().x,
  1095. item.boundingRect().center().y
  1096. );
  1097. if (len < 0) {
  1098. minIten = item;
  1099. len = dis;
  1100. }
  1101. if (dis < len) {
  1102. minIten = item;
  1103. len = dis;
  1104. }
  1105. }
  1106. }
  1107. })
  1108. console.log('-----------------------')
  1109. console.log(minIten)
  1110. console.log('-----------------------')
  1111. return minIten;
  1112. }
  1113. /**
  1114. * 点是否在吸附区域内
  1115. *
  1116. * @param p 要判断的点
  1117. * @param minX 空间区域
  1118. * @param minY 空间区域
  1119. * @param maxX 空间区域
  1120. * @param maxY 空间区域
  1121. */
  1122. static isPointInAbsorbArea(
  1123. p: SPoint,
  1124. minX: number,
  1125. maxX: number,
  1126. minY: number,
  1127. maxY: number
  1128. ): boolean {
  1129. let rect = new SRect(
  1130. minX - 1000,
  1131. minY - 1000,
  1132. maxX - minX + 2000,
  1133. maxY - minY + 2000
  1134. );
  1135. return rect.contains(p.x, p.y);
  1136. } // Function isPointInAbsorbArea()
  1137. /**
  1138. * 吸附空间
  1139. *
  1140. * @param event 鼠标事件对象
  1141. * @return boolean 是否找到吸附的对象
  1142. */
  1143. absorbSpace(event: SMouseEvent): boolean {
  1144. if (!this.highLight) {
  1145. return false;
  1146. }
  1147. let absorbLen = 1000;
  1148. if (this.view) {
  1149. absorbLen = 10 / this.view.scale;
  1150. }
  1151. let P = this.absorbSpacePoint(event, absorbLen);
  1152. if (P.Point) {
  1153. this.highLight.distance = P.MinDis;
  1154. this.highLight.point = new SPoint(P.Point.X, -P.Point.Y);
  1155. this.highLight.visible = true;
  1156. return true;
  1157. } else {
  1158. let L = this.absorbSpaceLine(event, absorbLen);
  1159. if (L.Line && L.Point) {
  1160. this.highLight.distance = L.MinDis;
  1161. this.highLight.point = L.Point;
  1162. this.highLight.line = L.Line;
  1163. this.highLight.visible = true;
  1164. return true;
  1165. }
  1166. return false;
  1167. }
  1168. } // Function absorbSpace()
  1169. /**
  1170. * 吸附空间点
  1171. *
  1172. * @param event 鼠标事件对象
  1173. * @param absorbLen 吸附距离
  1174. * @return MinDis 吸附的点
  1175. */
  1176. absorbSpacePoint(event: SMouseEvent, absorbLen: number): MinDis {
  1177. let minPointDis = Number.MAX_SAFE_INTEGER;
  1178. let Point;
  1179. this.spaceList.map((space): void => {
  1180. if (
  1181. EditScence.isPointInAbsorbArea(
  1182. new SPoint(event.x, event.y),
  1183. space.minX,
  1184. space.maxX,
  1185. space.minY,
  1186. space.maxY
  1187. )
  1188. ) {
  1189. space.data.OutLine.forEach((item): void => {
  1190. let minDis = SMathUtil.getMinDisPoint(
  1191. new SPoint(event.x, event.y),
  1192. item
  1193. );
  1194. if (
  1195. minDis &&
  1196. minDis.MinDis < absorbLen &&
  1197. minDis.MinDis < minPointDis
  1198. ) {
  1199. minPointDis = minDis.MinDis;
  1200. Point = minDis.Point;
  1201. }
  1202. });
  1203. }
  1204. });
  1205. return {
  1206. MinDis: minPointDis,
  1207. Point: Point
  1208. };
  1209. } // Function absorbSpacePoint()
  1210. /**
  1211. * 吸附空间线
  1212. *
  1213. * @param event 鼠标事件对象
  1214. * @param absorbLen 吸附距离
  1215. * @return PointToLine 吸附的线
  1216. */
  1217. absorbSpaceLine(event: SMouseEvent, absorbLen: number): PointToLine {
  1218. let minPointDis = Number.MAX_SAFE_INTEGER;
  1219. let Point, Line;
  1220. this.spaceList.forEach((space): void => {
  1221. if (
  1222. EditScence.isPointInAbsorbArea(
  1223. new SPoint(event.x, event.y),
  1224. space.minX,
  1225. space.maxX,
  1226. space.minY,
  1227. space.maxY
  1228. )
  1229. ) {
  1230. space.data.OutLine.forEach((item): void => {
  1231. let minDisLine = SMathUtil.getMinDisLine(
  1232. new SPoint(event.x, event.y),
  1233. item
  1234. );
  1235. if (
  1236. minDisLine &&
  1237. minDisLine.MinDis < absorbLen &&
  1238. minDisLine.MinDis < minPointDis
  1239. ) {
  1240. minPointDis = minDisLine.MinDis;
  1241. Point = minDisLine.Point;
  1242. Line = minDisLine.Line;
  1243. }
  1244. });
  1245. }
  1246. });
  1247. return {
  1248. MinDis: minPointDis,
  1249. Point: Point,
  1250. Line: Line
  1251. };
  1252. } // Function absorbSpaceLine()
  1253. }