YaolongHan 4 rokov pred
rodič
commit
536277e156
74 zmenil súbory, kde vykonal 6778 pridanie a 37 odobranie
  1. 0 0
      persagy-web-big-edit/BigEditFactory.ts
  2. 0 0
      persagy-web-big-edit/SBaseEditScene.ts
  3. 13 0
      persagy-web-big-edit/index.ts
  4. 0 0
      persagy-web-big-edit/items/SBaseArrow.ts
  5. 0 0
      persagy-web-big-edit/items/SBaseEquipment.ts
  6. 0 0
      persagy-web-big-edit/items/SBaseExpainEdit.ts
  7. 0 0
      persagy-web-big-edit/items/SBasePipe.ts
  8. 0 0
      persagy-web-big-edit/items/SBasePipeUninTool.ts
  9. 0 0
      persagy-web-big-edit/parsers/bigEditParse.ts
  10. 0 0
      persagy-web-big-edit/types/Anchor.ts
  11. 0 0
      persagy-web-big-edit/types/ElementData.ts
  12. 0 0
      persagy-web-big-edit/types/Legend.ts
  13. 54 0
      persagy-web-big-edit/types/Marker.ts
  14. 0 0
      persagy-web-big-edit/types/Relation.ts
  15. 0 0
      persagy-web-big-edit/until.ts
  16. 72 0
      persagy-web-big/src/config/ItemColor.ts
  17. 72 0
      persagy-web-big/src/config/ItemOrder.ts
  18. 135 0
      persagy-web-big/src/config/Transparency.ts
  19. 42 0
      persagy-web-big/src/enums/SGraphElementType.ts
  20. 40 0
      persagy-web-big/src/enums/SItemStatus.ts
  21. 36 0
      persagy-web-big/src/enums/SLineType.ts
  22. 40 0
      persagy-web-big/src/enums/SMarkerType.ts
  23. 40 0
      persagy-web-big/src/enums/SRelationDir.ts
  24. 42 0
      persagy-web-big/src/enums/SRelationState.ts
  25. 122 0
      persagy-web-big/src/factories/SItemFactory.ts
  26. 32 0
      persagy-web-big/src/factories/STopoItemFactory.ts
  27. 67 13
      persagy-web-big/src/index.ts
  28. 91 0
      persagy-web-big/src/items/SArrowItem.ts
  29. 34 0
      persagy-web-big/src/items/SArrowPoly.ts
  30. 422 0
      persagy-web-big/src/items/SIconTextItem.ts
  31. 34 0
      persagy-web-big/src/items/SLayerItem.ts
  32. 535 0
      persagy-web-big/src/items/SLineItem.ts
  33. 846 0
      persagy-web-big/src/items/SPolygonItem.ts
  34. 643 0
      persagy-web-big/src/items/SPolylineItem.ts
  35. 90 0
      persagy-web-big/src/items/SRectSelectItem.ts
  36. 34 0
      persagy-web-big/src/items/STooltipItem.ts
  37. 104 0
      persagy-web-big/src/items/floor/SBoardItem.ts
  38. 67 0
      persagy-web-big/src/items/floor/SColumnItem.ts
  39. 158 0
      persagy-web-big/src/items/floor/SDoorItem.ts
  40. 100 0
      persagy-web-big/src/items/floor/SHighlightItem.ts
  41. 183 0
      persagy-web-big/src/items/floor/SSpaceItem.ts
  42. 253 0
      persagy-web-big/src/items/floor/SSpaceItems.ts
  43. 118 0
      persagy-web-big/src/items/floor/SVirtualWallItem.ts
  44. 70 0
      persagy-web-big/src/items/floor/SWallItem.ts
  45. 151 0
      persagy-web-big/src/items/floor/SWallItems.ts
  46. 109 0
      persagy-web-big/src/items/floor/SWindowItem.ts
  47. 203 0
      persagy-web-big/src/items/floor/ZoneItem.ts
  48. 163 0
      persagy-web-big/src/parser/SFloorParser.ts
  49. 48 0
      persagy-web-big/src/parser/SParser.ts
  50. 85 0
      persagy-web-big/src/parser/STopologyParser.ts
  51. 60 0
      persagy-web-big/src/parser/SZoneParser.ts
  52. 38 0
      persagy-web-big/src/types/BigPoint.ts
  53. 52 0
      persagy-web-big/src/types/FloorData.ts
  54. 47 0
      persagy-web-big/src/types/ImageData.ts
  55. 11 24
      persagy-web-big/src/types/Marker.ts
  56. 39 0
      persagy-web-big/src/types/MinDis.ts
  57. 39 0
      persagy-web-big/src/types/Outline.ts
  58. 39 0
      persagy-web-big/src/types/Place.ts
  59. 41 0
      persagy-web-big/src/types/PointToLine.ts
  60. 37 0
      persagy-web-big/src/types/Size.ts
  61. 53 0
      persagy-web-big/src/types/TextData.ts
  62. 43 0
      persagy-web-big/src/types/TopologyData.ts
  63. 55 0
      persagy-web-big/src/types/floor/Casement.ts
  64. 49 0
      persagy-web-big/src/types/floor/Column.ts
  65. 59 0
      persagy-web-big/src/types/floor/Door.ts
  66. 55 0
      persagy-web-big/src/types/floor/Space.ts
  67. 46 0
      persagy-web-big/src/types/floor/VirtualWall.ts
  68. 52 0
      persagy-web-big/src/types/floor/Wall.ts
  69. 51 0
      persagy-web-big/src/types/floor/Zone.ts
  70. 39 0
      persagy-web-big/src/types/topology/Anchor.ts
  71. 52 0
      persagy-web-big/src/types/topology/MarkerTopo.ts
  72. 63 0
      persagy-web-big/src/types/topology/Node.ts
  73. 58 0
      persagy-web-big/src/types/topology/Relation.ts
  74. 352 0
      persagy-web-big/src/utils/SMathUtil.ts

persagy-web-big/src/BigEditFactory.ts → persagy-web-big-edit/BigEditFactory.ts


persagy-web-big/src/SBaseEditScene.ts → persagy-web-big-edit/SBaseEditScene.ts


+ 13 - 0
persagy-web-big-edit/index.ts

@@ -0,0 +1,13 @@
+import { SBaseEditScene } from "./SBaseEditScene"
+import { SBaseExpainEdit } from "./items/SBaseExpainEdit"
+import { SBasePipeUninTool } from "./items/SBasePipeUninTool"
+import { SBasePipe } from "./items/SBasePipe"
+import { SBaseArrow } from "./items/SBaseArrow"
+import { Anchor } from "./types/Anchor"
+import { ElementData } from "./types/ElementData"
+import { Legend } from "./types/Legend"
+import { Marker } from "./types/Marker"
+import { Relation } from "./types/Relation"
+import { BigEditFactory } from "./BigEditFactory"
+import { SBaseEquipment } from "./items/SBaseEquipment"
+export { SBaseArrow, SBasePipe, SBasePipeUninTool, SBaseEquipment, BigEditFactory, Anchor, Legend, Marker, Relation, ElementData, SBaseEditScene, SBaseExpainEdit }

persagy-web-big/src/items/SBaseArrow.ts → persagy-web-big-edit/items/SBaseArrow.ts


persagy-web-big/src/items/SBaseEquipment.ts → persagy-web-big-edit/items/SBaseEquipment.ts


persagy-web-big/src/items/SBaseExpainEdit.ts → persagy-web-big-edit/items/SBaseExpainEdit.ts


persagy-web-big/src/items/SBasePipe.ts → persagy-web-big-edit/items/SBasePipe.ts


persagy-web-big/src/items/SBasePipeUninTool.ts → persagy-web-big-edit/items/SBasePipeUninTool.ts


persagy-web-big/src/parsers/bigEditParse.ts → persagy-web-big-edit/parsers/bigEditParse.ts


persagy-web-big/src/types/Anchor.ts → persagy-web-big-edit/types/Anchor.ts


persagy-web-big/src/types/ElementData.ts → persagy-web-big-edit/types/ElementData.ts


persagy-web-big/src/types/Legend.ts → persagy-web-big-edit/types/Legend.ts


+ 54 - 0
persagy-web-big-edit/types/Marker.ts

@@ -0,0 +1,54 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2016-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph/lib/types/Point";
+import { Size } from "@persagy-web/big/lib/types/Size";
+
+/**
+ * 标识对象接口
+ *
+ * @author  张宇
+ */
+export interface Marker {
+    /** ID */
+    iD?: string;
+    /** 名称  */
+    name: string;
+    /** 图标(Image),线类型(Line) */
+    type: string;
+    /** 位置  */
+    pos: Point;
+    /** 缩放  */
+    scale?: Point;
+    /** 旋转  */
+    rolate?: Point;
+    /** 大小  */
+    size?: Size;
+    /** 绘制时得数据以及样式 */
+    style: any;
+    /** 由应用自己定义  */
+    properties?: any;
+} // Interface Marker

persagy-web-big/src/types/Relation.ts → persagy-web-big-edit/types/Relation.ts


persagy-web-big/src/until.ts → persagy-web-big-edit/until.ts


+ 72 - 0
persagy-web-big/src/config/ItemColor.ts

@@ -0,0 +1,72 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SColor } from "@persagy-web/draw";
+
+/**
+ * 接口item颜色配置
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated
+ */
+export class ItemColor {
+    /** 墙颜色 */
+    static wallColor = new SColor("#2b2b2b");
+    /** 柱子颜色 */
+    static columnColor = SColor.Black;
+    /** 虚拟墙颜色 */
+    static virtualWallColor = SColor.Black;
+    /** 空间颜色 */
+    static spaceColor = new SColor("#f1fffd80");
+    /** 门颜色 */
+    static doorColor = new SColor("#f5b36f");
+    /** 窗户颜色 */
+    static windowColor = new SColor("#fcd6ff");
+    /** 蒙版颜色 */
+    static sceneMarkColor = new SColor("#00000080");
+    /** 遮罩颜色 */
+    static shadeColor = new SColor("#00000080");
+    /** 高亮item吸附点颜色 */
+    static highLightPointColor = new SColor("#ff8d00");
+    /** 高亮item吸附线颜色 */
+    static highLightLineColor = new SColor("#409EFF");
+    /** 矩形选择对象边框颜色 */
+    static rectSelectOutColor = new SColor("#3e78f9e8");
+    /** 矩形选择对象填充颜色 */
+    static rectSelectInColor = new SColor("#8cf2fd73");
+    /** 空间边框颜色 */
+    static spaceBorderColor = new SColor("#2b2b2b");
+    /** 空间,业务空间选中颜色 */
+    static selectColor = new SColor("#1abc9c");
+    /** 空间高亮颜色 */
+    static spaceHighColor = new SColor("#fbb029");
+    /** 业务空间不可选中颜色 */
+    static zoneUnselectColor = new SColor("#cecece");
+    /** 受影响业务空间颜色 */
+    static zoneInfectedColor = new SColor("#ff0000");
+    /** 受影响的业务空间边框颜色 */
+    static zoneInfectedBorder = new SColor("#e2675c");
+} // Class ItemColor

+ 72 - 0
persagy-web-big/src/config/ItemOrder.ts

@@ -0,0 +1,72 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * item层级类
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated
+ */
+export class ItemOrder {
+    /** 空间层级 */
+    static spaceOrder = 200;
+    /** 业务空间层级 */
+    static zoneOrder = 800;
+    /** 类空间层级 */
+    static likeSpaceOrder = 1000;
+    /** 柱子层级 */
+    static columnOrder = 1200;
+    /** 墙层级 */
+    static wallOrder = 1600;
+    /** 虚拟墙层级 */
+    static virtualWallOrder = 2000;
+    /** 门层级 */
+    static doorOrder = 2400;
+    /** 窗户层级 */
+    static windowOrder = 2800;
+    /** 多边形层级 */
+    static polygonOrder = 4000;
+    /** 直线层级 */
+    static lineOrder = 5000;
+    /** 折线层级 */
+    static polylineOrder = 6000;
+    /** 图片层级 */
+    static imageOrder = 7000;
+    /** 文本层级 */
+    static textOrder = 8000;
+    /** 位置标签对象层级 */
+    static markOrder = 9900;
+    /** 遮罩层级 */
+    static shadeOrder = 12000;
+    /** 框选矩形对象层级 */
+    static rectSelectOrder = 9999900;
+    /** 高亮对象层级 */
+    static highLightOrder = 999900;
+    /** 业务空间关系点位层级 */
+    static RelationOrder = 999900;
+    /** 蒙版层级 */
+    static sceneMarkOrder = 9999900;
+} // Class ItemOrder

+ 135 - 0
persagy-web-big/src/config/Transparency.ts

@@ -0,0 +1,135 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 透明度索引对应
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated
+ */
+export const Transparency = [
+    "00",
+    "03",
+    "05",
+    "08",
+    "0A",
+    "0D",
+    "0F",
+    "12",
+    "14",
+    "17",
+    "1A",
+    "1C",
+    "1F",
+    "21",
+    "24",
+    "26",
+    "29",
+    "2B",
+    "2E",
+    "30",
+    "33",
+    "36",
+    "38",
+    "3B",
+    "3D",
+    "40",
+    "42",
+    "45",
+    "47",
+    "4A",
+    "4D",
+    "4F",
+    "52",
+    "54",
+    "57",
+    "59",
+    "5C",
+    "5E",
+    "61",
+    "63",
+    "66",
+    "69",
+    "6B",
+    "6E",
+    "70",
+    "73",
+    "75",
+    "78",
+    "7A",
+    "7D",
+    "80",
+    "82",
+    "85",
+    "87",
+    "8A",
+    "8C",
+    "8F",
+    "91",
+    "94",
+    "96",
+    "99",
+    "9C",
+    "9E",
+    "A1",
+    "A3",
+    "A6",
+    "A8",
+    "AB",
+    "AD",
+    "B0",
+    "B3",
+    "B5",
+    "B8",
+    "BA",
+    "BD",
+    "BF",
+    "C2",
+    "C4",
+    "C7",
+    "C9",
+    "CC",
+    "CF",
+    "D1",
+    "D4",
+    "D6",
+    "D9",
+    "DB",
+    "DE",
+    "E0",
+    "E3",
+    "E6",
+    "E8",
+    "EB",
+    "ED",
+    "F0",
+    "F2",
+    "F5",
+    "F7",
+    "FA",
+    "FC",
+    "FF"
+]; // Interface Transparency

+ 42 - 0
persagy-web-big/src/enums/SGraphElementType.ts

@@ -0,0 +1,42 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 图标,区域类型
+ *
+ * @author  张宇
+ * @deprecated 万达
+ */
+export enum SGraphElementType {
+    /** 非图例 */
+    None,
+    /** 线类型 */
+    Line,
+    /** 区域类型 */
+    Zone,
+    /** 图类型 */
+    Image
+} // Enum SGraphElementType

+ 40 - 0
persagy-web-big/src/enums/SItemStatus.ts

@@ -0,0 +1,40 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * item状态
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated move to edit
+ */
+export enum SItemStatus {
+    /** 标准状态 */
+    Normal,
+    /** 编辑状态 */
+    Edit,
+    /** 创建态 */
+    Create
+} // Enum SItemStatus

+ 36 - 0
persagy-web-big/src/enums/SLineType.ts

@@ -0,0 +1,36 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 线类型
+ *
+ * @author  张宇
+ * @deprecated 万达
+ */
+export enum SLineType {
+    /** 直线 */
+    Line
+} // Enum SLineType

+ 40 - 0
persagy-web-big/src/enums/SMarkerType.ts

@@ -0,0 +1,40 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 标识对象类型
+ *
+ * @author  张宇
+ * @deprecated 万达
+ */
+export enum SMarkerType {
+    /** 图标 */
+    Image,
+    /** 线类型 */
+    Line,
+    /** 文本类型 */
+    Text
+} // Enum SMarkerType

+ 40 - 0
persagy-web-big/src/enums/SRelationDir.ts

@@ -0,0 +1,40 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 关系方向
+ *
+ * @author  张宇
+ * @deprecated 万达
+ */
+export enum SRelationDir {
+    /** 无向 */
+    Undirected,
+    /** 正向(节点1到节点2) */
+    Forward,
+    /** 逆向(节点2到节点1) */
+    Reverse
+} // Enum SRelationDir

+ 42 - 0
persagy-web-big/src/enums/SRelationState.ts

@@ -0,0 +1,42 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 关系状态
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated
+ */
+export enum SRelationState {
+    /** 标准状态 */
+    Normal,
+    /** 动画撞他 */
+    Animation,
+    /** 编辑状态 */
+    Edit,
+    /** 创建态 */
+    Create
+} // Enum SRelationState

+ 122 - 0
persagy-web-big/src/factories/SItemFactory.ts

@@ -0,0 +1,122 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Column } from "../types/floor/Column";
+import { SColumnItem } from "../items/floor/SColumnItem";
+import { SWallItem } from "../items/floor/SWallItem";
+import { Wall } from "../types/floor/Wall";
+import { SVirtualWallItem } from "../items/floor/SVirtualWallItem";
+import { VirtualWall } from "../types/floor/VirtualWall";
+import { SSpaceItem } from "../items/floor/SSpaceItem";
+import { Space } from "../types/floor/Space";
+import { Door } from "../types/floor/Door";
+import { SDoorItem } from "../items/floor/SDoorItem";
+import { SWindowItem } from "../items/floor/SWindowItem";
+import { Casement } from "../types/floor/Casement";
+import { SZoneItem } from "../items/floor/ZoneItem";
+import { Zone } from "../types/floor/Zone";
+
+/**
+ * item创建工厂
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SItemFactory {
+    /**
+     * 构造函数
+     */
+    constructor() {} // Constructor
+
+    /**
+     * 创建柱子item
+     *
+     * @param data    柱子数据
+     * @return 柱子 item
+     */
+    createColumn(data: Column): SColumnItem {
+        return new SColumnItem(null, data);
+    } // Function createColumn()
+
+    /**
+     * 创建墙item
+     *
+     * @param data    墙数据
+     * @return 墙 item
+     */
+    createWall(data: Wall): SWallItem {
+        return new SWallItem(null, data);
+    } // Function createWall()
+
+    /**
+     * 创建虚拟墙item
+     *
+     * @param data    虚拟墙数据
+     * @return 虚拟墙 item
+     */
+    createVirtualWall(data: VirtualWall): SVirtualWallItem {
+        return new SVirtualWallItem(null, data);
+    } // Function createVirtualWall()
+
+    /**
+     * 创建空间item
+     *
+     * @param data    空间数据
+     * @return 空间 item
+     */
+    createSpace(data: Space): SSpaceItem {
+        return new SSpaceItem(null, data);
+    } // Function createSpace()
+
+    /**
+     * 创建门item
+     *
+     * @param data    门数据
+     * @return 门item
+     */
+    createDoor(data: Door): SDoorItem {
+        return new SDoorItem(null, data);
+    } // Function createDoor()
+
+    /**
+     * 创建窗item
+     *
+     * @param data    窗户数据
+     * @return 窗户 item
+     */
+    createWindow(data: Casement): SWindowItem {
+        return new SWindowItem(null, data);
+    } // Function createWindow()
+
+    /**
+     * 创建业务空间item
+     *
+     * @param data    业务空间数据
+     * @return 业务空间 item
+     */
+    createZone(data: Zone): SZoneItem {
+        return new SZoneItem(null, data);
+    } // Function createZone()
+} // Class SItemFactory

+ 32 - 0
persagy-web-big/src/factories/STopoItemFactory.ts

@@ -0,0 +1,32 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 拓扑图item创建工厂
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class STopoItemFactory {} // Class STopoItemFactory

+ 67 - 13
persagy-web-big/src/index.ts

@@ -1,13 +1,67 @@
-import { SBaseEditScene } from "./SBaseEditScene"
-import { SBaseExpainEdit } from "./items/SBaseExpainEdit"
-import { SBasePipeUninTool } from "./items/SBasePipeUninTool"
-import { SBasePipe } from "./items/SBasePipe"
-import { SBaseArrow } from "./items/SBaseArrow"
-import { Anchor } from "./types/Anchor"
-import { ElementData } from "./types/ElementData"
-import { Legend } from "./types/Legend"
-import { Marker } from "./types/Marker"
-import { Relation } from "./types/Relation"
-import { BigEditFactory } from "./BigEditFactory"
-import { SBaseEquipment } from "./items/SBaseEquipment"
-export { SBaseArrow, SBasePipe, SBasePipeUninTool, SBaseEquipment, BigEditFactory, Anchor, Legend, Marker, Relation, ElementData, SBaseEditScene, SBaseExpainEdit }
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SLayerItem } from "./items/SLayerItem";
+import { STooltipItem } from "./items/STooltipItem";
+import { ItemColor } from "./config/ItemColor";
+import { Transparency } from "./config/Transparency";
+import { ItemOrder } from "./config/ItemOrder";
+import { SItemFactory } from "./factories/SItemFactory";
+import { SZoneParser } from "./parser/SZoneParser";
+import { SFloorParser } from "./parser/SFloorParser";
+import { SParser } from "./parser/SParser";
+import { SIconTextItem } from "./items/SIconTextItem";
+import { SPolylineItem } from "./items/SPolylineItem";
+import { SLineItem } from "./items/SLineItem";
+import { SRelationState } from "./enums/SRelationState";
+import { SItemStatus } from "./enums/SItemStatus";
+import { SPolygonItem } from "./items/SPolygonItem";
+import { SRectSelectItem } from "./items/SRectSelectItem";
+import { SBoardItem } from "./items/floor/SBoardItem";
+import { SArrowItem } from "./items/SArrowItem";
+import { SArrowPoly } from "./items/SArrowPoly";
+
+export {
+    SLayerItem,
+    SLineItem,
+    SPolylineItem,
+    STooltipItem,
+    ItemColor,
+    ItemOrder,
+    Transparency,
+    SItemFactory,
+    SParser,
+    SFloorParser,
+    SZoneParser,
+    SIconTextItem,
+    SRelationState,
+    SItemStatus,
+    SPolygonItem,
+    SRectSelectItem,
+    SBoardItem,
+    SArrowItem,
+    SArrowPoly
+};

+ 91 - 0
persagy-web-big/src/items/SArrowItem.ts

@@ -0,0 +1,91 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPainter, SArrowStyleType } from "@persagy-web/draw";
+import { SPolylineItem } from "..";
+import { SLineStyle } from "@persagy-web/graph";
+
+/**
+ * 折线箭头 item
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SArrowItem extends SPolylineItem {
+    /** 起始点样式 */
+    _begin = SArrowStyleType.None;
+    get begin(): SArrowStyleType {
+        return this._begin;
+    } // Get begin
+    set begin(v: SArrowStyleType) {
+        this._begin = v;
+        this.update();
+    } // Set begin
+
+    /** 结束点样式 */
+    _end = SArrowStyleType.None;
+    get end(): SArrowStyleType {
+        return this._end;
+    } // Get end
+    set end(v: SArrowStyleType) {
+        this._end = v;
+        this.update();
+    } // Set end
+
+    /**
+     * 绘制基本图形
+     *
+     * @param painter   绘制对象
+     */
+    drawBaseLine(painter: SPainter): void {
+        // 绘制基本图形
+        if (this.lineStyle == SLineStyle.Dashed) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth * 3),
+                painter.toPx(this.lineWidth * 7)
+            ];
+        } else if (this.lineStyle == SLineStyle.Dotted) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth),
+                painter.toPx(this.lineWidth)
+            ];
+        }
+
+        painter.pen.color = this.strokeColor;
+        painter.drawArrowLine(this.pointList[0], this.pointList[1], {
+            begin: this.begin,
+            end: SArrowStyleType.None
+        });
+        painter.drawArrowLine(
+            this.pointList[this.pointList.length - 2],
+            this.pointList[this.pointList.length - 1],
+            {
+                begin: SArrowStyleType.None,
+                end: this.end
+            }
+        );
+        painter.drawPolyline(this.pointList);
+    } // Function drawBaseLine()
+} // Class SArrowItem

+ 34 - 0
persagy-web-big/src/items/SArrowPoly.ts

@@ -0,0 +1,34 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 箭头多边形类型
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SArrowPoly extends SGraphItem {} // Class SArrowPoly

+ 422 - 0
persagy-web-big/src/items/SIconTextItem.ts

@@ -0,0 +1,422 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import {
+    SObjectItem,
+    SImageItem,
+    STextItem,
+    SAnchorItem,
+    SGraphItem
+} from "@persagy-web/graph";
+import { SItemStatus, ItemOrder } from "..";
+import { SMouseEvent } from "@persagy-web/base";
+import {
+    SSize,
+    SRect,
+    SPainter,
+    SColor,
+    SFont,
+    SPoint
+} from "@persagy-web/draw";
+import { Anchor } from "../types/topology/Anchor";
+
+/**
+ * 图例 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SIconTextItem extends SObjectItem {
+    /** item 状态 */
+    _status: SItemStatus = SItemStatus.Normal;
+    get status(): SItemStatus {
+        return this._status;
+    } // Get status
+    set status(v: SItemStatus) {
+        this._status = v;
+        if (v == SItemStatus.Normal) {
+            this.moveable = true;
+            this.textItem.moveable = false;
+            this.img.moveable = false;
+        } else if (v == SItemStatus.Edit) {
+            this.moveable = false;
+            this.textItem.moveable = true;
+            this.img.moveable = true;
+        } else if (v == SItemStatus.Create) {
+            this.moveable = true;
+            this.textItem.moveable = false;
+            this.img.moveable = false;
+        }
+        this.update();
+    } // Set status
+
+    /** 是否显示文字 */
+    _showText: boolean = true;
+    get showText(): boolean {
+        return this._showText;
+    } // Get showText
+    set showText(v: boolean) {
+        if (v === this._showText) {
+            return;
+        }
+        this._showText = v;
+        if (v) {
+            this.textItem.show();
+        } else {
+            this.textItem.hide();
+        }
+    } // Set showText
+
+    /** 是否被选中 */
+    get selected(): boolean {
+        return this._selected && this.selectable && this.enabled;
+    } // Get selected
+    set selected(value: boolean) {
+        // 如果选择状态未变更
+        if (this.selected == value) {
+            return;
+        }
+        this._selected = value;
+        if (value) {
+            this.img.scale = 1.25;
+            this.zOrder = ItemOrder.highLightOrder;
+        } else {
+            this.img.scale = 1;
+            this.zOrder = ItemOrder.markOrder;
+        }
+        this.update();
+    } // Set selected
+
+    /** 是否激活 */
+    _isActive: boolean = false;
+    get isActive(): boolean {
+        return this._isActive;
+    } // Get isActive
+    set isActive(v: boolean) {
+        this._isActive = v;
+        if (v) {
+            this.cursor = "pointer";
+            this.textItem.cursor = "pointer";
+            this.img.cursor = "pointer";
+        } else {
+            this.cursor = "auto";
+            this.textItem.cursor = "auto";
+            this.img.cursor = "auto";
+        }
+        this.update();
+    } // Set isActive
+
+    /** 激活显示颜色 */
+    _activeColor: SColor = new SColor("#00000033");
+    get activeColor(): SColor {
+        return this._activeColor;
+    } // Get activeColor
+    set activeColor(v: SColor) {
+        this._activeColor = v;
+        this.update();
+    } // Set activeColor
+
+    /** X 轴坐标 */
+    get x(): number {
+        return this.pos.x;
+    } // Get x
+    set x(v: number) {
+        this.pos.x = v;
+        this.$emit("changePos");
+        this.update();
+    } // Set x
+
+    /** Y 轴坐标 */
+    get y(): number {
+        return this.pos.y;
+    } // Get y
+    set y(v: number) {
+        this.pos.y = v;
+        this.$emit("changePos");
+        this.update();
+    } // Set y
+
+    /** icon宽 */
+    get sWidth(): number {
+        return this.img.width;
+    } // Get sWidth
+    set sWidth(v: number) {
+        this.img.width = v;
+        this.img.origin = new SPoint(
+            this.img.width * 0.5,
+            this.img.height * 0.5
+        );
+        this.changeAnchorPoint();
+        this.update();
+    } // Set sWidth
+
+    /** icon高 */
+    get sHeight(): number {
+        return this.img.height;
+    } // Get sHeight
+    set sHeight(v: number) {
+        this.img.height = v;
+        this.img.origin = new SPoint(
+            this.img.width * 0.5,
+            this.img.height * 0.5
+        );
+        this.changeAnchorPoint();
+        this.update();
+    } // Set sHeight
+
+    /** 是否显示锚点 */
+    private _showAnchor: boolean = false;
+    get showAnchor(): boolean {
+        return this._showAnchor;
+    } // Get showAnchor
+    set showAnchor(v: boolean) {
+        this._showAnchor = v;
+        this.anchorList.forEach(t => {
+            t.visible = v;
+        });
+    } // Set showAnchor
+
+    /** 文本内容 */
+    get text(): string {
+        return this.textItem.text;
+    } // Get text
+    set text(v: string) {
+        this.textItem.text = v;
+        this.update();
+    } // Set text
+
+    /** 文本颜色 */
+    get color(): SColor {
+        return this.textItem.color;
+    } // Get color
+    set color(v: SColor) {
+        this.textItem.color = v;
+        this.update();
+    } // Get color
+
+    /** 文本字体 */
+    get font(): SFont {
+        return this.textItem.font;
+    } // Get font
+    set font(v: SFont) {
+        this.textItem.font = v;
+        this.update();
+    } // Set font
+
+    /** img Item */
+    img: SImageItem = new SImageItem(this);
+
+    /** text Item */
+    textItem: STextItem = new STextItem(this);
+
+    /**
+     * 构造体
+     *
+     * @param parent  父类
+     * @param data    锚点数据
+     */
+    constructor(parent: SGraphItem | null, data?: Anchor[]) {
+        super(parent);
+        this.img.width = 32;
+        this.img.height = 32;
+        this.img.origin = new SPoint(
+            this.img.width * 0.5,
+            this.img.height * 0.5
+        );
+        this.img.connect("onMove", this, this.changeAnchorPoint.bind(this));
+        let anchorPoint;
+        if (data && data.length) {
+            anchorPoint = data.map(t => {
+                return {
+                    x: t.pos.x,
+                    y: t.pos.y,
+                    id: t.id
+                };
+            });
+        } else {
+            anchorPoint = [
+                { x: this.img.x, y: this.img.y, id: "" },
+                { x: this.img.x, y: this.img.y, id: "" },
+                { x: this.img.x, y: this.img.y, id: "" },
+                { x: this.img.x, y: this.img.y, id: "" }
+                // { x: this.img.x, y: this.img.y + this.img.height / 2, id: "" },
+                // { x: this.img.x, y: this.img.y - this.img.height / 2, id: "" },
+                // { x: this.img.x - this.img.width / 2, y: this.img.y, id: "" },
+                // { x: this.img.x + this.img.width / 2, y: this.img.y, id: "" }
+            ];
+        }
+        this.anchorList = anchorPoint.map(t => {
+            let item = new SAnchorItem(this);
+            if (t.id) {
+                item.id = t.id;
+            }
+            item.moveTo(t.x, t.y);
+            return item;
+        });
+        this.showAnchor = false;
+        this.textItem.text = "";
+        this.textItem.font.size = 12;
+        // 偏移二分之一文本高度
+        this.textItem.moveTo(
+            this.img.width * 0.5,
+            -(this.font.size * 1.25 * 0.5)
+        );
+        this.moveable = true;
+        this.selectable = true;
+    } // Constructor
+
+    /**
+     * 计算并移动锚点的位置
+     */
+    private changeAnchorPoint(): void {
+        // 判断是否有锚点
+        if (this.anchorList.length) {
+            let anchorPoint = [
+                { x: this.img.x, y: this.img.y },
+                { x: this.img.x, y: this.img.y },
+                { x: this.img.x, y: this.img.y },
+                { x: this.img.x, y: this.img.y }
+                // { x: this.img.x, y: this.img.y + this.img.height / 2 },
+                // { x: this.img.x, y: this.img.y - this.img.height / 2 },
+                // { x: this.img.x - this.img.width / 2, y: this.img.y },
+                // { x: this.img.x + this.img.width / 2, y: this.img.y }
+            ];
+            this.anchorList.forEach((item, index) => {
+                item.moveTo(anchorPoint[index].x, anchorPoint[index].y);
+            });
+        }
+    } // Function changeAnchorPoint()
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param event   事件对象
+     * @return 是否处理事件
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Normal) {
+            return super.onMouseDown(event);
+        } else if (this.status == SItemStatus.Edit) {
+            return super.onMouseDown(event);
+        }
+        return true;
+    } // Function onMouseDown()
+
+    /**
+     * 宽高发发生变化
+     *
+     * @param oldSize 改之前的大小
+     * @param newSize 改之后大小
+     */
+    onResize(oldSize: SSize, newSize: SSize): void {
+        console.log(arguments);
+    } // Function onResize()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param event   鼠标事件
+     * @return 是否处理事件
+     */
+    onDoubleClick(event: SMouseEvent): boolean {
+        // 如果位show状态 双击改对象则需改为编辑状态
+        if (SItemStatus.Normal == this.status) {
+            this.status = SItemStatus.Edit;
+            this.grabItem(this);
+        } else if (SItemStatus.Edit == this.status) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        }
+        this.update();
+        return true;
+    } // Function onDoubleClick()
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界矩阵
+     */
+    boundingRect(): SRect {
+        let rect = this.img
+            .boundingRect()
+            .adjusted(this.img.pos.x, this.img.pos.y, 0, 0);
+        if (this.showText) {
+            rect = rect.unioned(
+                this.textItem
+                    .boundingRect()
+                    .adjusted(this.textItem.pos.x, this.textItem.pos.y, 0, 0)
+            );
+        }
+
+        return rect.adjusted(-5, -5, 10, 10);
+    } // Function boundingRect()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        if (this.status == SItemStatus.Edit) {
+            painter.pen.lineWidth = painter.toPx(1);
+            painter.pen.lineDash = [painter.toPx(3), painter.toPx(7)];
+            painter.pen.color = SColor.Black;
+            painter.brush.color = SColor.Transparent;
+            painter.drawRect(this.boundingRect());
+        }
+
+        if (this.isActive) {
+            painter.pen.color = SColor.Transparent;
+            painter.brush.color = this.activeColor;
+            if (this.selected) {
+                painter.shadow.shadowBlur = 10;
+                painter.shadow.shadowColor = this.activeColor;
+                painter.shadow.shadowOffsetX = 5;
+                painter.shadow.shadowOffsetY = 5;
+                painter.drawCircle(
+                    this.img.x,
+                    this.img.y,
+                    (this.sWidth / 2.0 + 3) * 1.25
+                );
+            } else {
+                painter.drawCircle(
+                    this.img.x,
+                    this.img.y,
+                    this.sWidth / 2.0 + 3
+                );
+            }
+        } else {
+            if (this.selected) {
+                painter.pen.color = SColor.Transparent;
+                painter.brush.color = SColor.Transparent;
+                painter.shadow.shadowBlur = 10;
+                painter.shadow.shadowColor = new SColor(`#00000033`);
+                painter.shadow.shadowOffsetX = 5;
+                painter.shadow.shadowOffsetY = 5;
+                painter.drawCircle(this.img.x, this.img.y, this.sWidth / 2.0);
+            }
+        }
+    } // Function onDraw()
+} // Class SIconTextItem

+ 34 - 0
persagy-web-big/src/items/SLayerItem.ts

@@ -0,0 +1,34 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ *  编辑器图层-图层锁定,业务层组合使用
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SLayerItem extends SGraphItem {} // Class SLayerItem

+ 535 - 0
persagy-web-big/src/items/SLineItem.ts

@@ -0,0 +1,535 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SColor, SLine, SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { SMouseButton, SMouseEvent, SUndoStack } from "@persagy-web/base";
+import { SMathUtil } from "../utils/SMathUtil";
+import { SItemStatus } from "..";
+import {
+    SGraphItem,
+    SGraphPointListInsert,
+    SGraphPointListUpdate,
+    SLineStyle
+} from "@persagy-web/graph";
+
+/**
+ * 直线 item
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SLineItem extends SGraphItem {
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    /** 线段 */
+    private _line: SPoint[] = [];
+    get line(): SPoint[] {
+        return this._line;
+    } // Get line
+    set line(arr: SPoint[]) {
+        this._line = arr;
+        this.update();
+    } // Set line
+
+    /** 是否完成绘制 */
+    protected _status: SItemStatus = SItemStatus.Normal;
+    get status(): SItemStatus {
+        return this._status;
+    } // Get status
+    set status(v: SItemStatus) {
+        this._status = v;
+        this.undoStack.clear();
+        this.update();
+    } // Set status
+
+    /** 线条颜色 */
+    private _strokeColor: SColor = SColor.Black;
+    get strokeColor(): SColor {
+        return this._strokeColor;
+    } // Get strokeColor
+    set strokeColor(v: SColor) {
+        this._strokeColor = v;
+        this.update();
+    } // Set strokeColor
+
+    /** 线条样式 */
+    private _lineStyle: SLineStyle = SLineStyle.Solid;
+    get lineStyle(): SLineStyle {
+        return this._lineStyle;
+    } // Get lineStyle
+    set lineStyle(v: SLineStyle) {
+        this._lineStyle = v;
+        this.update();
+    } // Set lineStyle
+
+    /** 端点填充色 */
+    private _fillColor: SColor = SColor.White;
+    get fillColor(): SColor {
+        return this._fillColor;
+    } // Get fillColor
+    set fillColor(v: SColor) {
+        this._fillColor = v;
+        this.update();
+    } // Set fillColor
+
+    /** 选中端点填充色 */
+    private _activeFillColor: SColor = new SColor("#2196f3");
+    get activeFillColor(): SColor {
+        return this._activeFillColor;
+    } // Get activeFillColor
+    set activeFillColor(v: SColor) {
+        this._activeFillColor = v;
+        this.update();
+    } // Set activeFillColor
+
+    /** 线条宽度 */
+    private _lineWidth: number = 1;
+    get lineWidth(): number {
+        return this._lineWidth;
+    } // Get lineWidth
+    set lineWidth(v: number) {
+        this._lineWidth = v;
+        this.update();
+    } // Set lineWidth
+
+    /** 拖动灵敏度 */
+    dis: number = 5;
+
+    /** 拖动灵敏度 */
+    private sceneDis: number = 5;
+
+    /** 当前点索引 */
+    curIndex: number = -1;
+
+    /** 当前点坐标 */
+    private curPoint: SPoint | null = null;
+
+    /** undo/redo 堆栈 */
+    private undoStack: SUndoStack = new SUndoStack();
+
+    /**
+     * 构造函数
+     *
+     * @param parent  父级
+     */
+    constructor(parent: SGraphItem | null);
+
+    /**
+     * 构造函数
+     *
+     * @param parent  父级
+     * @param line    坐标集合
+     */
+    constructor(parent: SGraphItem | null, line: SPoint[]);
+
+    /**
+     * 构造函数
+     *
+     * @param parent  父级
+     * @param point   第一个点坐标
+     */
+    constructor(parent: SGraphItem | null, point: SPoint);
+
+    /**
+     * 构造函数
+     *
+     * @param parent    父级
+     * @param line      坐标集合|第一个点坐标
+     */
+    constructor(parent: SGraphItem | null, line?: SPoint | SPoint[]) {
+        super(parent);
+        if (line) {
+            if (line instanceof SPoint) {
+                this.line.push(line);
+            } else {
+                this.line = line;
+            }
+        } else {
+            this.line = [];
+        }
+    } // Constructor
+
+    /**
+     * 添加点至数组中
+     *
+     * @param p 添加的点
+     */
+    private addPoint(p: SPoint): void {
+        if (this.line.length < 2) {
+            this.line.push(p);
+            this.recordAction(SGraphPointListInsert, [this.line, p]);
+        } else {
+            this.line[1] = p;
+            this.recordAction(SGraphPointListInsert, [this.line, p, 1]);
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+            this.$emit("finishCreated");
+        }
+        this.update();
+    } // Function addPoint()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param event     事件参数
+     * @return 是否处理事件
+     */
+    onDoubleClick(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Normal) {
+            this.status = SItemStatus.Edit;
+            this.grabItem(this);
+        } else if (this.status == SItemStatus.Edit) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        }
+        this.update();
+        return true;
+    } // Function onDoubleClick()
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param event     鼠标事件
+     * @return 是否处理事件
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        this.curIndex = -1;
+        this.curPoint = null;
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+        if (event.buttons == SMouseButton.LeftButton) {
+            if (this.status == SItemStatus.Normal) {
+                return super.onMouseDown(event);
+            } else if (this.status == SItemStatus.Edit) {
+                // 判断是否点击到端点上(获取端点索引值)
+                this.findNearestPoint(new SPoint(event.x, event.y));
+            } else if (this.status == SItemStatus.Create) {
+                this.addPoint(new SPoint(event.x, event.y));
+                return true;
+            }
+        }
+
+        return true;
+    } // Function onMouseDown()
+
+    /**
+     * 鼠标抬起事件
+     *
+     * @param event     事件参数
+     * @return 是否处理事件
+     */
+    onMouseUp(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Edit) {
+            if (this.curIndex > -1) {
+                const p = new SPoint(
+                    this.line[this.curIndex].x,
+                    this.line[this.curIndex].y
+                );
+                this.recordAction(SGraphPointListUpdate, [
+                    this.line,
+                    this.curPoint,
+                    p,
+                    this.curIndex
+                ]);
+            }
+        } else if (this.status == SItemStatus.Normal) {
+            this.moveToOrigin(this.x, this.y);
+            return super.onMouseUp(event);
+        }
+
+        this.curIndex = -1;
+        this.curPoint = null;
+        return true;
+    } // Function onMouseUp()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param event     事件参数
+     * @return 是否处理事件
+     */
+    onMouseMove(event: SMouseEvent): boolean {
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+
+        if (this.status == SItemStatus.Create) {
+            if (this.line[0] instanceof SPoint) {
+                this.line[1] = new SPoint(event.x, event.y);
+            }
+        } else if (this.status == SItemStatus.Edit) {
+            if (-1 != this.curIndex) {
+                this.line[this.curIndex].x = event.x;
+                this.line[this.curIndex].y = event.y;
+            }
+        } else {
+            return super.onMouseMove(event);
+        }
+
+        this.update();
+        return true;
+    } // Function onMouseMove()
+
+    /**
+     * 获取点击点与 Point[] 中的点距离最近点
+     *
+     * @param p     鼠标点击点
+     */
+    findNearestPoint(p: SPoint): void {
+        let len = this.sceneDis;
+        for (let i = 0; i < this.line.length; i++) {
+            let dis = SMathUtil.pointDistance(
+                p.x,
+                p.y,
+                this.line[i].x,
+                this.line[i].y
+            );
+            if (dis < len) {
+                len = dis;
+                this.curIndex = i;
+                this.curPoint = new SPoint(this.line[this.curIndex]);
+            }
+        }
+    } // Function findNearestPoint()
+
+    /**
+     * 记录相关动作并推入栈中
+     *
+     * @param SGraphCommand 相关命令类
+     * @param any           对应传入参数
+     */
+    protected recordAction(SGraphCommand: any, any: any[]): void {
+        // 记录相关命令并推入堆栈中 todo
+        const command = new SGraphCommand(this.scene, this, ...any);
+        this.undoStack.push(command);
+    } // Function recordAction()
+
+    /**
+     * 移动后处理所有坐标,并肩原点置为场景原点
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     */
+    moveToOrigin(x: number, y: number): void {
+        super.moveToOrigin(x, y);
+        this.line = this.line.map(t => {
+            t.x = t.x + x;
+            t.y = t.y + y;
+            return t;
+        });
+        this.x = 0;
+        this.y = 0;
+    } // Function moveToOrigin()
+
+    /**
+     * shift 垂直水平创建或编辑
+     *
+     * @param event     事件
+     * @return 处理后的事件对象
+     */
+    compare(event: SMouseEvent): SMouseEvent {
+        if (this.line.length) {
+            let last = new SPoint(event.x, event.y);
+            if (this.status == SItemStatus.Create) {
+                last = this.line[0];
+            } else if (this.status == SItemStatus.Edit) {
+                if (this.curIndex == 1) {
+                    last = this.line[0];
+                } else if (this.curIndex == 0) {
+                    last = this.line[1];
+                }
+            }
+            const dx = Math.abs(event.x - last.x);
+            const dy = Math.abs(event.y - last.y);
+            if (dy > dx) {
+                event.x = last.x;
+            } else {
+                event.y = last.y;
+            }
+        }
+
+        return event;
+    } // Function compare()
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     * @return 是否包含
+     */
+    contains(x: number, y: number): boolean {
+        if (this.line.length == 2) {
+            let p = new SPoint(x, y);
+            if (
+                SMathUtil.pointToLine(p, new SLine(this.line[0], this.line[1]))
+                    .MinDis < this.dis
+            ) {
+                return true;
+            }
+        }
+
+        return false;
+    } // Function contains()
+
+    /**
+     * 撤销操作
+     */
+    undo(): void {
+        if (this.status != SItemStatus.Normal) {
+            this.undoStack.undo();
+        }
+    } // Function undo()
+
+    /**
+     * 重做操作
+     */
+    redo(): void {
+        if (this.status != SItemStatus.Normal) {
+            this.undoStack.redo();
+        }
+    } // Function redo()
+
+    /**
+     * 取消操作 item 事件
+     */
+    cancelOperate(): void {
+        if (this.status == SItemStatus.Create) {
+            this.parent = null;
+            this.releaseItem();
+        } else if (this.status == SItemStatus.Edit) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        }
+    } // Function cancelOperate()
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界区域
+     */
+    boundingRect(): SRect {
+        if (this.line.length) {
+            this.minX = this.line[0].x;
+            this.maxX = this.line[0].x;
+            this.minY = this.line[0].y;
+            this.maxY = this.line[0].y;
+            this.line.forEach(it => {
+                let x = it.x,
+                    y = it.y;
+                if (x < this.minX) {
+                    this.minX = x;
+                }
+                if (y < this.minY) {
+                    this.minY = y;
+                }
+                if (x > this.maxX) {
+                    this.maxX = x;
+                }
+                if (y > this.maxY) {
+                    this.maxY = y;
+                }
+            });
+        }
+
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        this.sceneDis = painter.toPx(this.dis);
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+        painter.pen.color = this.strokeColor;
+        if (this.line.length == 2) {
+            // 绘制直线
+            painter.pen.color = new SColor(this.strokeColor);
+            if (this.lineStyle == SLineStyle.Dashed) {
+                painter.pen.lineDash = [
+                    painter.toPx(this.lineWidth * 3),
+                    painter.toPx(this.lineWidth * 7)
+                ];
+            } else if (this.lineStyle == SLineStyle.Dotted) {
+                painter.pen.lineDash = [
+                    painter.toPx(this.lineWidth),
+                    painter.toPx(this.lineWidth)
+                ];
+            }
+
+            if (this.selected && this.status == SItemStatus.Normal) {
+                painter.pen.lineWidth = painter.toPx(this.lineWidth * 2);
+                painter.shadow.shadowBlur = 10;
+                painter.shadow.shadowColor = new SColor(`#00000033`);
+                painter.shadow.shadowOffsetX = 5;
+                painter.shadow.shadowOffsetY = 5;
+            }
+
+            painter.drawLine(this.line[0], this.line[1]);
+            if (
+                this.status == SItemStatus.Edit ||
+                this.status == SItemStatus.Create
+            ) {
+                // 绘制端点
+                this.line.forEach((p, i): void => {
+                    painter.brush.color = this.fillColor;
+                    if (i == this.curIndex) {
+                        painter.brush.color = this.activeFillColor;
+                    }
+
+                    painter.drawCircle(p.x, p.y, painter.toPx(5));
+                });
+            }
+        } else if (this.line.length == 1) {
+            if (
+                this.status == SItemStatus.Edit ||
+                this.status == SItemStatus.Create
+            ) {
+                // 绘制端点
+                painter.brush.color = this.fillColor;
+                painter.drawCircle(
+                    this.line[0].x,
+                    this.line[0].y,
+                    painter.toPx(5)
+                );
+            }
+        }
+    } // Function onDraw()
+} // Class SLineItem

+ 846 - 0
persagy-web-big/src/items/SPolygonItem.ts

@@ -0,0 +1,846 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import {
+    SGraphItem,
+    SGraphPointListDelete,
+    SGraphPointListInsert,
+    SGraphPointListUpdate,
+    SLineStyle
+} from "@persagy-web/graph";
+import { SKeyCode, SMouseEvent, SUndoStack } from "@persagy-web/base/";
+import {
+    SColor,
+    SLine,
+    SLineCapStyle,
+    SPainter,
+    SPoint,
+    SPolygonUtil,
+    SRect
+} from "@persagy-web/draw";
+import { SItemStatus } from "..";
+import { SMathUtil } from "../utils/SMathUtil";
+
+/**
+ * 编辑多边形
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SPolygonItem extends SGraphItem {
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    /** 轮廓线坐标 */
+    private pointList: SPoint[] = [];
+    get getPointList(): SPoint[] {
+        return this.pointList;
+    } // Get getPointList
+    set setPointList(arr: SPoint[]) {
+        this.pointList = arr;
+        this.update();
+    } // Set getPointList
+
+    /** 当前状态 */
+    protected _status: number = SItemStatus.Normal;
+    get status(): SItemStatus {
+        return this._status;
+    } // Get status
+    set status(value: SItemStatus) {
+        this._status = value;
+        this.undoStack.clear();
+        this.update();
+    } // Set status
+
+    /** 边框颜色 */
+    _strokeColor: SColor = new SColor("#0091FF");
+    /**  画笔颜色 */
+    get strokeColor(): SColor {
+        return this._strokeColor;
+    } // Get strokeColor
+    set strokeColor(v: SColor) {
+        this._strokeColor = v;
+        this.update();
+    } // Set strokeColor
+
+    /** 填充颜色 */
+    _fillColor: SColor = new SColor("#1EE887");
+    get fillColor(): SColor {
+        return this._fillColor;
+    } // Get fillColor
+    set fillColor(v: SColor) {
+        this._fillColor = v;
+        this.update();
+    } // Set fillColor
+
+    /** 边框样式 */
+    _lineStyle: SLineStyle = SLineStyle.Solid;
+    get lineStyle(): SLineStyle {
+        return this._lineStyle;
+    } // Get lineStyle
+    set lineStyle(v: SLineStyle) {
+        this._lineStyle = v;
+        this.update();
+    } // Set lineStyle
+
+    /** 边框的宽 只可输入像素宽 */
+    _lineWidth: number = 4;
+    get lineWidth(): number {
+        return this._lineWidth;
+    } // Get lineWidth
+    set lineWidth(v: number) {
+        this._lineWidth = v;
+        this.update();
+    } // Set lineWidth
+
+    /** 是否闭合 */
+    closeFlag: boolean = false;
+    /** 鼠标移动点 */
+    private lastPoint: SPoint | null = null;
+    /** 当前鼠标获取顶点对应索引 */
+    private curIndex: number = -1;
+    /** 当前鼠标获取顶点对应坐标 */
+    private curPoint: null | SPoint = null;
+    /** 灵敏像素 */
+    private len: number = 10;
+    /** 场景像素 内部将灵敏像素换算为场景实际距离 */
+    private scenceLen: number = 15;
+    /** 场景像素 */
+    private isAlt: boolean = false;
+    /** undo/redo 堆栈 */
+    protected undoStack: SUndoStack = new SUndoStack();
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     */
+    constructor(parent: SGraphItem | null) {
+        super(parent);
+    } // Constructor
+
+    //////////////////
+    //  以下为对pointList 数组的操作方法
+
+    /**
+     * 储存新的多边形顶点
+     *
+     * @param x   点位得 x 坐标
+     * @param y   点位得 y 坐标
+     * @param i   储存所在索引
+     * @return SPoint 添加的顶点
+     */
+    insertPoint(x: number, y: number, i: number | null = null): SPoint {
+        const point = new SPoint(x, y);
+        if (i == null) {
+            this.pointList.push(point);
+        } else {
+            this.pointList.splice(i, 0, point);
+        }
+        this.update();
+        return point;
+    } // Function insertPoint()
+
+    /**
+     * 删除点位
+     *
+     * @param i   删除点所在的索引
+     * @return 索引不在数组范围则返回 null
+     */
+    deletePoint(i: number | null = null): SPoint | null {
+        let point = null;
+        if (i != null) {
+            if (i >= this.pointList.length || i < 0) {
+                point = null;
+            } else {
+                point = new SPoint(this.pointList[i].x, this.pointList[i].y);
+                this.pointList.splice(i, 1);
+            }
+        } else {
+            if (this.pointList.length) {
+                point = this.pointList[this.pointList.length - 1];
+                this.pointList.pop();
+            } else {
+                point = null;
+            }
+        }
+        this.curIndex = -1;
+        this.curPoint = null;
+        this.update();
+        return point;
+    } // Function deletePoint()
+
+    /**
+     * 多边形顶点的移动位置
+     *
+     * @param x   点位得 x 坐标
+     * @param y   点位得 y 坐标
+     * @param i   点位得 i 坐标
+     * @return   移动对应得点。如果索引无法找到移动顶点,则返回 null
+     */
+    movePoint(x: number, y: number, i: number): SPoint | null {
+        let point = null;
+        if (i >= this.pointList.length || i < 0) {
+            return null;
+        }
+
+        if (this.pointList.length) {
+            this.pointList[i].x = x;
+            this.pointList[i].y = y;
+        }
+
+        point = this.pointList[i];
+        return point;
+    } // Function movePoint()
+
+    ////////////
+    //  以下为三种状态下的绘制多边形方法
+
+    /**
+     * 展示状态 --绘制多边形数组
+     *
+     * @param painter      绘制类
+     * @param pointList    绘制多边形数组
+     */
+    protected drawShowPolygon(painter: SPainter, pointList: SPoint[]): void {
+        painter.save();
+        painter.pen.lineCapStyle = SLineCapStyle.Square;
+        painter.pen.color = this.strokeColor;
+        painter.brush.color = this.fillColor;
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+        if (this.lineStyle == SLineStyle.Dashed) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth * 3),
+                painter.toPx(this.lineWidth * 7)
+            ];
+        } else if (this.lineStyle == SLineStyle.Dotted) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth),
+                painter.toPx(this.lineWidth)
+            ];
+        }
+
+        if (this.selected) {
+            painter.shadow.shadowBlur = 10;
+            painter.shadow.shadowColor = new SColor(`#00000033`);
+            painter.shadow.shadowOffsetX = 5;
+            painter.shadow.shadowOffsetY = 5;
+        } else {
+            painter.shadow.shadowColor = SColor.Transparent;
+        }
+
+        painter.drawPolygon([...pointList]);
+        painter.restore();
+    } // Function drawShowPolygon()
+
+    /**
+     * 创建状态 --绘制多边形数组
+     *
+     * @param painter      绘制类
+     * @param pointList    绘制多边形数组
+     */
+    protected drawCreatePolygon(painter: SPainter, pointList: SPoint[]): void {
+        painter.pen.lineCapStyle = SLineCapStyle.Square;
+        painter.pen.color = this.strokeColor;
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+        if (this.lastPoint && pointList.length) {
+            painter.drawLine(
+                pointList[pointList.length - 1].x,
+                pointList[pointList.length - 1].y,
+                this.lastPoint.x,
+                this.lastPoint.y
+            );
+        }
+
+        painter.drawPolyline(pointList);
+        painter.pen.color = SColor.Transparent;
+        painter.brush.color = new SColor(this.fillColor.value);
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+
+        if (this.lastPoint) {
+            painter.drawPolygon([...pointList, this.lastPoint]);
+            // 绘制顶点块
+            painter.pen.color = SColor.Black;
+            painter.brush.color = SColor.White;
+            pointList.forEach(item => {
+                painter.drawCircle(item.x, item.y, painter.toPx(this.len / 2));
+            });
+            // 如果最后一个点在第一个点的灵敏度范围内,第一个点填充变红
+            if (this.pointList.length) {
+                if (
+                    SMathUtil.pointDistance(
+                        this.lastPoint.x,
+                        this.lastPoint.y,
+                        this.pointList[0].x,
+                        this.pointList[0].y
+                    ) < this.scenceLen
+                ) {
+                    // 绘制第一个点的顶点块
+                    painter.pen.color = SColor.Black;
+                    painter.brush.color = SColor.Red;
+                    painter.drawCircle(
+                        this.pointList[0].x,
+                        this.pointList[0].y,
+                        painter.toPx(this.len / 2)
+                    );
+                }
+            }
+        } else {
+            painter.drawPolygon(pointList);
+        }
+    } // Function drawCreatePolygon()
+
+    /**
+     * 编辑状态 --绘制多边形数组
+     *
+     * @param painter       绘制类
+     * @param pointList    绘制多边形数组
+     */
+    protected drawEditPolygon(painter: SPainter, pointList: SPoint[]): void {
+        // 展示多边形
+        painter.pen.lineCapStyle = SLineCapStyle.Square;
+        painter.pen.color = this.strokeColor;
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+        painter.brush.color = new SColor(this.fillColor.value);
+        painter.drawPolygon([...pointList]);
+        // 绘制顶点块
+        painter.pen.color = SColor.Black;
+        painter.brush.color = SColor.White;
+        pointList.forEach((item, index) => {
+            painter.brush.color = SColor.White;
+            if (index == this.curIndex) {
+                painter.brush.color = new SColor("#2196f3");
+            }
+
+            painter.drawCircle(item.x, item.y, painter.toPx(this.len / 2));
+        });
+    } // Function drawCreatePolygon()
+
+    /**
+     * 编辑状态操作多边形数组
+     *
+     * @param event    鼠标事件
+     */
+    protected editPolygonPoint(event: SMouseEvent): void {
+        //  判断是否为删除状态 isAlt = true为删除状态
+        if (this.isAlt) {
+            // 1 判断是否点击在多边形顶点
+            let lenIndex = -1; // 当前点击到的点位索引;
+            let curenLen = this.scenceLen; // 当前的灵敏度
+            this.pointList.forEach((item, index) => {
+                let dis = SMathUtil.pointDistance(
+                    event.x,
+                    event.y,
+                    item.x,
+                    item.y
+                );
+                if (dis < curenLen) {
+                    curenLen = dis;
+                    lenIndex = index;
+                }
+            });
+            // 若点击到,对该索引对应的点做删除
+            if (lenIndex != -1) {
+                if (this.pointList.length <= 3) {
+                    return;
+                }
+
+                const delePoint = new SPoint(
+                    this.pointList[lenIndex].x,
+                    this.pointList[lenIndex].y
+                );
+                this.deletePoint(lenIndex);
+                // 记录顶点操作记录压入堆栈
+                this.recordAction(SGraphPointListDelete, [
+                    this.pointList,
+                    delePoint,
+                    lenIndex
+                ]);
+            }
+        } else {
+            // 1 判断是否点击在多边形顶点
+            this.curIndex = -1;
+            this.curPoint = null;
+            let lenIndex = -1; // 当前点击到的点位索引;
+            let curenLen = this.scenceLen; // 当前的灵敏度
+            this.pointList.forEach((item, index) => {
+                let dis = SMathUtil.pointDistance(
+                    event.x,
+                    event.y,
+                    item.x,
+                    item.y
+                );
+                if (dis < curenLen) {
+                    curenLen = dis;
+                    lenIndex = index;
+                }
+            });
+            this.curIndex = lenIndex;
+            // 2判断是否点击在多边形得边上
+            if (-1 == lenIndex) {
+                let len = SMathUtil.pointToLine(
+                        new SPoint(event.x, event.y),
+                        new SLine(this.pointList[0], this.pointList[1])
+                    ),
+                    index = 0;
+                if (this.pointList.length > 2) {
+                    for (let i = 1; i < this.pointList.length; i++) {
+                        let dis = SMathUtil.pointToLine(
+                            new SPoint(event.x, event.y),
+                            new SLine(this.pointList[i], this.pointList[i + 1])
+                        );
+                        if (i + 1 == this.pointList.length) {
+                            dis = SMathUtil.pointToLine(
+                                new SPoint(event.x, event.y),
+                                new SLine(this.pointList[i], this.pointList[0])
+                            );
+                        }
+
+                        if (dis.MinDis < len.MinDis) {
+                            len = dis;
+                            index = i;
+                        }
+                    }
+                }
+
+                // 判断是否有点
+                if (len.Point) {
+                    // 点在了多边形的边上
+                    if (len.MinDis <= this.scenceLen) {
+                        this.pointList.splice(index + 1, 0, len.Point);
+                        // 记录新增顶点操作记录压入堆栈
+                        this.recordAction(SGraphPointListInsert, [
+                            this.pointList,
+                            len.Point,
+                            index + 1
+                        ]);
+                    } else {
+                        //没点在多边形边上也没点在多边形顶点上
+                        super.onMouseDown(event);
+                    }
+                }
+            } else {
+                // 当捕捉到顶点后 ,记录当前点的xy坐标,用于undo、redo操作
+                this.curPoint = new SPoint(
+                    this.pointList[this.curIndex].x,
+                    this.pointList[this.curIndex].y
+                );
+            }
+            // 刷新视图
+            this.update();
+        }
+    } // Function editPolygonPoint()
+
+    /////////////////////
+    // undo、redo相关操作
+
+    /**
+     * 记录相关动作并推入栈中
+     *
+     * @param	SGraphCommand   相关命令类
+     * @param	any             对应传入参数
+     */
+    protected recordAction(SGraphCommand: any, any: any[]): void {
+        // 记录相关命令并推入堆栈中
+        const sgraphcommand = new SGraphCommand(this.scene, this, ...any);
+        this.undoStack.push(sgraphcommand);
+    } // Function recordAction()
+
+    /**
+     * 执行取消操作执行
+     */
+    undo(): void {
+        if (this.status == SItemStatus.Normal) {
+            return;
+        }
+        this.undoStack.undo();
+    } // Function undo()
+
+    /**
+     * 执行重做操作执行
+     */
+    redo(): void {
+        if (this.status == SItemStatus.Normal) {
+            return;
+        }
+        this.undoStack.redo();
+    } // Function redo()
+
+    ///////////////////////////////
+    // 以下为鼠标事件
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param event   事件参数
+     * @return 是否处理
+     */
+    onDoubleClick(event: SMouseEvent): boolean {
+        // 如果位show状态 双击改对象则需改为编辑状态
+        if (SItemStatus.Normal == this.status) {
+            this.status = SItemStatus.Edit;
+            this.grabItem(this);
+        } else if (SItemStatus.Edit == this.status) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        }
+
+        this.update();
+        return true;
+    } // Function onDoubleClick()
+
+    /**
+     * 键盘事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+
+    onKeyDown(event: KeyboardEvent): boolean {
+        if (this.status == SItemStatus.Normal) {
+            return false;
+        } else if (this.status == SItemStatus.Create) {
+            if (event.code == "Enter") {
+                // 当顶点大于二个时才又条件执行闭合操作并清空堆栈
+                if (this.pointList.length > 2) {
+                    this.status = SItemStatus.Normal;
+                    //3 传递完成事件状态
+                    this.$emit("finishCreated");
+                    //1 grabItem 置为null
+                    this.releaseItem();
+                }
+            }
+        } else if (this.status == SItemStatus.Edit) {
+            if (event.key == "Alt") {
+                this.isAlt = true;
+            }
+        }
+
+        this.update();
+        return true;
+    } // Function onKeyDown()
+
+    /**
+     * 键盘键抬起事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onKeyUp(event: KeyboardEvent): void {
+        if (this.status == SItemStatus.Edit) {
+            if (event.key == "Alt") {
+                this.isAlt = false;
+            } else if (event.keyCode == SKeyCode.Delete) {
+                // 当多边形的顶点大于三个允许删除点
+                if (this.pointList.length > 3) {
+                    this.deletePoint(this.curIndex);
+                }
+            }
+        }
+
+        this.update();
+    } // Function onKeyUp()
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+
+        // 如果状态为编辑状态则添加点
+        if (this.status == SItemStatus.Create) {
+            // 新增顶点
+            let len = -1;
+            if (this.pointList.length) {
+                len = SMathUtil.pointDistance(
+                    event.x,
+                    event.y,
+                    this.pointList[0].x,
+                    this.pointList[0].y
+                );
+            }
+
+            if (this.pointList.length > 2 && len > 0 && len < this.scenceLen) {
+                this.status = SItemStatus.Normal;
+                //3 传递完成事件状态
+                this.$emit("finishCreated");
+                //1 grabItem 置为null
+                this.releaseItem();
+            } else {
+                this.insertPoint(event.x, event.y);
+                // 记录新增顶点操作记录压入堆栈
+                let pos = new SPoint(event.x, event.y);
+                this.recordAction(SGraphPointListInsert, [this.pointList, pos]);
+            }
+        } else if (this.status == SItemStatus.Edit) {
+            // 对多边形数组做编辑操作
+            this.editPolygonPoint(event);
+        } else {
+            return super.onMouseDown(event);
+        }
+
+        return true;
+    } // Function onMouseDown()
+
+    /**
+     * 鼠标移入事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseEnter(event: SMouseEvent): boolean {
+        return true;
+    } // Function onMouseEnter()
+
+    /**
+     * 鼠标移出事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseLeave(event: SMouseEvent): boolean {
+        return true;
+    } // Function onMouseLeave()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseMove(event: SMouseEvent): boolean {
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+
+        if (this.status == SItemStatus.Create) {
+            this.lastPoint = new SPoint();
+            this.lastPoint.x = event.x;
+            this.lastPoint.y = event.y;
+            this.update();
+        } else if (this.status == SItemStatus.Edit) {
+            if (event.buttons == 1) {
+                if (-1 != this.curIndex) {
+                    this.pointList[this.curIndex].x = event.x;
+                    this.pointList[this.curIndex].y = event.y;
+                }
+            }
+
+            this.update();
+        } else {
+            return super.onMouseMove(event);
+        }
+
+        return true;
+    } // Function onMouseMove()
+
+    /**
+     * shift 垂直水平创建或编辑
+     *
+     * @param event     事件
+     * @return 处理后的事件
+     */
+    compare(event: SMouseEvent): SMouseEvent {
+        if (this.pointList.length) {
+            let last = new SPoint(event.x, event.y);
+            if (this.status == SItemStatus.Create) {
+                last = this.pointList[this.pointList.length - 1];
+            } else if (this.status == SItemStatus.Edit) {
+                if (this.curIndex > 0) {
+                    last = this.pointList[this.curIndex - 1];
+                }
+            }
+
+            const dx = Math.abs(event.x - last.x);
+            const dy = Math.abs(event.y - last.y);
+            if (dy > dx) {
+                event.x = last.x;
+            } else {
+                event.y = last.y;
+            }
+        }
+
+        return event;
+    } // Function compare()
+
+    /**
+     * 鼠标抬起事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseUp(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Edit) {
+            if (-1 != this.curIndex) {
+                const pos = new SPoint(
+                    this.pointList[this.curIndex].x,
+                    this.pointList[this.curIndex].y
+                );
+                this.recordAction(SGraphPointListUpdate, [
+                    this.pointList,
+                    this.curPoint,
+                    pos,
+                    this.curIndex
+                ]);
+            }
+        } else if (this.status == SItemStatus.Normal) {
+            this.moveToOrigin(this.x, this.y);
+            return super.onMouseUp(event);
+        }
+
+        return true;
+    } // Function onMouseUp()
+
+    /**
+     * 移动后处理所有坐标,并肩原点置为场景原点
+     *
+     * @param x   x 坐标
+     * @param y   y 坐标
+     */
+    moveToOrigin(x: number, y: number): void {
+        super.moveToOrigin(x, y);
+        this.pointList = this.pointList.map(t => {
+            t.x = t.x + x;
+            t.y = t.y + y;
+            return t;
+        });
+        this.x = 0;
+        this.y = 0;
+    } // Function moveToOrigin()
+
+    /**
+     * 适配事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onResize(event: SMouseEvent): boolean {
+        return true;
+    } // Function onResize()
+
+    /**
+     * 取消操作
+     */
+    cancelOperate(): void {
+        // 当状态为展示状态
+        if (this.status == SItemStatus.Create) {
+            // 闭合多边形
+            this.parent = null;
+        } else if (this.status == SItemStatus.Edit) {
+            // 编辑状态
+            this.status = SItemStatus.Normal;
+        }
+
+        this.update();
+    } // Function cancelOperate()
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界区域
+     */
+    boundingRect(): SRect {
+        if (this.pointList.length) {
+            this.minX = this.pointList[0].x;
+            this.maxX = this.pointList[0].x;
+            this.minY = this.pointList[0].y;
+            this.maxY = this.pointList[0].y;
+            this.pointList.forEach(it => {
+                let x = it.x,
+                    y = it.y;
+                if (x < this.minX) {
+                    this.minX = x;
+                }
+
+                if (y < this.minY) {
+                    this.minY = y;
+                }
+
+                if (x > this.maxX) {
+                    this.maxX = x;
+                }
+
+                if (y > this.maxY) {
+                    this.maxY = y;
+                }
+
+            });
+        }
+
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     * @return 是否在区域内
+     */
+    contains(x: number, y: number): boolean {
+        let arr = this.pointList;
+        if (arr.length < 3 || !SPolygonUtil.pointIn(x, y, arr)) {
+            return false;
+        }
+
+        return true;
+    } // Function contains()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        this.scenceLen = painter.toPx(this.len);
+        // 当状态为展示状态
+        if (this.status == SItemStatus.Normal) {
+            // 闭合多边形
+            this.drawShowPolygon(painter, this.pointList);
+        } else if (this.status == SItemStatus.Create) {
+            // 创建状态
+            this.drawCreatePolygon(painter, this.pointList);
+        } else {
+            // 编辑状态
+            this.drawEditPolygon(painter, this.pointList);
+        }
+    } // Function onDraw()
+} // Class SPolygonItem

+ 643 - 0
persagy-web-big/src/items/SPolylineItem.ts

@@ -0,0 +1,643 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SColor, SLine, SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { SKeyCode, SMouseEvent, SUndoStack } from "@persagy-web/base";
+import { SItemStatus } from "..";
+import { SMathUtil } from "../utils/SMathUtil";
+import {
+    SGraphItem,
+    SGraphPointListDelete,
+    SGraphPointListInsert,
+    SGraphPointListUpdate,
+    SLineStyle
+} from "@persagy-web/graph";
+
+/**
+ * 折线 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SPolylineItem extends SGraphItem {
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+    /** 折点信息 */
+    pointList: SPoint[] = [];
+    /** 是否绘制完成 */
+    _status: SItemStatus = SItemStatus.Normal;
+    get status(): SItemStatus {
+        return this._status;
+    } // Get status
+    set status(v: SItemStatus) {
+        this._status = v;
+        this.undoStack.clear();
+        this.update();
+    } // Set status
+
+    /** 鼠标移动时的点 */
+    protected lastPoint: SPoint | null = null;
+    /** 线条颜色 */
+    _strokeColor: SColor = SColor.Black;
+    get strokeColor(): SColor {
+        return this._strokeColor;
+    } // Get strokeColor
+    set strokeColor(v: SColor) {
+        this._strokeColor = v;
+        this.update();
+    } // Set strokeColor
+
+    /** 填充色 */
+    _fillColor: SColor = new SColor("#2196f3");
+    get fillColor(): SColor {
+        return this._fillColor;
+    } // Get fillColor
+    set fillColor(v: SColor) {
+        this._fillColor = v;
+        this.update();
+    } // Set fillColor
+
+    /** 线条宽度 */
+    _lineWidth: number = 1;
+    get lineWidth(): number {
+        return this._lineWidth;
+    } // Get lineWidth
+    set lineWidth(v: number) {
+        this._lineWidth = v;
+        this.update();
+    } // Set lineWidth
+
+    /** 边框样式 */
+    _lineStyle: SLineStyle = SLineStyle.Solid;
+    get lineStyle(): SLineStyle {
+        return this._lineStyle;
+    } // Get lineStyle
+    set lineStyle(v: SLineStyle) {
+        this._lineStyle = v;
+        this.update();
+    } // Set lineStyle
+
+    /** 全局灵敏度 */
+    dis: number = 10;
+    /** 灵敏度转换为场景长度 */
+    protected sceneDis: number = 10;
+    /** 当前点索引 */
+    protected curIndex: number = -1;
+    /** 当前点 */
+    private curPoint: SPoint | null = null;
+    /** undo/redo 堆栈 */
+    private undoStack: SUndoStack = new SUndoStack();
+
+    /**
+     * 构造函数
+     *
+     * @param parent    父级
+     * @param list      坐标集合
+     */
+    constructor(parent: null | SGraphItem, list: SPoint[]);
+
+    /**
+     * 构造函数
+     *
+     * @param parent    父级
+     * @param list      第一个坐标
+     */
+    constructor(parent: null | SGraphItem, list: SPoint);
+
+    /**
+     * 构造函数
+     *
+     * @param parent    父级
+     * @param list      第一个坐标|坐标集合
+     */
+    constructor(parent: null | SGraphItem, list: SPoint | SPoint[]) {
+        super(parent);
+        if (list instanceof SPoint) {
+            this.pointList.push(list);
+        } else {
+            this.pointList = list;
+        }
+    } // Constructor
+
+    /**
+     * 添加点至数组中
+     *
+     * @param p         添加的点
+     * @param index     添加到的索引
+     */
+    private addPoint(p: SPoint, index?: number): void {
+        if (index && this.canHandle(index)) {
+            this.pointList.splice(index, 0, p);
+            this.recordAction(SGraphPointListInsert, [
+                this.pointList,
+                p,
+                index
+            ]);
+        } else {
+            this.pointList.push(p);
+            this.recordAction(SGraphPointListInsert, [this.pointList, p]);
+        }
+
+        this.update();
+    } // Function addPoint()
+
+    /**
+     * 是否可以添加点到数组中
+     *
+     * @param index     要添加到的索引
+     * @return 是否可添加
+     */
+    private canHandle(index: number): boolean {
+        return index >= 0 && index <= this.pointList.length;
+    } // Function canHandle()
+
+    /**
+     * 根据索引删除点
+     *
+     * @param index     删除点
+     */
+    deletePoint(index: number): void {
+        if (this.canHandle(index) && this.pointList.length > 2) {
+            const p = new SPoint(
+                this.pointList[this.curIndex].x,
+                this.pointList[this.curIndex].y
+            );
+            this.pointList.splice(index, 1);
+            this.recordAction(SGraphPointListDelete, [
+                this.pointList,
+                p,
+                index
+            ]);
+            this.curIndex = -1;
+            this.curPoint = null;
+            this.update();
+        }
+    } // Function deletePoint
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param event     鼠标事件
+     * @return 是否处理事件
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        this.curIndex = -1;
+        this.curPoint = null;
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+
+        if (event.buttons == 1) {
+            if (this.status == SItemStatus.Create) {
+                this.addPoint(new SPoint(event.x, event.y));
+                return true;
+            } else if (this.status == SItemStatus.Edit) {
+                // 查询鼠标最近的索引
+                this.findNearestPoint(new SPoint(event.x, event.y));
+                // 增加点
+                if (this.curIndex < 0) {
+                    this.findAddPos(new SPoint(event.x, event.y));
+                }
+
+                // 删除点
+                if (event.altKey && this.canHandle(this.curIndex)) {
+                    this.deletePoint(this.curIndex);
+                }
+
+                this.update();
+                return true;
+            } else {
+                return super.onMouseDown(event);
+            }
+        }
+
+        return super.onMouseDown(event);
+    } // Function onMouseDown()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param event     鼠标事件
+     * @return 是否处理事件
+     */
+    onMouseMove(event: SMouseEvent): boolean {
+        if (event.shiftKey) {
+            event = this.compare(event);
+        }
+
+        if (this.status == SItemStatus.Create) {
+            if (this.lastPoint) {
+                this.lastPoint.x = event.x;
+                this.lastPoint.y = event.y;
+            } else {
+                this.lastPoint = new SPoint(event.x, event.y);
+            }
+
+            this.update();
+            return true;
+        } else if (this.status == SItemStatus.Edit) {
+            if (event.buttons == 1) {
+                if (this.canHandle(this.curIndex)) {
+                    this.pointList[this.curIndex].x = event.x;
+                    this.pointList[this.curIndex].y = event.y;
+                }
+            }
+
+            this.update();
+            return true;
+        } else {
+            return super.onMouseMove(event);
+        }
+    } // Function onMouseMove()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param event     鼠标事件
+     * @return 是否处理事件
+     */
+    onMouseUp(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Edit) {
+            if (this.curIndex > -1) {
+                const p = new SPoint(
+                    this.pointList[this.curIndex].x,
+                    this.pointList[this.curIndex].y
+                );
+                this.recordAction(SGraphPointListUpdate, [
+                    this.pointList,
+                    this.curPoint,
+                    p,
+                    this.curIndex
+                ]);
+            }
+        } else if (this.status == SItemStatus.Normal) {
+            this.moveToOrigin(this.x, this.y);
+            return super.onMouseUp(event);
+        }
+
+        return true;
+    } // Function onMouseUp()
+
+    /**
+     * 鼠标双击事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onDoubleClick(event: SMouseEvent): boolean {
+        if (this.status == SItemStatus.Normal) {
+            this.status = SItemStatus.Edit;
+            this.grabItem(this);
+        } else if (this.status == SItemStatus.Edit) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        } else if (this.status == SItemStatus.Create) {
+            if (this.pointList.length > 1) {
+                this.status = SItemStatus.Normal;
+                this.releaseItem();
+                this.$emit("finishCreated");
+            }
+        }
+
+        this.$emit("onDoubleClick", event);
+        return true;
+    } // Function onDoubleClick()
+
+    /***
+     * 键盘按键弹起事件
+     *
+     * @param event     事件参数
+     */
+    onKeyUp(event: KeyboardEvent): void {
+        if (event.keyCode == SKeyCode.Enter) {
+            if (this.pointList.length > 1) {
+                if (this.status == SItemStatus.Create) {
+                    this.$emit("finishCreated");
+                }
+
+                this.status = SItemStatus.Normal;
+                this.releaseItem();
+            }
+        }
+
+        // delete删除点
+        if (
+            event.keyCode == SKeyCode.Delete &&
+            this.status == SItemStatus.Edit
+        ) {
+            this.deletePoint(this.curIndex);
+        }
+    } // Function onKeyUp()
+
+    /**
+     * 移动后处理所有坐标,并肩原点置为场景原点
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     */
+    moveToOrigin(x: number, y: number): void {
+        super.moveToOrigin(x, y);
+        this.pointList = this.pointList.map(t => {
+            t.x = t.x + x;
+            t.y = t.y + y;
+            return t;
+        });
+        this.x = 0;
+        this.y = 0;
+    } // Function moveToOrigin()
+
+    /**
+     * 获取点击点与点集中距离最近点
+     *
+     * @param p     鼠标点击点
+     */
+    findNearestPoint(p: SPoint): void {
+        let len = this.sceneDis;
+        for (let i = 0; i < this.pointList.length; i++) {
+            let dis = SMathUtil.pointDistance(
+                p.x,
+                p.y,
+                this.pointList[i].x,
+                this.pointList[i].y
+            );
+            if (dis < len) {
+                len = dis;
+                this.curIndex = i;
+                this.curPoint = new SPoint(
+                    this.pointList[this.curIndex].x,
+                    this.pointList[this.curIndex].y
+                );
+            }
+        }
+    } // Function findNearestPoint()
+
+    /**
+     * 计算增加点的位置
+     *
+     * @param p     鼠标点击点
+     */
+    findAddPos(p: SPoint): void {
+        let len = SMathUtil.pointToLine(
+                p,
+                new SLine(this.pointList[0], this.pointList[1])
+            ),
+            index = 0;
+        if (this.pointList.length > 2) {
+            for (let i = 1; i < this.pointList.length - 1; i++) {
+                let dis = SMathUtil.pointToLine(
+                    p,
+                    new SLine(this.pointList[i], this.pointList[i + 1])
+                );
+                if (dis.MinDis < len.MinDis) {
+                    len = dis;
+                    index = i;
+                }
+            }
+        }
+
+        if (len.MinDis < this.sceneDis && len.Point) {
+            this.addPoint(len.Point, index + 1);
+        }
+    } // Function findAddPos()
+
+    /**
+     * shift 垂直水平创建或编辑
+     *
+     * @param event     事件
+     * @return 事件对象
+     */
+    compare(event: SMouseEvent): SMouseEvent {
+        if (this.pointList.length) {
+            let last = new SPoint(event.x, event.y);
+            if (this.status == SItemStatus.Create) {
+                last = this.pointList[this.pointList.length - 1];
+            } else if (this.status == SItemStatus.Edit) {
+                if (this.curIndex > 1) {
+                    last = this.pointList[this.curIndex - 1];
+                }
+            }
+
+            const dx = Math.abs(event.x - last.x);
+            const dy = Math.abs(event.y - last.y);
+            if (dy > dx) {
+                event.x = last.x;
+            } else {
+                event.y = last.y;
+            }
+        }
+
+        return event;
+    } // Function compare()
+
+    /**
+     * 记录相关动作并推入栈中
+     *
+     * @param SGraphCommand     相关命令类
+     * @param any               对应传入参数
+     */
+    protected recordAction(SGraphCommand: any, any: any[]): void {
+        // 记录相关命令并推入堆栈中
+        const command = new SGraphCommand(this.scene, this, ...any);
+        this.undoStack.push(command);
+    } // Function recordAction()
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 外接矩阵
+     */
+    boundingRect(): SRect {
+        if (this.pointList.length) {
+            this.minX = this.pointList[0].x;
+            this.maxX = this.pointList[0].x;
+            this.minY = this.pointList[0].y;
+            this.maxY = this.pointList[0].y;
+            this.pointList.forEach(it => {
+                let x = it.x,
+                    y = it.y;
+                if (x < this.minX) {
+                    this.minX = x;
+                }
+
+                if (y < this.minY) {
+                    this.minY = y;
+                }
+
+                if (x > this.maxX) {
+                    this.maxX = x;
+                }
+
+                if (y > this.maxY) {
+                    this.maxY = y;
+                }
+            });
+        }
+
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     * @return 是否在区域内
+     */
+    contains(x: number, y: number): boolean {
+        let p = new SPoint(x, y);
+        for (let i = 1; i < this.pointList.length; i++) {
+            let PTL = SMathUtil.pointToLine(
+                p,
+                new SLine(
+                    this.pointList[i - 1].x,
+                    this.pointList[i - 1].y,
+                    this.pointList[i].x,
+                    this.pointList[i].y
+                )
+            );
+            if (PTL.MinDis < this.sceneDis) {
+                return true;
+            }
+        }
+        return false;
+    } // Function contains()
+
+    /**
+     * 撤销操作
+     */
+    undo(): void {
+        if (this._status != SItemStatus.Normal) {
+            this.undoStack.undo();
+        }
+    } // Function undo()
+
+    /**
+     * 重做操作
+     */
+    redo(): void {
+        if (this._status != SItemStatus.Normal) {
+            this.undoStack.redo();
+        }
+    } // Function redo()
+
+    /**
+     * 取消操作执行
+     */
+    cancelOperate(): void {
+        if (this.status == SItemStatus.Create) {
+            this.parent = null;
+            this.releaseItem();
+        } else if (this.status == SItemStatus.Edit) {
+            this.status = SItemStatus.Normal;
+            this.releaseItem();
+        }
+    } // Function cancelOperate()
+
+    /**
+     * 绘制基本图形
+     *
+     * @param painter   绘制对象
+     */
+    drawBaseLine(painter: SPainter): void {
+        // 绘制基本图形
+        if (this.lineStyle == SLineStyle.Dashed) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth * 3),
+                painter.toPx(this.lineWidth * 7)
+            ];
+        } else if (this.lineStyle == SLineStyle.Dotted) {
+            painter.pen.lineDash = [
+                painter.toPx(this.lineWidth),
+                painter.toPx(this.lineWidth)
+            ];
+        }
+
+        painter.pen.color = this.strokeColor;
+        painter.drawPolyline(this.pointList);
+    } // Function drawBaseLine()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        // 缓存场景长度
+        this.sceneDis = painter.toPx(this.dis);
+        // 创建状态
+        painter.pen.lineWidth = painter.toPx(this.lineWidth);
+        if (this.status == SItemStatus.Create && this.lastPoint) {
+            // 绘制基本图形
+            this.drawBaseLine(painter);
+            painter.drawLine(
+                this.pointList[this.pointList.length - 1],
+                this.lastPoint
+            );
+            this.pointList.forEach((t, i): void => {
+                painter.brush.color = SColor.White;
+                if (i == this.curIndex) {
+                    painter.brush.color = this.fillColor;
+                }
+
+                painter.drawCircle(t.x, t.y, painter.toPx(5));
+            });
+        } else if (this.status == SItemStatus.Edit) {
+            // 绘制基本图形
+            this.drawBaseLine(painter);
+            // 编辑状态
+            this.pointList.forEach((t, i): void => {
+                painter.brush.color = SColor.White;
+                if (i == this.curIndex) {
+                    painter.brush.color = this.fillColor;
+                }
+
+                painter.drawCircle(t.x, t.y, painter.toPx(5));
+            });
+        } else {
+            // 查看状态
+            if (this.selected) {
+                painter.pen.lineWidth = painter.toPx(this.lineWidth * 2);
+                painter.shadow.shadowBlur = 10;
+                painter.shadow.shadowColor = new SColor(`#00000033`);
+                painter.shadow.shadowOffsetX = 5;
+                painter.shadow.shadowOffsetY = 5;
+            }
+
+            // 绘制基本图形
+            this.drawBaseLine(painter);
+        }
+    } // Function onDraw()
+} // Class SPolylineItem

+ 90 - 0
persagy-web-big/src/items/SRectSelectItem.ts

@@ -0,0 +1,90 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SGraphItem } from "@persagy-web/graph";
+import { SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { SMouseEvent } from "@persagy-web/base";
+import { ItemColor, ItemOrder } from "..";
+
+/**
+ * 矩形选择 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SRectSelectItem extends SGraphItem {
+    /** 起点 */
+    startPoint: SPoint = new SPoint();
+    /** 终点 */
+    endPoint: SPoint = new SPoint();
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param point     起点数据
+     */
+    constructor(parent: SGraphItem | null, point: SPoint) {
+        super(parent);
+        this.startPoint = point;
+        this.endPoint = new SPoint(point.x, point.y);
+        this.update();
+        this.zOrder = ItemOrder.rectSelectOrder;
+    } // Constructor
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界区域
+     */
+    boundingRect(): SRect {
+        return new SRect(this.startPoint, this.endPoint);
+    } // Function boundingRect()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param event     事件参数
+     * @return 是否处理
+     */
+    onMouseMove(event: SMouseEvent): boolean {
+        this.endPoint.x = event.x;
+        this.endPoint.y = event.y;
+        this.update();
+        return true;
+    } // Function onMouseMove()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.lineWidth = painter.toPx(2);
+        painter.pen.color = ItemColor.rectSelectOutColor;
+        painter.brush.color = ItemColor.rectSelectInColor;
+        painter.drawRect(this.startPoint, this.endPoint);
+    } // Function onDraw()
+} // SRectSelectItem

+ 34 - 0
persagy-web-big/src/items/STooltipItem.ts

@@ -0,0 +1,34 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { STextItem } from "@persagy-web/graph";
+
+/**
+ * 提示框 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class STooltipItem extends STextItem {} // Class STooltipItem

+ 104 - 0
persagy-web-big/src/items/floor/SBoardItem.ts

@@ -0,0 +1,104 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPainter, SPath, SPoint } from "@persagy-web/draw";
+import { Zone } from "../../types/floor/Zone";
+import { ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 建筑轮廓 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SBoardItem extends SGraphItem {
+    /** 空间所有数据 */
+    data: Zone;
+    /** 空间轮廓线坐标 list */
+    readonly pointArr: SPoint[][][] = [];
+    /** path 数组 */
+    private pathList: SPath[] = [];
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      建筑轮廓数据
+     */
+    constructor(parent: SGraphItem | null, data: Zone) {
+        super(parent);
+        this.data = data;
+        this.zOrder = 0;
+        if (
+            this.data.OutLine.length &&
+            this.data.OutLine[0] &&
+            this.data.OutLine[0].length
+        ) {
+            let tempArr = this.data.OutLine;
+            this.pointArr = tempArr.map((t): SPoint[][] => {
+                let sPath = new SPath();
+                let tempArr = t.map((it): SPoint[] => {
+                    let array = it.map(
+                        (item): SPoint => {
+                            let x = item.X,
+                                y = -item.Y;
+                            return new SPoint(x, y);
+                        }
+                    );
+                    sPath.polygon(array);
+                    return array;
+                });
+                this.pathList.push(sPath);
+                return tempArr;
+            });
+        }
+    } // Constructor
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x     x 坐标
+     * @param y     y 坐标
+     * @return 是否在区域内
+     */
+    contains(x: number, y: number): boolean {
+        return false;
+    } // Function contains()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   painter 对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.lineWidth = painter.toPx(1);
+        painter.brush.color = ItemColor.spaceColor;
+        painter.pen.color = ItemColor.spaceBorderColor;
+        this.pathList.forEach((t): void => {
+            painter.drawPath(t);
+        });
+    } // Function onDraw()
+} // Class SBoardItem

+ 67 - 0
persagy-web-big/src/items/floor/SColumnItem.ts

@@ -0,0 +1,67 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Column } from "../../types/floor/Column";
+import { ItemOrder } from "../..";
+import { SGraphPolyGroupItem, SGraphItem, Point } from "@persagy-web/graph";
+
+/**
+ * 柱子 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SColumnItem extends SGraphPolyGroupItem {
+    /** 柱子数据 */
+    data: Column;
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      柱子数据
+     */
+    constructor(parent: SGraphItem | null, data: Column) {
+        const style = {
+            default: {
+                stroke: "#000000",
+                fill: "#000000",
+                lineWidth: 0,
+                effect: {}
+            }
+        };
+        let tempArr = data.OutLine;
+        let outline: Point[][] = [];
+        if (tempArr && tempArr.length) {
+            outline = tempArr.map(t => {
+                return t.map(it => ({x: it.X, y: -it.Y}));
+            });
+        }
+
+        super(parent, { outline: outline, style: style });
+        this.data = data;
+        this.zOrder = ItemOrder.columnOrder;
+    } // Constructor
+} // Class SColumnItem

+ 158 - 0
persagy-web-big/src/items/floor/SDoorItem.ts

@@ -0,0 +1,158 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Door } from "../../types/floor/Door";
+import { SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { SMathUtil } from "../../utils/SMathUtil";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 门 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SDoorItem extends SGraphItem {
+    /** 门数据 */
+    data: Door;
+    /** 门轮廓线坐标 list */
+    private readonly pointArr: SPoint[] = [];
+    /** 门长度 */
+    private readonly r: number = 0;
+    /** 角度 */
+    private readonly ang: number = 0;
+    /** 旋转点 */
+    private readonly p: SPoint = new SPoint(0, 0);
+    /** 旋转起始角度,结束角度 + Math.PI / 2 */
+    private readonly startAng: number = -Math.PI / 2;
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      门数据
+     */
+    constructor(parent: SGraphItem | null, data: Door) {
+        super(parent);
+        this.data = data;
+        this.zOrder = ItemOrder.doorOrder;
+        if (this.data.OutLine.length) {
+            this.pointArr = this.data.OutLine[0].map(
+                (t): SPoint => {
+                    let x = t.X;
+                    let y = -t.Y;
+                    if (x < this.minX) {
+                        this.minX = x;
+                    }
+                    if (y < this.minY) {
+                        this.minY = y;
+                    }
+                    if (x > this.maxX) {
+                        this.maxX = x;
+                    }
+                    if (y > this.maxY) {
+                        this.maxY = y;
+                    }
+                    return new SPoint(t.X, -t.Y);
+                }
+            );
+
+            let p1 = this.pointArr[0];
+            let p2 = this.pointArr[1];
+            // 旋转点
+            this.p = p1;
+            const HX = (this.data.HandDirection.X = Number(
+                this.data.HandDirection.X.toFixed()
+            ));
+            const HY = (this.data.HandDirection.Y = Number(
+                this.data.HandDirection.Y.toFixed()
+            ));
+            const FX = (this.data.FaceDirection.X = Number(
+                this.data.FaceDirection.X.toFixed()
+            ));
+            const FY = (this.data.FaceDirection.Y = Number(
+                this.data.FaceDirection.Y.toFixed()
+            ));
+            // 向量点乘 => x1 * x2 + y1 * y2,大于0同向
+            let dotProduct = (p2.x - p1.x) * HX + (p2.y - p1.y) * -HY;
+            if (dotProduct > 0) {
+                this.p = p2;
+                p2 = p1;
+                p1 = this.p;
+            }
+            // 两点间距离
+            this.r = SMathUtil.pointDistance(p1.x, p1.y, p2.x, p2.y);
+            // 门朝向角度
+            let fo = Math.atan(-FY / FX);
+            this.ang = FX > 0 ? fo : fo + Math.PI;
+            // 向量叉乘 => x1 * y2 - x2 * y1,小于0是顺时针
+            let direction = (p2.x - p1.x) * -FY - (p2.y - p1.y) * FX;
+            if (direction > 0) {
+                this.startAng = 0;
+            }
+        }
+    } // Constructor
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界矩形
+     */
+    boundingRect(): SRect {
+        return new SRect(0, 0, this.r, this.r);
+    } // Function boundingRect()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.translate(this.p.x, this.p.y);
+        painter.rotate(this.ang);
+        painter.pen.lineWidth = 100;
+        painter.pen.color = ItemColor.doorColor;
+        painter.drawLine(0, 0, this.r, 0);
+        painter.pen.lineDash = [50, 100];
+        painter.pen.lineWidth = painter.toPx(1);
+        // painter.drawArc(
+        //     -this.r,
+        //     -this.r,
+        //     this.r * 2,
+        //     this.r * 2,
+        //     this.startAng,
+        //     this.startAng + Math.PI / 2
+        // );
+    } // Function onDraw()
+} // Class SDoorItem

+ 100 - 0
persagy-web-big/src/items/floor/SHighlightItem.ts

@@ -0,0 +1,100 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SColor, SLine, SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 吸附时高亮对象
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SHighlightItem extends SGraphItem {
+    /** 对象与鼠标位置距离 */
+    distance: number = 0;
+    /** 对象类型 */
+    private type: number = 1;
+
+    /** 点对象数据-当吸附的为线时,此点为垂线与线段的交点 */
+    _point: SPoint = new SPoint();
+    get point(): SPoint {
+        return this._point;
+    } // Get point
+    set point(v: SPoint) {
+        this._point = v;
+        this.type = 1;
+        this.update();
+    } // Set point
+
+    /** 点对象数据 */
+    _line: SLine = new SLine();
+    get line(): SLine {
+        return this._line;
+    } // Get line
+    set line(v: SLine) {
+        this._line = v;
+        this.type = 2;
+        this.update();
+    } // Set line
+
+    /**
+     * 构造函数
+     *
+     * @param parent  指向父对象
+     */
+    constructor(parent: SGraphItem | null) {
+        super(parent);
+        this.visible = false;
+        this.zOrder = ItemOrder.highLightOrder;
+    } // Constructor
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return	边界矩形
+     */
+    boundingRect(): SRect {
+        return new SRect(this.point.x, this.point.y, 10, 10);
+    } // Function boundingRect()
+
+    /**
+     * Item绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        if (this.type == 2) {
+            painter.pen.color = ItemColor.highLightLineColor;
+            painter.pen.lineWidth = painter.toPx(6);
+            painter.drawLine(this.line);
+        }
+
+        painter.pen.color = SColor.Transparent;
+        painter.brush.color = ItemColor.highLightPointColor;
+        painter.drawCircle(this.point.x, this.point.y, painter.toPx(5));
+    } // Function onDraw()
+} // Class SHighlightItem

+ 183 - 0
persagy-web-big/src/items/floor/SSpaceItem.ts

@@ -0,0 +1,183 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import {
+    SColor,
+    SPainter,
+    STextAlign
+} from "@persagy-web/draw";
+import { Space } from "../../types/floor/Space";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem, SGraphAreaGroupItem } from "@persagy-web/graph";
+
+/**
+ * 模型空间 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SSpaceItem extends SGraphAreaGroupItem {
+    /** 空间所有数据 */
+    data: Space;
+    /** 高亮状态 */
+    private _highLightFlag: boolean = false;
+    get highLightFlag(): boolean {
+        return this._highLightFlag;
+    } // Get highLightFlag
+    set highLightFlag(value: boolean) {
+        this._highLightFlag = value;
+        this.update();
+    } // Set highLightFlag
+
+    /** 是否显示名字 */
+    private _showBaseName: boolean = false;
+    get showBaseName(): boolean {
+        return this._showBaseName;
+    } // Get showBaseName
+    set showBaseName(value: boolean) {
+        this._showBaseName = value;
+        this.update();
+    } // Set showBaseName
+
+    /** 是否名字大小 */
+    private _nameSize: number = 10;
+    get nameSize(): number {
+        return this._nameSize;
+    } // Get nameSize
+    set nameSize(value: number) {
+        this._nameSize = value;
+        this.update();
+    } // Set nameSize
+
+    /** 名字是否缩放 */
+    private _nameTransform: boolean = false;
+    get nameTransform(): boolean {
+        return this._nameTransform;
+    } // Get nameTransform
+    set nameTransform(value: boolean) {
+        this._nameTransform = value;
+        this.update();
+    } // Set nameTransform
+
+    /** 名字颜色 */
+    private _nameColor: string = "#000000";
+    get nameColor(): string {
+        return this._nameColor;
+    } // Get nameColor
+    set nameColor(value: string) {
+        this._nameColor = value;
+        this.update();
+    } // Set nameColor
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      空间数据
+     */
+    constructor(parent: SGraphItem | null, data: Space) {
+        super(parent, {
+            outline: [
+                data.OutLine.map(t => t.map(it => ({ x: it.X, y: -it.Y })))
+            ],
+            style: {
+                default: {
+                    stroke: "#2b2b2b",
+                    fill: "#f1fffd80",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                selected: {
+                    stroke: "#2b2b2b",
+                    fill: "#1abc9c",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                disabled: {
+                    stroke: "#2b2b2b",
+                    fill: "#afafaf",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                highlight: {
+                    stroke: "#2b2b2b",
+                    fill: "#fbb029",
+                    lineWidth: 1,
+                    effect: {}
+                }
+            }
+        });
+
+        this.data = data;
+        this.zOrder = ItemOrder.spaceOrder;
+        this.name = data.Name || "";
+    } // Constructor
+
+    /**
+     * 绘制前设置绘制样式
+     *
+     * @return 当前状态
+     */
+    setStyle(): string {
+        let status = "default";
+        if (this.style) {
+            if (this.highLightFlag) {
+                status = "highlight";
+            } else if (this.enabled) {
+                if (this.selected) {
+                    status = "selected";
+                }
+            } else {
+                status = "disabled";
+            }
+        }
+        return status;
+    } // Function setStyle()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        super.onDraw(painter);
+        if (this.showBaseName) {
+            if (this.name && this.name != "null") {
+                painter.brush.color = new SColor(this.nameColor);
+                if (this.nameTransform) {
+                    painter.font.size = this.nameSize;
+                } else {
+                    painter.font.size = painter.toPx(this.nameSize);
+                }
+                painter.font.textAlign = STextAlign.Center;
+                painter.drawText(
+                    this.name,
+                    this.data.Location.Points[0].X,
+                    -this.data.Location.Points[0].Y
+                );
+            }
+        }
+    } // Function onDraw()
+} // Class SSpaceItem

+ 253 - 0
persagy-web-big/src/items/floor/SSpaceItems.ts

@@ -0,0 +1,253 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import {
+    SColor,
+    SPainter,
+    SPoint,
+    SPolygonUtil,
+    SRect,
+    STextAlign
+} from "@persagy-web/draw";
+import { Space } from "../../types/floor/Space";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 模型空间 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated 万达
+ */
+export class SSpaceItems extends SGraphItem {
+    /** 空间所有数据  */
+    data: Space;
+    /** 空间轮廓线坐标list  */
+    readonly pointArr: SPoint[][] = [];
+    /** X坐标最小值  */
+    minX = Number.MAX_SAFE_INTEGER;
+    /** X坐标最大值  */
+    maxX = Number.MIN_SAFE_INTEGER;
+    /** Y坐标最小值  */
+    minY = Number.MAX_SAFE_INTEGER;
+    /** Y坐标最大值  */
+    maxY = Number.MIN_SAFE_INTEGER;
+    /** path对象      */
+    // private path = new SPath2D();
+    /** 高亮状态    */
+    private _highLightFlag: boolean = false;
+    get highLightFlag(): boolean {
+        return this._highLightFlag;
+    } // Get highLightFlag
+    set highLightFlag(value: boolean) {
+        this._highLightFlag = value;
+        this.update();
+    } // Set highLightFlag
+    /** 是否显示名字  */
+    private _showBaseName: boolean = false;
+    get showBaseName(): boolean {
+        return this._showBaseName;
+    } // Get showBaseName
+    set showBaseName(value: boolean) {
+        this._showBaseName = value;
+        this.update();
+    } // Set showBaseName
+    /** 是否名字大小  */
+    private _nameSize: number = 10;
+    get nameSize(): number {
+        return this._nameSize;
+    } // Get nameSize
+    set nameSize(value: number) {
+        this._nameSize = value;
+        this.update();
+    } // Set nameSize
+    /** 名字是否缩放  */
+    private _nameTransform: boolean = false;
+    get nameTransform(): boolean {
+        return this._nameTransform;
+    } // Get nameTransform
+    set nameTransform(value: boolean) {
+        this._nameTransform = value;
+        this.update();
+    } // Set nameTransform
+    /** 名字颜色    */
+    private _nameColor: string = "#000000";
+    get nameColor(): string {
+        return this._nameColor;
+    } // Get nameColor
+    set nameColor(value: string) {
+        this._nameColor = value;
+        this.update();
+    } // Set nameColor
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      空间数据
+     */
+    constructor(parent: SGraphItem | null, data: Space) {
+        super(parent);
+        this.data = data;
+        this.zOrder = ItemOrder.spaceOrder;
+        let tempArr = this.data.OutLine;
+        this.name = data.Name || "";
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map((t): SPoint[] => {
+                let temp = t.map(
+                    (it): SPoint => {
+                        let x = it.X,
+                            y = -it.Y;
+                        if (x < this.minX) {
+                            this.minX = x;
+                        }
+                        if (y < this.minY) {
+                            this.minY = y;
+                        }
+                        if (x > this.maxX) {
+                            this.maxX = x;
+                        }
+                        if (y > this.maxY) {
+                            this.maxY = y;
+                        }
+                        return new SPoint(x, y);
+                    }
+                );
+                // this.path.polygon(temp);
+                return temp;
+            });
+        }
+    } // Constructor
+
+    /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    // /**
+    //  * 鼠标单击事件
+    //  *
+    //  * @param	event         事件参数
+    //  * @return	boolean
+    //  */
+    // onMouseDown(event: SMouseEvent): boolean {
+    //     console.log("spaceDown");
+    //     this.$emit("click", event);
+    //     return true;
+    // } // Function onMouseDown()
+
+    // /**
+    //  * 鼠标移动事件
+    //  *
+    //  * @param event 事件参数
+    //  */
+    // onMouseMove(event: SMouseEvent): boolean {
+    //     return false;
+    // } // Function onMouseMove()
+
+    // /**
+    //  * 鼠标抬起事件
+    //  *
+    //  * @param	event         事件参数
+    //  * @return	boolean
+    //  */
+    // onMouseUp(event: SMouseEvent): boolean {
+    //     console.log("spaceUp");
+    //     return false;
+    // } // Function onClick()
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param x
+     * @param y
+     */
+    contains(x: number, y: number): boolean {
+        let arr = this.pointArr;
+        if (arr.length < 1 || !SPolygonUtil.pointIn(x, y, arr[0])) {
+            return false;
+        }
+
+        for (let i = 1; i < arr.length; i++) {
+            if (SPolygonUtil.pointIn(x, y, arr[i])) {
+                return false;
+            }
+        }
+        return true;
+    } // Function contains()
+
+    /**
+     * Item绘制操作
+     *
+     * @param painter    绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.color = ItemColor.spaceBorderColor;
+        if (this.selected) {
+            painter.brush.color = ItemColor.selectColor;
+        } else if (this.highLightFlag) {
+            painter.brush.color = ItemColor.spaceHighColor;
+        } else {
+            painter.brush.color = ItemColor.spaceColor;
+        }
+        painter.pen.lineWidth = painter.toPx(1);
+        // painter.drawPath(this.path);
+        if (this.pointArr.length) {
+            painter.drawPolygon(this.pointArr[0]);
+        }
+
+        if (this.showBaseName) {
+            if (this.name && this.name != "null") {
+                painter.brush.color = new SColor(this.nameColor);
+                if (this.nameTransform) {
+                    painter.font.size = this.nameSize;
+                } else {
+                    painter.font.size = painter.toPx(this.nameSize);
+                }
+                // painter.font.size = 500;
+                painter.font.textAlign = STextAlign.Center;
+                painter.drawText(
+                    this.name,
+                    this.data.Location.Points[0].X,
+                    -this.data.Location.Points[0].Y
+                );
+            }
+        }
+    } // Function onDraw()
+} // Class SSpaceItem

+ 118 - 0
persagy-web-big/src/items/floor/SVirtualWallItem.ts

@@ -0,0 +1,118 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { VirtualWall } from "../../types/floor/VirtualWall";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 虚拟墙 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SVirtualWallItem extends SGraphItem {
+    /** 虚拟墙数据 */
+    data: VirtualWall;
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+    /** 虚拟墙轮廓线坐标 list */
+    private readonly pointArr: SPoint[][] = [];
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      虚拟墙数据
+     */
+    constructor(parent: SGraphItem | null, data: VirtualWall) {
+        super(parent);
+        this.data = data;
+        this.zOrder = ItemOrder.virtualWallOrder;
+        let tempArr = this.data.OutLine;
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = tempArr.map((t): SPoint[] => {
+                return t.map(
+                    (it): SPoint => {
+                        let x = it.X,
+                            y = -it.Y;
+                        if (x < this.minX) {
+                            this.minX = x;
+                        }
+                        if (y < this.minY) {
+                            this.minY = y;
+                        }
+                        if (x > this.maxX) {
+                            this.maxX = x;
+                        }
+                        if (y > this.maxY) {
+                            this.maxY = y;
+                        }
+                        return new SPoint(x, y);
+                    }
+                );
+            });
+        }
+    } // Constructor
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界矩形
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   painter对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.lineWidth = painter.toPx(1);
+        painter.pen.color = ItemColor.virtualWallColor;
+        painter.pen.lineDash = [20, 20];
+        this.pointArr.forEach((t): void => {
+            painter.drawPolyline(t);
+        });
+    } // Function onDraw()
+} // Class SVirtualWallItem

+ 70 - 0
persagy-web-big/src/items/floor/SWallItem.ts

@@ -0,0 +1,70 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Wall } from "../../types/floor/Wall";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+import { Point, SGraphAreaGroupItem } from "@persagy-web/graph";
+
+/**
+ * 墙 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SWallItem extends SGraphAreaGroupItem {
+    /** 墙数据 */
+    data: Wall;
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      墙数据
+     */
+    constructor(parent: SGraphItem | null, data: Wall) {
+        const style = {
+            default: {
+                stroke: "#000000",
+                fill: "#000000",
+                lineWidth: 0,
+                effect: {}
+            }
+        };
+        let tempArr = data.OutLine;
+        let outline: Point[][] = [];
+        if (tempArr && tempArr.length) {
+            outline = tempArr.map(t => t.map(it => ({ x: it.X, y: -it.Y })));
+        }
+
+        super(parent, {
+            outline: outline.length ? [outline] : [],
+            style: style
+        });
+
+        this.data = data;
+        this.zOrder = ItemOrder.wallOrder;
+    } // Constructor
+} // Class SWallItem

+ 151 - 0
persagy-web-big/src/items/floor/SWallItems.ts

@@ -0,0 +1,151 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPainter, SPath, SPoint, SRect } from "@persagy-web/draw";
+import { Wall } from "../../types/floor/Wall";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 墙item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ * @deprecated 万达
+ */
+export class SWallItems extends SGraphItem {
+    /** 墙数据 */
+    data: Wall;
+    /** X坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+    /** 墙轮廓线坐标list */
+    private readonly pointArr: SPoint[][] = [];
+    /** 墙内轮廓线坐标list */
+    private readonly holesArr: SPoint[][] = [];
+    /** path对象 */
+    private path = new SPath();
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      墙数据
+     */
+    constructor(parent: SGraphItem | null, data: Wall) {
+        super(parent);
+        this.data = data;
+        this.zOrder = ItemOrder.wallOrder;
+        let tempArr = this.data.OutLine;
+        let holes = data.Holes;
+        if (tempArr && tempArr.length) {
+            this.minX = tempArr[0][0].X;
+            this.maxX = this.minX;
+            this.minY = -tempArr[0][0].Y;
+            this.maxY = this.minY;
+            this.pointArr = [];
+            let WLine = tempArr[0].map(
+                (it): SPoint => {
+                    let x = it.X,
+                        y = -it.Y;
+                    if (x < this.minX) {
+                        this.minX = x;
+                    }
+                    if (y < this.minY) {
+                        this.minY = y;
+                    }
+                    if (x > this.maxX) {
+                        this.maxX = x;
+                    }
+                    if (y > this.maxY) {
+                        this.maxY = y;
+                    }
+                    return new SPoint(x, y);
+                }
+            );
+            // 外轮廓
+            this.path.polygon(WLine);
+            // 外轮廓
+            this.pointArr.push(WLine);
+            // 内轮廓
+            if (holes && holes.length) {
+                this.holesArr = holes.map(t => {
+                    let temp = t.map(
+                        (it): SPoint => {
+                            let x = it.X,
+                                y = -it.Y;
+                            if (x < this.minX) {
+                                this.minX = x;
+                            }
+                            if (y < this.minY) {
+                                this.minY = y;
+                            }
+                            if (x > this.maxX) {
+                                this.maxX = x;
+                            }
+                            if (y > this.maxY) {
+                                this.maxY = y;
+                            }
+                            return new SPoint(x, y);
+                        }
+                    );
+                    this.path.polygon(temp);
+                    return temp;
+                });
+            }
+        }
+    } // Constructor
+
+    /**
+     * Item对象边界区域
+     *
+     * @return SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * Item绘制操作
+     *
+     * @param painter    绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.color = ItemColor.wallColor;
+        painter.pen.lineWidth = painter.toPx(1);
+        painter.brush.color = ItemColor.wallColor;
+        painter.drawPath(this.path);
+    } // Function onDraw()
+} // Class SWallItem

+ 109 - 0
persagy-web-big/src/items/floor/SWindowItem.ts

@@ -0,0 +1,109 @@
+
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { Casement } from "../../types/floor/Casement";
+import { ItemOrder, ItemColor } from "../..";
+import { SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 窗户 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SWindowItem extends SGraphItem {
+    /** 窗户数据 */
+    data: Casement;
+    /** 窗户轮廓线坐标 list */
+    private readonly pointArr: SPoint[] = [];
+    /** X 坐标最小值 */
+    private minX = Number.MAX_SAFE_INTEGER;
+    /** X 坐标最大值 */
+    private maxX = Number.MIN_SAFE_INTEGER;
+    /** Y 坐标最小值 */
+    private minY = Number.MAX_SAFE_INTEGER;
+    /** Y 坐标最大值 */
+    private maxY = Number.MIN_SAFE_INTEGER;
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      窗户数据
+     */
+    constructor(parent: SGraphItem | null, data: Casement) {
+        super(parent);
+        this.data = data;
+        this.zOrder = ItemOrder.windowOrder;
+        if (this.data.OutLine.length) {
+            this.pointArr = this.data.OutLine[0].map(
+                (t): SPoint => {
+                    let x = t.X;
+                    let y = -t.Y;
+                    if (x < this.minX) {
+                        this.minX = x;
+                    }
+                    if (y < this.minY) {
+                        this.minY = y;
+                    }
+                    if (x > this.maxX) {
+                        this.maxX = x;
+                    }
+                    if (y > this.maxY) {
+                        this.maxY = y;
+                    }
+                    return new SPoint(x, y);
+                }
+            );
+        }
+    } // Constructor
+
+    /**
+     * Item 对象边界区域
+     *
+     * @return 边界矩形
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            this.minX,
+            this.minY,
+            this.maxX - this.minX,
+            this.maxY - this.minY
+        );
+    } // Function boundingRect()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        painter.pen.color = ItemColor.windowColor;
+        painter.pen.lineWidth = painter.toPx(1);
+        painter.drawPolyline(this.pointArr);
+    } // Function onDraw()
+} // Class SWindowItem

+ 203 - 0
persagy-web-big/src/items/floor/ZoneItem.ts

@@ -0,0 +1,203 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SColor, SPainter, SPoint, SRect } from "@persagy-web/draw";
+import { SMouseEvent } from "@persagy-web/base";
+import { Zone } from "../../types/floor/Zone";
+import { ItemColor, ItemOrder, Transparency } from "../..";
+import { Point, SGraphAreaGroupItem, SGraphItem } from "@persagy-web/graph";
+
+/**
+ * 业务空间 item
+ *
+ * @author  郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SZoneItem extends SGraphAreaGroupItem {
+    /** 空间所有数据 */
+    data: Zone;
+    /** 点击位置坐标 */
+    private clickPoint: SPoint | undefined;
+    /** 高亮状态 */
+    private _highLightFlag: boolean = false;
+    get highLightFlag(): boolean {
+        return this._highLightFlag;
+    } // Get highLightFlag
+    set highLightFlag(value: boolean) {
+        this._highLightFlag = value;
+        this.update();
+    } // Set highLightFlag
+
+    /** 透明度 */
+    _transparency: number = 20;
+    get transparency(): number {
+        return this._transparency;
+    } // Get transparency
+    set transparency(value: number) {
+        this._transparency = value;
+        this.update();
+    } // Set transparency
+
+    /** 受影响状态 */
+    _isInfected: boolean = false;
+    get isInfected(): boolean {
+        return this._isInfected;
+    } // Get isInfected
+    set isInfected(value: boolean) {
+        this._isInfected = value;
+        this.update();
+    } // Set isInfected
+
+    /**
+     * 构造函数
+     *
+     * @param parent    指向父对象
+     * @param data      空间数据
+     */
+    constructor(parent: SGraphItem | null, data: Zone) {
+        super(parent, {
+            outline: data.OutLine.map((t): Point[][] => {
+                return t.map((it): Point[] => {
+                    return it.map(
+                        (item): Point => {
+                            return { x: item.X, y: -item.Y };
+                        }
+                    );
+                });
+            }),
+            style: {
+                default: {
+                    stroke: "#00000000",
+                    fill: "#ffee2280",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                selected: {
+                    stroke: "#00000000",
+                    fill: "#1abc9c",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                highlight: {
+                    stroke: "#00000000",
+                    fill: data.Color || "#fbb029",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                unselect: {
+                    stroke: "#00000000",
+                    fill: "#cecece",
+                    lineWidth: 1,
+                    effect: {}
+                },
+                infected: {
+                    stroke: "#00000000",
+                    fill: "#ff0000",
+                    lineWidth: 1,
+                    effect: {}
+                }
+            }
+        });
+
+        this.data = data;
+        this.zOrder = ItemOrder.zoneOrder;
+        this.highLightFlag = data.HighLightFlag || false;
+        this.transparency = data.Transparency || 20;
+        this.isInfected = data.Infected || false;
+    } // Constructor
+
+    /**
+     * 鼠标单击事件
+     *
+     * @param event     事件参数
+     * @return 是否处理事件
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        if (this.selectable) {
+            this.selected = !this.selected;
+            this.clickPoint = new SPoint(event.x, event.y);
+        }
+        this.$emit("click", event);
+        return true;
+    } // Function onMouseDown()
+
+    /**
+     * 鼠标抬起事件
+     *
+     * @param event     事件参数
+     * @return 是否处理事件
+     */
+    onMouseUp(event: SMouseEvent): boolean {
+        return false;
+    } // Function onMouseUp()
+
+    /**
+     * 绘制前设置绘制样式
+     *
+     * @return 当前状态
+     */
+    setStyle(): string {
+        let status = "default";
+        if (this.style) {
+            if (!this.selectable) {
+                status = "unselect";
+            } else {
+                if (this.selected) {
+                    status = "selected";
+                } else if (this.highLightFlag) {
+                    status = "highlight";
+                } else if (this.isInfected) {
+                    status = "infected";
+                } else {
+                    status = "default";
+                    if (this.data.Color) {
+                        this.style.default.fill = `${this.data.Color}${
+                            Transparency[this.transparency]
+                        }`;
+                    }
+                }
+            }
+        }
+        return status;
+    } // Function setStyle()
+
+    /**
+     * Item 绘制操作
+     *
+     * @param painter   绘制对象
+     */
+    onDraw(painter: SPainter): void {
+        super.onDraw(painter);
+        painter.brush.color = SColor.Black;
+        painter.font.size = painter.toPx(10);
+        if (this.clickPoint) {
+            painter.drawText(
+                this.data.RoomLocalName,
+                this.clickPoint.x,
+                this.clickPoint.y
+            );
+        }
+    } // Function onDraw()
+} // Class ZoneItem

+ 163 - 0
persagy-web-big/src/parser/SFloorParser.ts

@@ -0,0 +1,163 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SParser } from "./SParser";
+import { FloorData } from "../types/FloorData";
+import { Wall } from "../types/floor/Wall";
+import { Column } from "../types/floor/Column";
+import { Casement } from "../types/floor/Casement";
+import { VirtualWall } from "../types/floor/VirtualWall";
+import { Door } from "../types/floor/Door";
+import { Space } from "../types/floor/Space";
+import { SWallItem } from "../items/floor/SWallItem";
+import { SColumnItem } from "../items/floor/SColumnItem";
+import { SDoorItem } from "../items/floor/SDoorItem";
+import { SWindowItem } from "../items/floor/SWindowItem";
+import { SVirtualWallItem } from "../items/floor/SVirtualWallItem";
+import { SSpaceItem } from "../items/floor/SSpaceItem";
+
+/**
+ * 楼层信息解析器
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SFloorParser extends SParser {
+    /** 墙 list */
+    wallList: SWallItem[] = [];
+    /** 柱子 list */
+    columnList: SColumnItem[] = [];
+    /** 门 list */
+    doorList: SDoorItem[] = [];
+    /** 窗 list */
+    casementList: SWindowItem[] = [];
+    /** 虚拟墙 list */
+    virtualWallList: SVirtualWallItem[] = [];
+    /** 空间 list */
+    spaceList: SSpaceItem[] = [];
+
+    /**
+     * 解析数据
+     *
+     * @param data  楼层数据
+     */
+    parseData(data: FloorData): void {
+        if (data.Walls) {
+            data.Walls.forEach((t: Wall): void => {
+                this.addWall(t);
+            });
+        }
+
+        if (data.Columns) {
+            data.Columns.forEach((t: Column): void => {
+                this.addColumn(t);
+            });
+        }
+
+        if (data.Windows) {
+            data.Windows.forEach((t: Casement): void => {
+                this.addCasement(t);
+            });
+        }
+
+        if (data.VirtualWalls) {
+            data.VirtualWalls.forEach((t: VirtualWall): void => {
+                this.addVirtualWall(t);
+            });
+        }
+
+        if (data.Doors) {
+            data.Doors.forEach((t: Door): void => {
+                this.addDoor(t);
+            });
+        }
+
+        if (data.Spaces) {
+            data.Spaces.forEach((t: Space): void => {
+                this.addSpace(t);
+            });
+        }
+    } // Function parseData()
+
+    /**
+     * 添加墙至场景中
+     *
+     * @param t     墙数据
+     */
+    private addWall(t: Wall): void {
+        let item = this.factory.createWall(t);
+        this.wallList.push(item);
+    } // Function addWall()
+
+    /**
+     * 添加柱子至场景中
+     *
+     * @param t   柱子数据
+     */
+    private addColumn(t: Column): void {
+        let item = this.factory.createColumn(t);
+        this.columnList.push(item);
+    } // Function addColumn()
+
+    /**
+     * 添加窗户至场景中
+     *
+     * @param t     窗户数据
+     */
+    private addCasement(t: Casement): void {
+        let item = this.factory.createWindow(t);
+        this.casementList.push(item);
+    } // Function addCasement()
+
+    /**
+     * 添加虚拟墙至场景中
+     *
+     * @param t     虚拟墙数据
+     */
+    private addVirtualWall(t: VirtualWall): void {
+        let item = this.factory.createVirtualWall(t);
+        this.virtualWallList.push(item);
+    } // Function addVirtualWall()
+
+    /**
+     * 添加门至场景中
+     *
+     * @param t     门数据
+     */
+    private addDoor(t: Door): void {
+        let item = this.factory.createDoor(t);
+        this.doorList.push(item);
+    } // Function addDoor()
+
+    /**
+     * 添加空间至场景中
+     *
+     * @param t     空间数据
+     */
+    private addSpace(t: Space): void {
+        let item = this.factory.createSpace(t);
+        this.spaceList.push(item);
+    } // Function addSpace()
+} // class SFloorParser

+ 48 - 0
persagy-web-big/src/parser/SParser.ts

@@ -0,0 +1,48 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SItemFactory } from "..";
+
+/**
+ * 解析器基类
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export abstract class SParser {
+    /** 解析器工厂 */
+    protected factory: SItemFactory = new SItemFactory();
+
+    /**
+     * 构造函数
+     *
+     * @param factory   解析工厂
+     */
+    constructor(factory: SItemFactory | null = null) {
+        if (factory) {
+            this.factory = factory;
+        }
+    } // Constructor
+} // class SParser

+ 85 - 0
persagy-web-big/src/parser/STopologyParser.ts

@@ -0,0 +1,85 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SParser } from "./SParser";
+import { TopologyData } from "../types/TopologyData";
+import { MarkerTopo } from "../types/topology/MarkerTopo";
+import { Node } from "../types/topology/Node";
+import { Relation } from "../types/topology/Relation";
+
+/**
+ * 拓扑图信息解析器
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class STopologyParser extends SParser {
+    /** 节点 list */
+    nodeList = [];
+    /** 标记 list */
+    markList = [];
+    /** 关系 list */
+    relationList = [];
+
+    /**
+     * 解析数据
+     *
+     * @param data  楼层数据
+     */
+    parseData(data: TopologyData): void {
+        if (data.Marks) {
+            data.Marks.forEach((t: MarkerTopo): void => {
+                this.addMarks(t);
+            });
+        }
+
+        if (data.Nodes) {
+            data.Nodes.forEach((t: Node): void => {
+                this.addNodes(t);
+            });
+        }
+
+        if (data.Relations) {
+            data.Relations.forEach((t: Relation): void => {
+                this.addRelations(t);
+            });
+        }
+    } // Function parseData
+
+    /**
+     * 添加标识对象
+     */
+    private addMarks(t: MarkerTopo): void {} // Function addMarks
+
+    /**
+     * 添加关系对象
+     */
+    private addRelations(t: Relation): void {} // Function addRelations
+
+    /**
+     * 添加节点对象
+     */
+    private addNodes(t: Node): void {} // Function addNodes
+} // class STopologyParser

+ 60 - 0
persagy-web-big/src/parser/SZoneParser.ts

@@ -0,0 +1,60 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SParser } from "./SParser";
+import { SZoneItem } from "../items/floor/ZoneItem";
+import { Zone } from "../types/floor/Zone";
+
+/**
+ * 业务空间信息解析器
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SZoneParser extends SParser {
+    /** 业务空间 list */
+    zoneList: SZoneItem[] = [];
+
+    /**
+     * 解析业务空间数据
+     *
+     * @param data  业务空间数据
+     */
+    parseData(data: Zone[]): void {
+        if (data && data.length) {
+            data.forEach((z): void => this.addZone(z));
+        }
+    } // Function parseData()
+
+    /**
+     * 添加业务空间至场景中
+     *
+     * @param z     业务空间数据
+     */
+    private addZone(z: Zone): void {
+        let item = this.factory.createZone(z);
+        this.zoneList.push(item);
+    } // Function addZone()
+} // class SZoneParser

+ 38 - 0
persagy-web-big/src/types/BigPoint.ts

@@ -0,0 +1,38 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+/**
+ * 轮廓坐标接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface BigPoint {
+    /** x 坐标 */
+    X: number;
+    /** y 坐标 */
+    Y: number;
+    /** z 坐标 */
+    Z?: number;
+} // Interface BigPoint

+ 52 - 0
persagy-web-big/src/types/FloorData.ts

@@ -0,0 +1,52 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Door } from "./floor/Door";
+import { Column } from "./floor/Column";
+import { Space } from "./floor/Space";
+import { VirtualWall } from "./floor/VirtualWall";
+import { Wall } from "./floor/Wall";
+import { Casement } from "./floor/Casement";
+
+/**
+ * json 数据接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface FloorData {
+    /** 柱子列表 */
+    Columns: Column[];
+    /** 门列表 */
+    Doors: Door[];
+    /** 空间 */
+    Spaces: Space[];
+    /** 虚拟墙 */
+    VirtualWalls: VirtualWall[];
+    /** 墙 */
+    Walls: Wall[];
+    /** 窗户 */
+    Windows: Casement[];
+} // Interface FloorData

+ 47 - 0
persagy-web-big/src/types/ImageData.ts

@@ -0,0 +1,47 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 图片 item 数据接口
+ *
+ * @author 郝建龙  <haojianlong@sagacloud.cn>
+ */
+export interface ImageData {
+    /** 图片的 id */
+    id?: string;
+    /** 图片的名称 */
+    name?: string;
+    /** X 坐标 */
+    x: number;
+    /** Y 坐标 */
+    y: number;
+    /** 图片 url */
+    url: string;
+    /** 绘制图片的宽 */
+    width: number;
+    /** 绘制图片的高 */
+    height: number;
+} // Interface ImageData

+ 11 - 24
persagy-web-big/src/types/Marker.ts

@@ -17,38 +17,25 @@
  *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
  *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
  *      .:R888888I
- *      .&888888I                                          Copyright (c) 2016-2020.  博锐尚格科技股份有限公司
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
  *        ~8888'
  *        .!88~                                                                     All rights reserved.
  *
  * *********************************************************************************************************************
  */
 
-import { Point } from "@persagy-web/graph/lib/types/Point";
-import { Size } from "@persagy-web/big/lib/types/Size";
-
 /**
- * 标识对象接口
+ * 标记 item 接口
  *
- * @author  张宇
+ * @author 郝建龙  <haojianlong@sagacloud.cn>
  */
 export interface Marker {
-    /** ID */
-    iD?: string;
-    /** 名称  */
-    name: string;
-    /** 图标(Image),线类型(Line) */
-    type: string;
-    /** 位置  */
-    pos: Point;
-    /** 缩放  */
-    scale?: Point;
-    /** 旋转  */
-    rolate?: Point;
-    /** 大小  */
-    size?: Size;
-    /** 绘制时得数据以及样式 */
-    style: any;
-    /** 由应用自己定义  */
-    properties?: any;
+    /** 标记的 id */
+    id?: string;
+    /** 标记的名称 */
+    name?: string;
+    /** X 坐标 */
+    x: number;
+    /** Y 坐标 */
+    y: number;
 } // Interface Marker

+ 39 - 0
persagy-web-big/src/types/MinDis.ts

@@ -0,0 +1,39 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph";
+
+/**
+ * 距离最短点接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface MinDis {
+    /** 最短距离 */
+    MinDis: number;
+    /** 最短距离的点 */
+    Point: Point | undefined;
+} // Interface Space

+ 39 - 0
persagy-web-big/src/types/Outline.ts

@@ -0,0 +1,39 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SPoint } from "@persagy-web/draw";
+
+/**
+ * 轮廓线接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Outline {
+    /** 外轮廓 */
+    Outer: SPoint[];
+    /** 内轮廓 */
+    Inner: SPoint[][];
+} // Interface Outline

+ 39 - 0
persagy-web-big/src/types/Place.ts

@@ -0,0 +1,39 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { BigPoint } from "./BigPoint";
+
+/**
+ * 位置接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Place {
+    /** 定位 */
+    Points: BigPoint[];
+    /** 类型 */
+    Type: string;
+} // Interface Place

+ 41 - 0
persagy-web-big/src/types/PointToLine.ts

@@ -0,0 +1,41 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SLine, SPoint } from "@persagy-web/draw";
+
+/**
+ * 距离最短线接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface PointToLine {
+    /** 最短距离 */
+    MinDis: number;
+    /** 最短距离的线 */
+    Line: SLine | undefined;
+    /** 最短距离的点 */
+    Point: SPoint | undefined;
+} // Interface Space

+ 37 - 0
persagy-web-big/src/types/Size.ts

@@ -0,0 +1,37 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+/**
+ * 大小接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Size {
+    /** 宽 */
+    width: number;
+    /** 高 */
+    height: number;
+} // Interface Size

+ 53 - 0
persagy-web-big/src/types/TextData.ts

@@ -0,0 +1,53 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { STextAlign, STextBaseLine, STextDirection } from "@persagy-web/draw";
+
+/**
+ * 文本 item 数据接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface TextData {
+    /** 文本的 id */
+    id?: string;
+    /** 文本内容 */
+    text: string;
+    /** X 坐标 */
+    x: number;
+    /** Y 坐标 */
+    y: number;
+    /** 文本最大宽 */
+    width?: number;
+    /** 文本对齐方向 */
+    textAlign?: STextAlign;
+    /** 文本基线对齐 */
+    baseLine?: STextBaseLine;
+    /** 文本方向 */
+    textDirection?: STextDirection;
+    /** 文本大小 */
+    size?: number;
+} // Interface TextData

+ 43 - 0
persagy-web-big/src/types/TopologyData.ts

@@ -0,0 +1,43 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Node } from "./topology/Node";
+import { MarkerTopo } from "./topology/MarkerTopo";
+import { Relation } from "./topology/Relation";
+
+/**
+ * 对象关系
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface TopologyData {
+    /** 图例节点 */
+    Nodes: Node[];
+    /** 标识对象 */
+    Marks: MarkerTopo[];
+    /** 对象关系 */
+    Relations: Relation[];
+} // interface TopologyData

+ 55 - 0
persagy-web-big/src/types/floor/Casement.ts

@@ -0,0 +1,55 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Place } from "../Place";
+import { Point } from "@persagy-web/graph";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 窗户 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Casement {
+    /** 位置 */
+    Location: Place;
+    /** 模型 id (外键) */
+    ModelId: string;
+    /** 名称 */
+    Name: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 拥有者的 RevitId */
+    Owner: string;
+    /** 对应 Revit 模型 id */
+    SourceId: string;
+    /** 厚度 */
+    Thick: number;
+    /** 所属墙 */
+    WallId: string;
+    /** 宽度 */
+    Width: string;
+} // interface Casement

+ 49 - 0
persagy-web-big/src/types/floor/Column.ts

@@ -0,0 +1,49 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph";
+import { Place } from "../Place";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 柱子 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Column {
+    /** 名称 */
+    Name?: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 房间边界 */
+    RoomBoundary?: boolean;
+    /** 位置 */
+    Location?: Place;
+    /** 模型 id (外键) */
+    ModelId?: string;
+    /** 对应 Revit 模型 id */
+    SourceId?: string;
+} // Interface Column

+ 59 - 0
persagy-web-big/src/types/floor/Door.ts

@@ -0,0 +1,59 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph";
+import { Place } from "../Place";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 门 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Door {
+    /** 面朝方向 */
+    FaceDirection: BigPoint;
+    /** 把手方向 */
+    HandDirection: BigPoint;
+    /** 位置 */
+    Location: Place;
+    /** 模型 id (外键) */
+    ModelId: string;
+    /** 名称 */
+    Name: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 拥有者的 RevitId */
+    Owner: string;
+    /** 对应 Revit 模型 id */
+    SourceId: string;
+    /** 厚度 */
+    Thick: number;
+    /** 所属墙 */
+    WallId: string;
+    /** 宽度 */
+    Width: string;
+} // Interface Door

+ 55 - 0
persagy-web-big/src/types/floor/Space.ts

@@ -0,0 +1,55 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph";
+import { Place } from "../Place";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 空间 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Space {
+    /** 轮廓线段 */
+    BoundarySegments?: string[];
+    /** 位置 */
+    Location: Place;
+    /** 高度 */
+    Height?: number;
+    /** 模型 id (外键) */
+    ModelId?: string;
+    /** 名称 */
+    Name?: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 对应 Revit 模型 id */
+    SourceId?: string;
+    /** 补充信息 */
+    Tag?: string;
+    /** 类型 */
+    TypeId?: string;
+} // Interface Space

+ 46 - 0
persagy-web-big/src/types/floor/VirtualWall.ts

@@ -0,0 +1,46 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Place } from "../Place";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 虚拟墙 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface VirtualWall {
+    /** 位置 */
+    Location?: Place;
+    /** 模型 id (外键) */
+    ModelId?: string;
+    /** 名称 */
+    Name?: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 对应 Revit 模型 id */
+    SourceId?: string;
+} // interface VirtualWall

+ 52 - 0
persagy-web-big/src/types/floor/Wall.ts

@@ -0,0 +1,52 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Place } from "../Place";
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 墙 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Wall {
+    /** 层 id */
+    LevelId?: string;
+    /** 位置 */
+    Location?: Place;
+    /** 模型 id (外键) */
+    ModelId?: string;
+    /** 名称 */
+    Name?: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][];
+    /** 轮廓线 */
+    Holes?: BigPoint[][];
+    /** 对应 Revit 模型 id */
+    SourceId?: string;
+    /** 厚度 */
+    Width?: number;
+} // Interface Wall

+ 51 - 0
persagy-web-big/src/types/floor/Zone.ts

@@ -0,0 +1,51 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { BigPoint } from "../BigPoint";
+
+/**
+ * 业务空间 item 接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Zone {
+    /** 名称 */
+    RoomLocalName: string;
+    /** 轮廓线 */
+    OutLine: BigPoint[][][];
+    /** 业务空间 id */
+    RoomID: string;
+    /** 颜色 */
+    Color: string;
+    /** 高度 */
+    Height?: number;
+    /** 是否高亮 */
+    HighLightFlag?: boolean;
+    /** 透明度 */
+    Transparency?: number;
+    /** 是否受影响 */
+    Infected?: boolean;
+} // Interface Zone

+ 39 - 0
persagy-web-big/src/types/topology/Anchor.ts

@@ -0,0 +1,39 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph/lib";
+
+/**
+ * 锚点
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Anchor {
+    /** ID */
+    id: string;
+    /** 位置 */
+    pos: Point;
+} // interface Anchor

+ 52 - 0
persagy-web-big/src/types/topology/MarkerTopo.ts

@@ -0,0 +1,52 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph";
+import { Size } from "../Size";
+
+/**
+ * 标识对象接口
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface MarkerTopo {
+    /** ID */
+    id: string;
+    /** 名称 */
+    name: string;
+    /** 类型 */
+    type: string;
+    /** 位置 */
+    pos: Point;
+    /** 缩放 */
+    scale: Point;
+    /** 旋转 */
+    rotate: Point;
+    /** 大小 */
+    size: Size;
+    /** 由应用自己定义 */
+    properties: any;
+} // interface MarkerTo

+ 63 - 0
persagy-web-big/src/types/topology/Node.ts

@@ -0,0 +1,63 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { Point } from "@persagy-web/graph/lib";
+import { Size } from "../Size";
+import { Anchor } from "./Anchor";
+
+/**
+ * 图例节点
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Node {
+    /** ID */
+    id: string;
+    /** 名称 */
+    name: string;
+    /** 图例类型 */
+    graphElementType: string;
+    /** 对应的图元 ID */
+    graphElementId: string;
+    /** 图例数量 */
+    num: number;
+    /** 节点类型 */
+    type: string;
+    /** 位置 */
+    pos: Point;
+    /** 缩放 */
+    scale: Point;
+    /** 旋转 */
+    rotate: Point;
+    /** 大小 */
+    size: Size;
+    /** 锚点 */
+    anchorList: Anchor[];
+    /** 轮廓线 */
+    outLine: Point[][];
+    /** 由应用自己定义 */
+    properties: any;
+} // interface Node

+ 58 - 0
persagy-web-big/src/types/topology/Relation.ts

@@ -0,0 +1,58 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SRelationDir } from "../../enums/SRelationDir";
+import { Point } from "@persagy-web/graph/lib";
+
+/**
+ * 对象关系
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export interface Relation {
+    /** ID */
+    id: string;
+    /** 名称 */
+    name: string;
+    /** 对应的图元 ID */
+    graphElementId: string;
+    /** 关联节点 1_id */
+    node1Id: string;
+    /** 关联节点 2_id */
+    node2Id: string;
+    /** 关联锚点 1_id */
+    anchor1Id: string;
+    /** 关联锚点 2_id */
+    anchor2ID: string;
+    /** 方向 */
+    dir: SRelationDir;
+    /** 直线(Line),水平垂直 */
+    lineType: string;
+    /** 线的顶点坐标 */
+    pointList: Point[];
+    /** 线的绘图样式 */
+    style: any;
+} // interface Relation

+ 352 - 0
persagy-web-big/src/utils/SMathUtil.ts

@@ -0,0 +1,352 @@
+/*
+ * *********************************************************************************************************************
+ *
+ *          !!
+ *        .F88X
+ *        X8888Y
+ *      .}888888N;
+ *        i888888N;        .:!              .I$WI:
+ *          R888888I      .'N88~            i8}+8Y&8"l8i$8>8W~'>W8}8]KW+8IIN"8&
+ *          .R888888I    .;N8888~          .X8'  "8I.!,/8"  !%NY8`"8I8~~8>,88I
+ *            +888888N;  .8888888Y                                  "&&8Y.}8,
+ *            ./888888N;  .R888888Y        .'}~    .>}'.`+>  i}!    "i'  +/'  .'i~  !11,.:">,  .~]!  .i}i
+ *              ~888888%:  .I888888l      .]88~`1/iY88Ii+1'.R$8$8]"888888888>  Y8$  W8E  X8E  W8888'188Il}Y88$*
+ *              18888888    E8888881    .]W%8$`R8X'&8%++N8i,8N%N8+l8%`  .}8N:.R$RE%N88N%N$K$R  188,FE$8%~Y88I
+ *            .E888888I  .i8888888'      .:$8I;88+`E8R:/8N,.>881.`$8E/1/]N8X.Y8N`"KF&&FK!'88*."88K./$88%RN888+~
+ *            8888888I  .,N888888~        ~88i"8W,!N8*.I88.}888%F,i$88"F88"  888:E8X.>88!i88>`888*.}Fl1]*}1YKi'
+ *          i888888N'      I888Y          ]88;/EX*IFKFK88X  K8R  .l8W  88Y  ~88}'88E&%8W.X8N``]88!.$8K  .:W8I
+ *        .i888888N;        I8Y          .&8$  .X88!  i881.:%888>I88  ;88]  +88+.';;;;:.Y88X  18N.,88l  .+88/
+ *      .:R888888I
+ *      .&888888I                                          Copyright (c) 2009-2020.  博锐尚格科技股份有限公司
+ *        ~8888'
+ *        .!88~                                                                     All rights reserved.
+ *
+ * *********************************************************************************************************************
+ */
+
+import { SLine, SPoint, SRect } from "@persagy-web/draw";
+import { MinDis } from "../types/MinDis";
+import { Point } from "@persagy-web/graph";
+import { PointToLine } from "../types/PointToLine";
+import { Outline } from "../types/Outline";
+// @ts-ignore
+import { intersect } from "polybooljs";
+
+/**
+ * 数学工具类
+ *
+ * @author 郝建龙 <haojianlong@sagacloud.cn>
+ */
+export class SMathUtil {
+    /**
+     * 计算点到点距离
+     *
+     * @param x1    点 1 的 x 坐标
+     * @param y1    点 1 的 y 坐标
+     * @param x2    点 2 的 x 坐标
+     * @param y2    点 2 的 y 坐标
+     * @return 距离
+     */
+    static pointDistance(
+        x1: number,
+        y1: number,
+        x2: number,
+        y2: number
+    ): number {
+        return Math.sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
+    } // Function pointDistance()
+
+    /**
+     * 计算点到点集中点最小距离,返回该点和该距离
+     *
+     * @param p     第一个点
+     * @param arr   点集
+     * @return 距离,点坐标
+     */
+    static getMinDisPoint(p: SPoint, arr: Point[]): MinDis | null {
+        if (!arr.length) {
+            return null;
+        }
+
+        let minDis = {
+            // @ts-ignore
+            MinDis: SMathUtil.pointDistance(
+                p.x,
+                p.y,
+                // @ts-ignore
+                arr[0].X || arr[0].x,
+                // @ts-ignore
+                -arr[0].Y || -arr[0].y
+            ),
+            Point: arr[0]
+        };
+        for (let i = 1; i < arr.length; i++) {
+            let ds = SMathUtil.pointDistance(
+                p.x,
+                p.y,
+                // @ts-ignore
+                arr[i].X || arr[i].x,
+                // @ts-ignore
+                -arr[i].Y || -arr[i].y
+            );
+            if (ds < minDis.MinDis) {
+                minDis.MinDis = ds;
+                minDis.Point = arr[i];
+            }
+        }
+        return minDis;
+    } // Function getMinDisPoint()
+
+    /**
+     * 计算点到线段垂线与线段的交点
+     *
+     * @param p     点
+     * @param l     线段
+     * @return 距离
+     */
+    static pointToLine(p: SPoint, l: SLine): PointToLine {
+        let d = {
+            MinDis: Number.MAX_SAFE_INTEGER,
+            Line: new SLine(),
+            Point: new SPoint()
+        };
+        let bgX = Math.max(l.x1, l.x2);
+        let smX = Math.min(l.x1, l.x2);
+        if (l.dx == 0) {
+            // l.dx为0 说明线段是垂直于x轴的
+            let bgY = Math.max(l.y1, l.y2);
+            let smY = Math.min(l.y1, l.y2);
+            if (p.y > smY && p.y < bgY) {
+                d.MinDis = Math.abs(p.x - l.x1);
+                d.Line = l;
+                d.Point = new SPoint(l.x1, p.y);
+            }
+        } else if (l.dy == 0) {
+            // l.dy为0 说明线段是平行于x轴的
+            if (p.x > smX && p.x < bgX) {
+                d.MinDis = Math.abs(p.y - l.y1);
+                d.Line = l;
+                d.Point = new SPoint(p.x, l.y1);
+            }
+        } else {
+            // 直线1
+            let k1 = (l.y1 - l.y2) / (l.x1 - l.x2);
+            let b1 = l.y1 - k1 * l.x1;
+            // 直线2
+            let k2 = -1 / k1;
+            let b2 = p.y - k2 * p.x;
+            // 交点
+            let x = (b1 - b2) / (k2 - k1);
+            let y = k1 * x + b1;
+            if (x > smX && x < bgX) {
+                d.MinDis = SMathUtil.pointDistance(p.x, p.y, x, y);
+                d.Line = l;
+                d.Point = new SPoint(x, y);
+            }
+        }
+
+        return d;
+    } // Function pointDistance()
+
+    /**
+     * 计算点到点集中线段最小距离,返回该点和该距离
+     *
+     * @param p     第一个点
+     * @param arr   点集
+     * @return 距离,点坐标
+     */
+    static getMinDisLine(p: SPoint, arr: Point[]): PointToLine | null {
+        if (arr.length < 2) {
+            return null;
+        }
+
+        let PTL = SMathUtil.pointToLine(
+            p,
+            new SLine(
+                // @ts-ignore
+                arr[arr.length - 1].X || arr[arr.length - 1].x,
+                // @ts-ignore
+                -arr[arr.length - 1].Y || -arr[arr.length - 1].y,
+                // @ts-ignore
+                arr[0].X || arr[0].x,
+                // @ts-ignore
+                -arr[0].Y || -arr[0].y
+            )
+        );
+        for (let i = 0; i < arr.length - 1; i++) {
+            let temp = SMathUtil.pointToLine(
+                p,
+                new SLine(
+                    // @ts-ignore
+                    arr[i].X || arr[i].x,
+                    // @ts-ignore
+                    -arr[i].Y || -arr[i].y,
+                    // @ts-ignore
+                    arr[i + 1].X || arr[i + 1].x,
+                    // @ts-ignore
+                    -arr[i + 1].Y || -arr[i + 1].y
+                )
+            );
+            if (temp.MinDis < PTL.MinDis) {
+                PTL = temp;
+            }
+        }
+        return PTL;
+    } // Function getMinDisPoint()
+
+    /**
+     * 计算矩形是否有交集(外包矩形算法)
+     *
+     * @param rect1     矩形1
+     * @param rect2     矩形2
+     * @return 是否有交集
+     */
+    static rectIntersection(rect1: SRect, rect2: SRect): boolean {
+        let minX = rect1.x < rect2.x ? rect1.x : rect2.x;
+        let minY = rect1.y < rect2.y ? rect1.y : rect2.y;
+        let maxX = rect1.right > rect2.right ? rect1.right : rect2.right;
+        let maxY = rect1.bottom > rect2.bottom ? rect2.bottom : rect2.bottom;
+        return (
+            rect1.width + rect2.width > maxX - minX &&
+            rect1.height + rect2.height > maxY - minY
+        );
+    } // Function rectIntersection()
+
+    /**
+     * 计算线段交点
+     *
+     * @param line1     线段1
+     * @param line2     线段2
+     * @return 交点 null 平行但不重合 'repeat' 重合
+     */
+    static lineIntersection(
+        line1: SLine,
+        line2: SLine
+    ): SPoint | null | string {
+        let k1 = line1.dy / line1.dx;
+        let b1 = line1.y1 - k1 * line1.x1;
+        let k2 = line2.dy / line2.dx;
+        let b2 = line2.y1 - k2 * line2.x1;
+        if (k1 == k2) {
+            if (b1 == b2) {
+                return "repeat";
+            }
+
+            return null;
+        }
+
+        let intersectionX = (b2 - b1) / (k1 - k2);
+        let intersectionY = k1 * intersectionX + b1;
+        let minX = Math.min(line1.x1, line1.x2);
+        let maxX = Math.min(line2.x1, line2.x2);
+        if (intersectionX >= minX && intersectionX <= maxX) {
+            return new SPoint(intersectionX, intersectionY);
+        }
+
+        return null;
+    } // Function lineIntersection()
+
+    /**
+     * 转化数据格式为[][]
+     *
+     * @param SP    点数组
+     * @return 点二维数组
+     */
+    static transferToArray(SP: SPoint[]): number[][] {
+        return SP.map((t): number[] =>([t.x, t.y]));
+    } // Function transferToArray()
+
+    /**
+     * 转化数据格式为 SPoint[]
+     *
+     * @param arr 点二维数组
+     * @return 点数组
+     */
+    static transferToSPoint(arr: number[][]): SPoint[] {
+        return arr.map((t): SPoint => new SPoint(t[0], t[1]));
+    } // Function transferToSPoint()
+
+    /**
+     * 计算数组中每一项的交集,并返回外轮廓与内轮廓
+     *
+     * @param array     三维数组描述轮廓
+     * @return outline 列表
+     */
+    static getIntersectInArray(array: number[][][]): Outline[] {
+        let outlineList: Outline[] = [];
+        if (!array.length) {
+            // 无数据不做处理
+        } else if (array.length == 1) {
+            // 只有一条则为外轮廓
+            let outline: Outline = {
+                Outer: [],
+                Inner: []
+            };
+            outline.Outer = array[0].map(
+                (t): SPoint => {
+                    return new SPoint(t[0], t[1]);
+                }
+            );
+            outlineList.push(outline);
+        } else {
+            // 多条的时候,最后一条未外轮廓,倒序遍历与之相交的为内轮廓,不相交为另外的外轮廓
+            let poly2 = {
+                regions: [],
+                inverted: false
+            };
+            // @ts-ignore
+            poly2.regions.push(array[array.length - 1]);
+            let indexArr: number[] = [array.length - 1];
+            for (let i = array.length - 2; i > 0; i--) {
+                let poly1 = {
+                    regions: [],
+                    inverted: false
+                };
+                // @ts-ignore
+                poly1.regions.push(array[i]);
+                let intersectObj = intersect(poly1, poly2);
+                if (!intersectObj.regions.length) {
+                    indexArr.unshift(i);
+                    poly2.regions = [];
+                    // @ts-ignore
+                    poly2.regions.push(array[i]);
+                }
+            }
+            indexArr.unshift(0);
+            for (let i = 0; i < indexArr.length - 1; i++) {
+                let axArr = array.slice(
+                    i == 0 ? 0 : indexArr[i] + 1,
+                    indexArr[i + 1]
+                );
+                let outline: Outline = {
+                    Outer: [],
+                    Inner: []
+                };
+                outline.Outer = array[indexArr[i + 1]].map(
+                    (t): SPoint =>  new SPoint(t[0], t[1]));
+                outline.Inner = axArr.map((t): SPoint[] =>
+                    t.map((item): SPoint =>  new SPoint(item[0], item[1]))
+                );
+                outlineList.push(outline);
+            }
+        }
+        return outlineList;
+    } // Function getIntersectInArray()
+
+    /**
+     * 计算轮廓线面积
+     *
+     * @param arr   轮廓线
+     * @return 面积(毫米)
+     */
+    static calculateArea(arr: SPoint[]): number {
+        let sum = 0;
+        let n = arr.length;
+        arr[n] = arr[0];
+        for (let i = 1; i <= n; i++) {
+            sum += arr[i].x * arr[i - 1].y - arr[i - 1].x * arr[i].y;
+        }
+
+        return sum / 2;
+    } // Function calculateArea()
+} // Class SMathUtil