Parcourir la source

Merge branch 'master' of http://39.106.8.246:3003/doc/saga-doc

caiaf il y a 4 ans
Parent
commit
041123e765
73 fichiers modifiés avec 110079 ajouts et 283 suppressions
  1. 3 0
      docs/.vuepress/components/example/web/graph/.idea/.gitignore
  2. 6 0
      docs/.vuepress/components/example/web/graph/.idea/misc.xml
  3. 8 0
      docs/.vuepress/components/example/web/graph/.idea/modules.xml
  4. 6 0
      docs/.vuepress/components/example/web/graph/.idea/vcs.xml
  5. 0 1
      docs/.vuepress/components/example/web/graph/Circle1.vue
  6. 3 3
      docs/.vuepress/components/example/web/graph/DrawLine1.vue
  7. 53 0
      docs/.vuepress/components/example/web/graph/MapDemo.vue
  8. 184 0
      docs/.vuepress/components/example/web/graph/scene/Align.vue
  9. 6 4
      docs/.vuepress/components/example/web/graph/scene/ImageItem.vue
  10. 55 0
      docs/.vuepress/components/example/web/graph/scene/PolylineItem.vue
  11. 47 0
      docs/.vuepress/components/example/web/graph/scene/SEditLine.vue
  12. 114 47
      docs/.vuepress/components/example/web/graph/scene/SImgTextItem.vue
  13. 25 27
      docs/.vuepress/components/example/web/graph/scene/TextItem.vue
  14. 83 0
      docs/.vuepress/components/example/web/graph/style/shadow.vue
  15. 12 1
      docs/.vuepress/config.js
  16. 77122 0
      docs/.vuepress/public/assets/map/1.json
  17. BIN
      docs/.vuepress/public/assets/map/1.jsonz
  18. 30621 0
      docs/.vuepress/public/assets/map/2.json
  19. BIN
      docs/.vuepress/public/assets/map/2.jsonz
  20. 3 0
      docs/.vuepress/styles/palette.styl
  21. 14 0
      docs/.vuepress/templates/dev.html
  22. 20 0
      docs/.vuepress/templates/ssr.html
  23. 2 0
      docs/dev/data-center-scheme/README.md
  24. 3 0
      docs/dev/data-center-scheme/dict-ADM.md
  25. 463 0
      docs/dev/data-center-scheme/dict-dataplatform.md
  26. 8 0
      docs/dev/data-center-scheme/index.js
  27. 14 2
      docs/dev/data-center/index.js
  28. 17 11
      docs/dev/data-center/relations/belongs/Bd2Sp.md
  29. 10 5
      docs/dev/data-center/relations/belongs/Eq2Bd.md
  30. 16 9
      docs/dev/data-center/relations/belongs/Eq2Fl.md
  31. 13 6
      docs/dev/data-center/relations/belongs/Eq2Sh.md
  32. 27 18
      docs/dev/data-center/relations/belongs/Eq2Sp.md
  33. 11 7
      docs/dev/data-center/relations/belongs/Fl2Fl.md
  34. 9 3
      docs/dev/data-center/relations/belongs/Pe2Bd.md
  35. 8 2
      docs/dev/data-center/relations/belongs/Pe2Fl.md
  36. 7 1
      docs/dev/data-center/relations/belongs/Pe2Sh.md
  37. 7 1
      docs/dev/data-center/relations/belongs/Pe2Sp.md
  38. 8 3
      docs/dev/data-center/relations/belongs/Sh2Bd.md
  39. 9 2
      docs/dev/data-center/relations/belongs/Sh2Sh.md
  40. 11 5
      docs/dev/data-center/relations/belongs/Sp2Fl.md
  41. 12 6
      docs/dev/data-center/relations/belongs/Sp2Sp.md
  42. 35 6
      docs/dev/data-center/relations/belongs/Sp2Sp2.md
  43. 0 34
      docs/dev/data-center/relations/belongs/Sp2Sp_new.md
  44. 9 3
      docs/dev/data-center/relations/belongs/Sy2Bd.md
  45. 9 3
      docs/dev/data-center/relations/belongs/Sy2Fl.md
  46. 9 3
      docs/dev/data-center/relations/belongs/Sy2Sh.md
  47. 8 2
      docs/dev/data-center/relations/belongs/Sy2Sp.md
  48. 9 3
      docs/dev/data-center/relations/belongs/f_rel_calc.md
  49. BIN
      docs/dev/data-center/relations/belongs/img/sp2sp2-1.png
  50. 10 4
      docs/dev/data-center/relations/other/calc_area_v3.md
  51. BIN
      docs/dev/data-center/relations/other/img/rel_cilin-1.png
  52. 88 0
      docs/dev/data-center/relations/other/is_point_in_polygon_v1.md
  53. 126 0
      docs/dev/data-center/relations/other/is_point_in_polygon_v2.md
  54. 142 0
      docs/dev/data-center/relations/other/is_point_in_polygon_v3.md
  55. 35 14
      docs/dev/data-center/relations/other/calc_vertically_overlap.md
  56. 7 1
      docs/dev/data-center/relations/other/other_ispace_floor_overlap.md
  57. 6 6
      docs/dev/data-center/relations/other/rel_affected_space.md
  58. 43 0
      docs/dev/data-center/relations/other/rel_cilin_str_similar.md
  59. 6 6
      docs/dev/data-center/relations/other/rel_str_similar.md
  60. 110 0
      docs/dev/data-center/relations/other/sim.md
  61. 58 0
      docs/dev/data-center/relations/problems/problems.md
  62. 21 14
      docs/dev/data-center/relations/topology/sys_block.md
  63. 14 8
      docs/dev/data-center/relations/topology/sys_direction.md
  64. 222 5
      docs/dev/paas/data-dict.md
  65. 10 0
      docs/dev/saga-graphy/floor-map/mapDemo.md
  66. 5 0
      docs/dev/saga-graphy/graphy-engine/style.md
  67. 6 2
      docs/dev/saga-graphy/index.js
  68. 16 0
      docs/dev/saga-graphy/scene-manage/align.md
  69. 15 0
      docs/dev/saga-graphy/scene-manage/items/editLine.md
  70. 0 0
      docs/dev/saga-graphy/scene-manage/items/editPolygon.md
  71. 15 0
      docs/dev/saga-graphy/scene-manage/items/editPolyline.md
  72. 1 1
      docs/dev/saga-graphy/scene-manage/items/image.md
  73. 4 4
      package.json

+ 3 - 0
docs/.vuepress/components/example/web/graph/.idea/.gitignore

@@ -0,0 +1,3 @@
+
+# Default ignored files
+/workspace.xml

+ 6 - 0
docs/.vuepress/components/example/web/graph/.idea/misc.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="JavaScriptSettings">
+    <option name="languageLevel" value="ES6" />
+  </component>
+</project>

+ 8 - 0
docs/.vuepress/components/example/web/graph/.idea/modules.xml

@@ -0,0 +1,8 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="ProjectModuleManager">
+    <modules>
+      <module fileurl="file://$PROJECT_DIR$/.idea/graph.iml" filepath="$PROJECT_DIR$/.idea/graph.iml" />
+    </modules>
+  </component>
+</project>

+ 6 - 0
docs/.vuepress/components/example/web/graph/.idea/vcs.xml

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project version="4">
+  <component name="VcsDirectoryMappings">
+    <mapping directory="$PROJECT_DIR$/../../../../../.." vcs="Git" />
+  </component>
+</project>

+ 0 - 1
docs/.vuepress/components/example/web/graph/Circle1.vue

@@ -1,4 +1,3 @@
-import {SLineCapStyle} from "@saga-web/draw/lib";
 <template>
     <canvas id="circle" width="740" height="250" />
 </template>

+ 3 - 3
docs/.vuepress/components/example/web/graph/DrawLine1.vue

@@ -43,12 +43,12 @@
 
             canvas.pen.color = new SColor('#03a9f4');
             canvas.pen.lineWidth = 5;
-            canvas.drawLine(400, 50, 700, 50);
+            canvas.drawLine(450, 50, 700, 50);
             canvas.pen.lineWidth = 3;
-            canvas.pen.dashOffset = new Date().getTime()/50%60;
+            canvas.pen.dashOffset = new Date().getTime()/50%80;
             canvas.pen.lineDash = [30,50];
             canvas.pen.color = SColor.White;
-            canvas.drawLine(400, 50, 700, 50);
+            canvas.drawLine(450, 50, 700, 50);
             this.update();
         }
     }

+ 53 - 0
docs/.vuepress/components/example/web/graph/MapDemo.vue

@@ -0,0 +1,53 @@
+<template>
+    <div>
+        <el-button @click="showMap(1)">查看地图1</el-button>
+        <el-button @click="showMap(2)">查看地图2</el-button>
+        <canvas id="mapDemo" width="740" height="400" tabindex="0"></canvas>
+    </div>
+</template>
+
+<script>
+    import { SGraphScene, SGraphView } from "@saga-web/graph/lib";
+    import { SFloorParser } from "@saga-web/big/lib";
+    export default {
+        name: "mapDemo",
+        data(){
+            return{
+                view:null,
+                scene:null,
+                map1: require('../../../../public/assets/map/1.json'),
+                map2: require('../../../../public/assets/map/2.json'),
+            }
+        },
+        mounted(){
+            this.view = new SGraphView("mapDemo");
+            this.init()
+        },
+        methods:{
+            init(){
+                this.showMap(1);
+            },
+            showMap(id){
+                this.scene = new SGraphScene();
+                this.view.scene = this.scene;
+                let parser = new SFloorParser();
+                parser.parseData(this[`map${id}`].EntityList[0].Elements);
+                parser.spaceList.forEach(t => this.scene.addItem(t));
+                parser.wallList.forEach(t => this.scene.addItem(t));
+                parser.virtualWallList.forEach(t => this.scene.addItem(t));
+                parser.doorList.forEach(t => this.scene.addItem(t));
+                parser.columnList.forEach(t => this.scene.addItem(t));
+                parser.casementList.forEach(t => this.scene.addItem(t));
+                this.view.fitSceneToView();
+            }
+        }
+    }
+</script>
+
+
+<style scoped>
+    canvas{
+        border: 1px solid #eeeeee;
+        outline: none;
+    }
+</style>

+ 184 - 0
docs/.vuepress/components/example/web/graph/scene/Align.vue

@@ -0,0 +1,184 @@
+<template>
+    <div>
+        <el-button @click="addCircle">Circle</el-button>
+        <el-button @click="addRect">Rect</el-button>
+        <el-select placeholder="请选择" @change="changeAlign" v-model="value">
+            <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value"></el-option>
+        </el-select>
+        <canvas id="align" width="740" height="400" tabindex="0"></canvas>
+    </div>
+</template>
+
+<script>
+    import {SGraphItem, SGraphScene, SGraphView, SGraphLayoutType} from "@saga-web/graph/lib";
+    import { SColor, SPainter, SRect } from "@saga-web/draw/lib";
+
+    class RectItem extends SGraphItem {
+        width = 200;
+        height = 100;
+        text = '';
+        constructor(parent) {
+            super(parent);
+            this.moveable = true;
+            this.selectable = true;
+            this.text = new Date().getMilliseconds().toString()
+        }
+
+        boundingRect() {
+            return new SRect(0, 0, this.width, this.height);
+        }
+
+        onDraw(canvas) {
+            canvas.pen.color = SColor.Transparent;
+            canvas.pen.lineWidth = canvas.toPx(1);
+            canvas.brush.color = this.selected ? SColor.Red : new SColor("#00fcee");
+            canvas.drawRect(0, 0, this.width, this.height);
+
+            canvas.pen.lineDash = [10,10];
+            canvas.pen.color = SColor.Yellow;
+            canvas.brush.color = SColor.Transparent;
+            canvas.drawRect(this.boundingRect());
+
+            canvas.brush.color = SColor.Black;
+            canvas.drawText(`${this.x},${this.y}`,0,0);
+
+        }
+    }
+
+    class CircleItem extends SGraphItem {
+        r = 75;
+        text = '';
+
+        constructor(parent) {
+            super(parent);
+            this.moveable = true;
+            this.selectable = true;
+            this.text = new Date().getMilliseconds().toString()
+        }
+
+        boundingRect() {
+            return new SRect(0, 0, this.r * 2, this.r * 2);
+        }
+
+        onDraw(canvas) {
+            canvas.pen.color = SColor.Transparent;
+            canvas.pen.lineWidth = canvas.toPx(1);
+            canvas.brush.color = this.selected ? SColor.Red : new SColor("#00fcee");
+            canvas.drawCircle(this.r, this.r, this.r);
+
+            canvas.pen.color = SColor.Yellow;
+            canvas.brush.color = SColor.Transparent;
+            canvas.pen.lineDash = [10,10];
+            canvas.drawRect(this.boundingRect());
+
+            canvas.brush.color = SColor.Black;
+            canvas.drawText(`${this.x},${this.y}`,0,0);
+        }
+    }
+
+    class SScene extends SGraphScene {
+        /** 定义命令 */
+        cmd = 0;
+
+        constructor() {
+            super();
+        }
+
+
+        onMouseUp(event) {
+            switch(this.cmd) {
+                case 1:
+                    this.addCircle(event.x, event.y);
+                    break;
+                case 2:
+                    this.addRect(event.x, event.y);
+                    break;
+                default:
+                    super.onMouseUp(event);
+            }
+            this.cmd = 0;
+            return false
+        }
+
+        addCircle(x, y) {
+            let item = new CircleItem(null);
+            item.moveTo(x - 50, y - 50);
+            this.addItem(item);
+        }
+
+        addRect(x, y) {
+            let item = new RectItem(null);
+            item.moveTo(x - 50, y - 50);
+            this.addItem(item);
+        }
+    }
+
+    class TestView extends SGraphView {
+        constructor() {
+            super("align");
+        }
+    }
+
+    export default {
+        data() {
+            return {
+                scene: new SScene(),
+                value: -1,
+                options:[
+                    {
+                        value:SGraphLayoutType.Left,
+                        label:'左对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Right,
+                        label:'右对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Top,
+                        label:'顶对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Bottom,
+                        label:'底对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Center,
+                        label:'水平居中对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Middle,
+                        label:'垂直居中对齐'
+                    },
+                    {
+                        value:SGraphLayoutType.Vertical,
+                        label:'垂直分布'
+                    },
+                    {
+                        value:SGraphLayoutType.Horizontal,
+                        label:'水平分布'
+                    }
+                ]
+            }
+        },
+        mounted() {
+            let view = new TestView();
+            view.scene = this.scene;//new SScene(); //this.data.scene;
+        },
+        methods: {
+            addCircle() {
+                this.scene.cmd = 1;
+            },
+            addRect() {
+                this.scene.cmd = 2;
+            },
+            changeAlign(v){
+                this.scene.selectContainer.layout(v)
+                // console.log(this.scene.selectContainer.layout(SGraphLayoutType.Left))
+            }
+        }
+    }
+</script>
+
+<style scoped>
+
+</style>

+ 6 - 4
docs/.vuepress/components/example/web/graph/scene/ImageItem.vue

@@ -10,9 +10,7 @@
 </template>
 
 <script lang="ts">
-    import { SGraphScene, SGraphView } from "@saga-web/graph";
-    import { SImageItem } from "@saga-web/big/lib";
-    import { SImageShowType } from "@saga-web/big/lib/enums/SImageShowType";
+    import { SGraphScene, SGraphView, SImageShowType, SImageItem } from "@saga-web/graph";
 
     class SScene extends SGraphScene {
         imageItem: SImageItem = new SImageItem(null);
@@ -35,6 +33,7 @@
     export default {
         mounted(): void {
             let view = new ImageView();
+            // @ts-ignore
             view.scene = this.scene;
             view.fitSceneToView();
         },
@@ -45,12 +44,15 @@
         },
         methods: {
             Full() {
+                // @ts-ignore
                 this.scene.imageItem.showType = SImageShowType.Full;
             },
             Equivalency() {
+                // @ts-ignore
                 this.scene.imageItem.showType = SImageShowType.Equivalency;
             },
             AutoFit() {
+                // @ts-ignore
                 this.scene.imageItem.showType = SImageShowType.AutoFit;
             },
         }
@@ -59,4 +61,4 @@
 
 <style scoped>
 
-</style>
+</style>

+ 55 - 0
docs/.vuepress/components/example/web/graph/scene/PolylineItem.vue

@@ -0,0 +1,55 @@
+<template>
+    <div>
+        <el-button size="mini" @click="init">清空画布,并初始化折线item</el-button>
+        <el-button size="mini" @click="undo">undo</el-button>
+        <el-button size="mini" @click="redo">redo</el-button>
+        <canvas id="editPolyline" width="740" height="400" tabindex="0"></canvas>
+    </div>
+</template>
+
+<script>
+    import {SGraphScene, SGraphView} from "@saga-web/graph/lib";
+    import {SPolylineItem} from "@saga-web/big/lib";
+    export default {
+        name: "editPolyline",
+        data() {
+            return {
+                scene: null,
+                view: null,
+                item: null,
+            };
+        },
+        mounted() {
+            this.view = new SGraphView("editPolyline");
+            this.scene = new SGraphScene();
+            this.view.scene = this.scene;
+            this.init()
+        },
+        methods:{
+            init(){
+                this.scene.root.children = [];
+                this.item = new SPolylineItem(null,[]);
+                this.scene.addItem(this.item);
+                this.scene.grabItem = this.item;
+                this.view.update();
+            },
+            undo(){
+                if(this.scene.grabItem) {
+                    this.scene.grabItem.undo()
+                }
+            },
+            redo(){
+                if(this.scene.grabItem) {
+                    this.scene.grabItem.redo()
+                }
+            }
+        }
+    }
+</script>
+
+<style scoped>
+canvas{
+    border: 1px solid #eeeeee;
+    outline: none;
+}
+</style>

+ 47 - 0
docs/.vuepress/components/example/web/graph/scene/SEditLine.vue

@@ -0,0 +1,47 @@
+<template>
+    <div>
+        <el-button @click="create">创建</el-button>
+        <el-button @click="undo">undo</el-button>
+        <el-button @click="redo">redo</el-button>
+        <canvas id="editLine" width="740" height="400"  tabindex="0" />
+    </div>
+</template>
+<script>
+    import { SGraphScene, SGraphView } from "@saga-web/graph/";
+    import { SItemStatus } from "@saga-web/big/lib/enums/SItemStatus";
+    import { SLineItem } from "@saga-web/big/lib";
+
+    export default {
+        data() {
+            return {
+                scene: null,
+                view: null
+            };
+        },
+        mounted() {
+            this.view = new SGraphView("editLine");
+            this.scene = new SGraphScene();
+            this.view.scene = this.scene;
+        },
+        methods: {
+            create() {
+                this.scene.root.children = [];
+                const lineItem = new SLineItem(null, [] );
+                lineItem.status = SItemStatus.Create;
+                this.scene.addItem(lineItem);
+                this.scene.grabItem = lineItem;
+                this.view.fitSceneToView();
+            },
+            undo(){
+                if(this.scene.grabItem) {
+                    this.scene.grabItem.undo();
+                }
+            },
+            redo(){
+                if(this.scene.grabItem) {
+                    this.scene.grabItem.redo();
+                }
+            }
+        }
+    };
+</script>

+ 114 - 47
docs/.vuepress/components/example/web/graph/scene/SImgTextItem.vue

@@ -1,51 +1,77 @@
-import {SItemStatus} from "@saga-web/big/lib";
 <template>
     <div>
-        <el-input v-model="input" placeholder="请输入内容"></el-input>
-        <el-button @click="change">00000</el-button>
+        <el-button @click="changemaodian">切换锚点显示状态</el-button>
+        <el-button @click="changetext">切换文本显示状态</el-button>
         <canvas id="editPolygon" width="740" height="400" tabindex="0"></canvas>
     </div>
 </template>
 
 <script lang="ts">
-    import {SGraphItem, SGraphScene, SGraphView} from "@saga-web/graph/lib";
-    import {SImageItem, SItemStatus, SObjectItem, STextItem} from "@saga-web/big/lib";
-    import {SColor, SPainter, SRect, SSize, STextBaseLine} from "@saga-web/draw/lib";
+    import {SGraphItem, SGraphScene, SGraphView, SObjectItem, STextItem, SImageItem, SAnchorItem} from "@saga-web/graph/lib";
+    import { SItemStatus }from "@saga-web/big/lib";
+    import {SColor, SPainter, SRect, SSize} from "@saga-web/draw/lib";
     import {SMouseEvent} from "@saga-web/base/lib";
 
     /**
      * 图例item  icon
      *
      * */
-    class SImgTextItem extends SObjectItem{
+    class SImgTextItem extends SObjectItem {
 
         /** item状态  */
-        _status:SItemStatus = SItemStatus.Create;
-        get status():SItemStatus{
+        _status: SItemStatus = SItemStatus.Normal;
+        get status(): SItemStatus {
             return this._status;
         }
-        set status(v:SItemStatus){
+        set status(v: SItemStatus) {
             this._status = v;
             this.update();
         }
 
         /** 是否显示文字  */
-        _showText:boolean = true;
-        get showText():boolean{
+        _showText: boolean = true;
+        get showText(): boolean {
             return this._showText;
         }
-        set showText(v:boolean){
+        set showText(v: boolean) {
             if (v === this._showText) {
                 return
             }
             this._showText = v;
-            if (v) {
-                this.textItem.show();
-            } else {
-                this.textItem.hide();
-            }
+            this.textItem.visible = v;
+        }
+
+        /** 是否显示锚点  */
+        _showAnchor: boolean = false;
+        get showAnchor():boolean{
+            return this._showAnchor;
+        }
+        set showAnchor(v:boolean){
+            this._showAnchor = v;
+            this.anchorList.forEach(t => {
+                t.visible = v;
+            })
         }
 
+        /** 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
+
         /** img Item    */
         img: SImageItem = new SImageItem(this);
 
@@ -56,21 +82,55 @@ import {SItemStatus} from "@saga-web/big/lib";
          * 构造体
          *
          * */
-        constructor(parent:SGraphItem|null){
+        constructor(parent: SGraphItem | null) {
             super(parent);
             this.img.url = `http://adm.sagacloud.cn:8080/doc/assets/img/logo.png`;
-            setTimeout(() => {
-                this.img.width = 28;
-                this.img.height = 28;
-                this.update();
-            },1000);
-            this.img.isTransform = true;
-            this.textItem.text = `图例item示例`;
-            this.textItem.moveTo(16,0);
-            this.textItem.font.textBaseLine = STextBaseLine.Middle;
+            this.img.width = 32;
+            this.img.height = 32;
+            let anchorPoint = [{ x: 0, y: this.img.height / 2 }, { x: 0, y: -this.img.height / 2 }, { x: -this.img.width / 2, y: 0 }, { x: this.img.width / 2, y: 0 }];
+            this.anchorList = anchorPoint.map(t => {
+                let item = new SAnchorItem(this);
+                item.moveTo(t.x, t.y);
+                return item;
+            });
+            this.update();
+            this.textItem.text = "x2";
+            this.textItem.moveTo(18, -6);
+            this.moveable = true;
+            this.selectable = true;
+            this.textItem.enabled = false;
+            this.img.enabled = false;
+        }
+
+        onMouseEnter(event: SMouseEvent): boolean {
+            this.showAnchor = true;
+            return true;
+        }
+
+        onMouseLeave(event: SMouseEvent): boolean {
+            this.showAnchor = false;
+            return true;
+        }
+
+        onMouseMove(event: SMouseEvent): boolean {
+            return super.onMouseMove(event);
         }
 
         /**
+         * 鼠标按下事件
+         *
+         * */
+        onMouseDown(event: SMouseEvent): boolean {
+            console.log(this.textItem)
+            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 改之前的大小
@@ -87,7 +147,6 @@ import {SItemStatus} from "@saga-web/big/lib";
          * @return  是否处理事件
          * */
         onDoubleClick(event: SMouseEvent): boolean {
-            console.log('doubleclick');
             this.status = SItemStatus.Edit;
             return true;
         } // Function onDoubleClick()
@@ -98,10 +157,10 @@ import {SItemStatus} from "@saga-web/big/lib";
          * @return  SRect   所有子对象的并集
          * */
         boundingRect(): SRect {
-            let rect = new SRect();
-            this.children.forEach(t => {
-                rect = rect.unioned(t.boundingRect());
-            });
+            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;
         } // Function boundingRect()
 
@@ -114,14 +173,10 @@ import {SItemStatus} from "@saga-web/big/lib";
             painter.pen.lineWidth = painter.toPx(1);
             painter.pen.color = new SColor("#00FF00");
             painter.brush.color = SColor.Transparent;
-            painter.drawRect(this.boundingRect());
-            super.onDraw(painter);
-
-            if (this.status == SItemStatus.Edit) {
-                this.anchorList.forEach(t => {
-
-                })
+            if (this.showAnchor) {
+                painter.brush.color = SColor.Gray
             }
+            painter.drawRect(this.boundingRect());
         } // Function onDraw()
     }
 
@@ -137,21 +192,33 @@ import {SItemStatus} from "@saga-web/big/lib";
         },
         mounted() {
             console.log(22222222222222222)
+            // @ts-ignore
             this.view = new SGraphView("editPolygon");
+            // @ts-ignore
             this.scene = new SGraphScene();
+            // @ts-ignore
             this.view.scene = this.scene;
+            // @ts-ignore
             this.init()
         },
         methods:{
             init(){
-                const item = new SImgTextItem(null);
-                item.moveable = true;
-
-                this.scene.addItem(item);
-                this.view.fitSceneToView();
+                // @ts-ignore
+                this.item = new SImgTextItem(null);
+                // @ts-ignore
+                this.item.moveable = true;
+
+                // @ts-ignore
+                this.scene.addItem(this.item);
+                // this.view.fitSceneToView();
             },
-            change() {
-
+            changemaodian(){
+                // @ts-ignore
+                this.item.showAnchor = !this.item.showAnchor;
+            },
+            changetext(){
+                // @ts-ignore
+                this.item.showText = !this.item.showText;
             }
         }
     }

+ 25 - 27
docs/.vuepress/components/example/web/graph/scene/TextItem.vue

@@ -12,16 +12,14 @@
 	</div>
 </template>
 
-<script lang="ts">
-	import { SUndoStack } from "@saga-web/base";
-    import { SFont } from "@saga-web/draw";
-	import { SGraphItem, SGraphScene, SGraphView, SGraphPropertyCommand, SGraphMoveCommand } from "@saga-web/graph";
-	import { SPoint } from "@saga-web/draw/lib";
-	import {STextItem} from "@saga-web/big/lib";
+<script>
+	import { SUndoStack } from "@saga-web/base/lib";
+    import { SFont } from "@saga-web/draw/lib";
+	import { SGraphScene, SGraphView, SGraphPropertyCommand, SGraphMoveCommand, STextItem } from "@saga-web/graph/lib";
 
 	class SScene extends SGraphScene {
 		undoStack = new SUndoStack();
-		textItem: STextItem = new STextItem(null);
+		textItem = new STextItem(null);
 
 		constructor() {
 			super();
@@ -32,7 +30,7 @@
 			this.textItem.connect("onMove", this, this.onItemMove.bind(this));
 		}
 
-		updateText(str: string): void {
+		updateText(str) {
 			if (this.textItem.text !== str) {
 				let old = this.textItem.text;
 				this.textItem.text = str;
@@ -40,7 +38,7 @@
 			}
 		}
 
-		updateColor(color: string): void {
+		updateColor(color) {
 			if (this.textItem.color !== color) {
 				let old = this.textItem.color;
 				this.textItem.color = color;
@@ -48,7 +46,7 @@
 			}
 		}
 
-		updateSize(size: number): void {
+		updateSize(size) {
 			if (this.textItem.font.size !== size) {
 				let old = new SFont(this.textItem.font);
 				let font = new SFont(this.textItem.font);
@@ -58,8 +56,8 @@
 			}
 		}
 
-		onItemMove(item: SGraphItem, ...arg: any): void {
-            this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0] as SPoint, arg[0][1] as SPoint));
+		onItemMove(item, ...arg) {
+            this.undoStack.push(new SGraphMoveCommand(this, item, arg[0][0], arg[0][1]));
         }
 
 	}
@@ -71,13 +69,6 @@
 	}
 
     export default {
-        mounted(): void {
-			let view = new TestView();
-			this.scene.updateText(this.text);
-			this.scene.updateColor(this.color);
-			this.scene.updateSize(this.size);
-			view.scene = this.scene;
-		},
 		data() {
 			return {
 				scene: new SScene(),
@@ -86,23 +77,30 @@
 				color: "#333333",
 			}
 		},
+        mounted() {
+			let view = new TestView();
+			this.scene.updateText(this.text);
+			this.scene.updateColor(this.color);
+			this.scene.updateSize(this.size);
+			view.scene = this.scene;
+		},
 		methods: {
-			handleChangeText(text): void {
-				this.scene.updateText(this.text);
+			handleChangeText(text) {
+				this.scene.updateText(text);
 			},
-			handleChangeColor(color): void {
+			handleChangeColor(color) {
 				this.scene.updateColor(color);
 			},
-			handleChangeSize(size): void {
+			handleChangeSize(size) {
 				this.scene.updateSize(size);
 			},
-			undo(): void {
+			undo() {
 				this.scene.undoStack.undo();
 			},
-			redo(): void {
+			redo() {
 				this.scene.undoStack.redo();
 			},
-			reset(): void {
+			reset() {
 				this.text = "测试文本";
 				this.size = 20;
 				this.color = "#333333";
@@ -116,4 +114,4 @@
 
 <style scoped>
 
-</style>
+</style>

+ 83 - 0
docs/.vuepress/components/example/web/graph/style/shadow.vue

@@ -0,0 +1,83 @@
+<template>
+    <div>
+        阴影扩散范围:<el-input-number @change="changeblur" v-model="blurl" size="mini" style="width: 100px"></el-input-number>
+        x轴偏移量:<el-input-number @change="changeX" v-model="X" size="mini" style="width: 100px"></el-input-number>
+        y轴偏移量:<el-input-number @change="changeY" v-model="Y" size="mini" style="width: 100px"></el-input-number>
+        <el-color-picker @change="changeColor" v-model="color" size="mini" style="vertical-align: middle"></el-color-picker>
+        <canvas id="shadow" width="740" height="400" tabindex="0"></canvas>
+    </div>
+</template>
+
+<script>
+    import {SGraphScene, SGraphView} from "@saga-web/graph/lib";
+    import { SCanvasView, SColor, SPainter } from "@saga-web/draw/lib";
+
+    class shadowView extends SCanvasView {
+
+        constructor(id) {
+            super(id);
+            this.blurArr = [1,2,3,4,5,6,7,8,9,10];
+            this.shadowBlur = 10;
+            this.shadowColor = new SColor('#CCCCCC');
+            this.shadowOffsetX = 10;
+            this.shadowOffsetY = 10;
+        }
+
+        onDraw(canvas) {
+            canvas.clearRect(0,0,740,400);
+
+            canvas.pen.lineWidth = 1;
+            canvas.pen.color = SColor.Black;
+            canvas.brush.color = SColor.White;
+            canvas.shadow.shadowBlur = this.shadowBlur;
+            canvas.shadow.shadowColor = this.shadowColor;
+            canvas.shadow.shadowOffsetX = this.shadowOffsetX;
+            canvas.shadow.shadowOffsetY = this.shadowOffsetY;
+            canvas.drawRect(270,100,100,100);
+        }
+    }
+    export default {
+        name: "shadow",
+        data(){
+            return {
+                view: null,
+                blurl: 10,
+                X:10,
+                Y:10,
+                color:"#CCCCCC"
+            }
+        },
+        mounted() {
+            this.view = new shadowView('shadow');
+        },
+        methods:{
+            // 修改扩散距离
+            changeblur(v) {
+                this.view.shadowBlur = v;
+                this.view.update()
+            },
+            // x轴偏移量
+            changeX(v){
+                this.view.shadowOffsetX = v;
+                this.view.update()
+            },
+            // y轴偏移量
+            changeY(v){
+                this.view.shadowOffsetY = v;
+                this.view.update()
+            },
+            // 修改颜色
+            changeColor(v){
+                this.view.shadowColor = new SColor(v);
+                this.view.update()
+            }
+        }
+    }
+</script>
+
+<style scoped>
+    canvas{
+        border: 1px solid #eeeeee;
+        outline: none;
+    }
+</style>

+ 12 - 1
docs/.vuepress/config.js

@@ -5,6 +5,7 @@ const dataCenterContent = require("../dev/data-center/index");
 const paasContent = require("../dev/paas/index");
 const revitCenterContent = require("../dev/revit-center/index");
 const sagaGraphyContent = require("../dev/saga-graphy/index");
+const dataCenterScheme = require("../dev/data-center-scheme/index");
 
 module.exports = {
     title: "数字化交付开发文档",
@@ -67,6 +68,15 @@ module.exports = {
                             { text: "系统图", link: "/dev/database/topo/" }
                         ]
                     },
+                    {
+                        text: "新版数据字典物理世界对接",
+                        items: [
+                            { text: "新版字典中台工具接口对接", link: "/dev/data-center-scheme/" },
+                            // { text: "新版字典ADM对接", link: "/dev/data-center-scheme/" },
+                            // { text: "新版字典对接数据中心", link: "/dev/data-center-scheme/" },
+                            // { text: "新版物理世界对接数据中心", link: "/dev/data-center-scheme/" }
+                        ]
+                    },
                 ]
             },
             {
@@ -84,7 +94,7 @@ module.exports = {
                     {
                         text: "Web开发",
                         items: [
-                            { text: "图形引擎", link: "http://adm.sagacloud.cn:8080/api/web/graphy/" },
+                            { text: "图形引擎", link: "http://adm.sagacloud.cn:8080/api/web/graph/" },
                             { text: "建筑信息图", link: "http://adm.sagacloud.cn:8080/api/web/big/" }
                         ]
                     },
@@ -117,6 +127,7 @@ module.exports = {
             "/dev/paas/" : paasContent,
             "/dev/revit-center/" : revitCenterContent,
             "/dev/saga-graphy/": sagaGraphyContent,
+            "/dev/data-center-scheme/" : dataCenterScheme,
         }
     }
 };

Fichier diff supprimé car celui-ci est trop grand
+ 77122 - 0
docs/.vuepress/public/assets/map/1.json


BIN
docs/.vuepress/public/assets/map/1.jsonz


Fichier diff supprimé car celui-ci est trop grand
+ 30621 - 0
docs/.vuepress/public/assets/map/2.json


BIN
docs/.vuepress/public/assets/map/2.jsonz


+ 3 - 0
docs/.vuepress/styles/palette.styl

@@ -0,0 +1,3 @@
+body{
+  user-select :none;
+}

+ 14 - 0
docs/.vuepress/templates/dev.html

@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1">
+    <title></title>
+</head>
+<body>
+<script>
+    const Image = window.Image;//定义global
+</script>
+<div id="app"></div>
+</body>
+</html>

+ 20 - 0
docs/.vuepress/templates/ssr.html

@@ -0,0 +1,20 @@
+<!DOCTYPE html>
+<html lang="{{ lang }}">
+<head>
+    <meta charset="utf-8">
+    <meta name="viewport" content="width=device-width,initial-scale=1">
+    <title>{{ title }}</title>
+    <meta name="generator" content="VuePress {{ version }}">
+    {{{ userHeadTags }}}
+    {{{ pageMeta }}}
+    {{{ renderResourceHints() }}}
+    {{{ renderStyles() }}}
+    <script>
+        const Image = window.Image;//定义global变量
+    </script>
+</head>
+<body>
+<!--vue-ssr-outlet-->
+{{{ renderScripts() }}}
+</body>
+</html>

+ 2 - 0
docs/dev/data-center-scheme/README.md

@@ -0,0 +1,2 @@
+# 数据中台字典、新版物理世界、新版ADM 对接方案
+

+ 3 - 0
docs/dev/data-center-scheme/dict-ADM.md

@@ -0,0 +1,3 @@
+# 新版字典ADM对接方案
+
+

+ 463 - 0
docs/dev/data-center-scheme/dict-dataplatform.md

@@ -0,0 +1,463 @@
+# 中台工具字典接口使用对接方案
+测试环境IP以及端口号
+```
+172.16.44.212:8081/paas
+```
+
+
+## 集团管理
+
+#### 查询所有集团列表 
+```
+POST: /usercenter/groupCompany/query
+```
+
+请求参数
+```
+{}
+```
+
+应答内容
+
+```
+{
+    "result": "success",
+    "data": [
+        {
+            "code": "SN",             集团id
+            "name": "苏宁集团"         集团名称
+        },
+        {
+            "code": "WD",
+            "name": "万达集团"
+        },
+        {
+            "code": "WK",
+            "name": "万科集团"
+        }
+    ],
+    "count": 3
+}
+```
+
+#### 添加集团
+
+```
+POST: /usercenter/groupCompany/save
+```
+请求参数
+```
+{
+    "code":"546455",      集团id
+    "name":"12123213"     集团名称
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success"
+}
+```
+
+#### 编辑集团信息 注意编辑集团和创建使用的同一个接口
+
+```
+POST: /usercenter/groupCompany/save
+```
+请求参数
+```
+{
+    "code":"546455",      集团id
+    "name":"12123213"     集团名称
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success"
+}
+```
+
+##### 中台工具中只修改集团名称,前端控制ID不可以修改,确保集团id入参是要修改集团ID否则会创建新的集团
+
+
+#### 集团字典搜索 功能前端自行筛选
+
+创建集团后,自动创建集团字典(字典默认为平台字典全部内容);并创建默认方案(默认为集团字典全部内容)
+
+创建集团后调用创建方案接口 ,然后调用方案订阅接口订阅所有类型,以及每个类型下的信息点
+
+#### 创建集团下默认方案
+
+```
+dict/scheme/create
+```
+
+请求参数
+
+```
+{
+    "groupId":"142563",             集团id
+    "note":null,                    备注
+    "name":"默认方案"                方案名称
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success",
+    "id":5
+}
+```
+
+
+方案中订阅类型  需要把平台级字典的所有类型查询出来  然后组合成数组调用方案订阅接口   
+方案种类型订阅信息点,需要把平台级的每个类型的信息点查出来,然后一个一个类型的信息点通过接口执行订阅
+
+## 项目管理
+
+#### 根据集团查询项目
+
+```
+POST: usercenter/project/query
+```
+
+请求参数
+
+```
+{
+    "criteria":{
+        "groupCompanyCode":"WK"   集团id
+    }
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success",
+    "data":[
+        {
+            "id":"Pj1106479820",
+            "name":"北京万科国际大厦",
+            "groupCompany":{
+                "code":"WK",
+                "name":"万科集团"
+            }
+        }
+    ],
+    "count":1
+}
+```
+
+#### 添加项目
+
+```
+POST: usercenter/project/save
+```
+
+请求参数
+
+```
+{
+    "id":"Pj3264971164",      项目id
+    "name":"测试项目",         项目名称
+    "groupCompany":{          
+        "code":"WK"           集团id
+    }
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success"
+}
+```
+#### 集团方案列表
+
+```
+POST: /dict/scheme/query
+```
+
+请求参数
+
+```
+{
+    "criteria":{
+        "groupId":"WD"  集团id
+    }
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success",
+    "data":[
+        {
+            "id":3,                         方案id
+            "name":"商业综合体",             方案名称
+            "groupId":"WD"                  集团id
+        },
+        {
+            "id":4,
+            "name":"酒店管理方案",
+            "note":"wanda03156",
+            "groupId":"WD"
+        }
+    ],
+    "count":2
+}
+```
+#### 项目设置集团方案
+
+```
+dict/scheme/project/set
+```
+
+请求参数
+
+```
+{
+    "criteria":{
+        "projectId":[    项目id列表
+            "Pj1101050029"
+        ]
+    }
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success"
+}
+```
+
+#### 编辑项目
+
+```
+POST: usercenter/project/save
+```
+
+请求参数
+
+```
+{
+    "id":"Pj1101050029",            项目id
+    "name":"东坝万达广场1",           项目名称
+    "groupCompany":{                集团对象
+        "code":"WD",                集团id
+        "name":"万达集团"            集团名称
+    }
+}
+```
+
+应答内容
+
+```
+{
+    "result":"success"
+}
+```
+
+## 集团字典
+
+### 集团字典管理
+
+#### 获取集团下类型树结构
+
+```
+ Get: dict/class?&groupId=WD&subFlag=false     //groupId: 集团id   subFlag: 是否显示所有子分类
+```
+
+应答内容
+
+```
+{
+    "result":"success",
+    "data":[
+        {
+            "code":"project",
+            "name":"项目",
+            "aliasCode":"project",
+            "aliasName":"项目"
+        },
+        {
+            "code":"building",
+            "name":"建筑",
+            "aliasCode":"building",
+            "aliasName":"建筑"
+        },
+        {
+            "code":"floor",
+            "name":"楼层",
+            "aliasCode":"floor",
+            "aliasName":"楼层"
+        },
+        {
+            "code":"space",
+            "name":"空间",
+            "aliasCode":"space",
+            "aliasName":"空间"
+        },
+        {
+            "code":"system",
+            "name":"系统",
+            "aliasCode":"system",
+            "aliasName":"系统",
+            "children":[
+                {
+                    "code":"system-AC",
+                    "name":"空调专业",
+                    "aliasCode":"system-AC",
+                    "aliasName":"空调专业",
+                    "children":[
+                        {
+                            "code":"ACAT",
+                            "name":"空调末端系统",
+                            "aliasCode":"ACAT",
+                            "aliasName":"空调末端系统",
+                            "parentCode":"system",
+                            "majorCode":"AC"
+                        },
+                        {
+                            "code":"ACAD",
+                            "name":"空调人防系统",
+                            "aliasCode":"ACAD",
+                            "aliasName":"空调人防系统",
+                            "parentCode":"system",
+                            "majorCode":"AC"
+                        }
+                    ]
+                },
+                {
+                    "code":"system-FF",
+                    "name":"消防专业",
+                    "aliasCode":"system-FF",
+                    "aliasName":"消防专业",
+                    "children":[
+                        {
+                            "code":"FFSC",
+                            "name":"防排烟系统",
+                            "aliasCode":"FFSC",
+                            "aliasName":"防排烟系统",
+                            "parentCode":"system",
+                            "majorCode":"FF"
+                        }
+                    ]
+                }
+            ]
+        },
+        {
+            "code":"equipment",
+            "name":"设备",
+            "aliasCode":"equipment",
+            "aliasName":"设备",
+            "children":[
+                {
+                    "code":"equipment-AC",
+                    "name":"空调专业",
+                    "aliasCode":"equipment-AC",
+                    "aliasName":"空调专业",
+                    "children":[
+                        {
+                            "code":"equipment-ACAT",
+                            "name":"空调末端系统",
+                            "aliasCode":"equipment-ACAT",
+                            "aliasName":"空调末端系统",
+                            "children":[
+                                {
+                                    "code":"ACATAH",
+                                    "name":"空调机组",
+                                    "aliasCode":"ACATAH",
+                                    "aliasName":"空调机组",
+                                    "parentCode":"equipment",
+                                    "majorCode":"AC",
+                                    "systemCode":"ACAT"
+                                }
+                            ]
+                        },
+                        {
+                            "code":"equipment-ACCH",
+                            "name":"中央供热系统",
+                            "aliasCode":"equipment-ACCH",
+                            "aliasName":"中央供热系统",
+                            "children":[
+                                {
+                                    "code":"ACCHWT",
+                                    "name":"供热水箱",
+                                    "aliasCode":"ACCHWT",
+                                    "aliasName":"供热水箱",
+                                    "parentCode":"equipment",
+                                    "majorCode":"AC",
+                                    "systemCode":"ACCH"
+                                }
+                            ]
+                        }
+                    ]
+                }
+            ]
+        }
+    ]
+}
+```
+
+
+
+
+
+
+
+
+
+## 注意事项
+1.某一个类型显示子分类功能新版字典还没有实现
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 
+
+

+ 8 - 0
docs/dev/data-center-scheme/index.js

@@ -0,0 +1,8 @@
+const content = [
+
+            // ["/dev/data-center-scheme/dict-dataplatform", "中台工具字典接口使用对接方案"],
+            ["/dev/data-center-scheme/dict-ADM", "新版字典ADM对接方案"],
+            ["/dev/data-center-scheme/dict-dataplatform", "关系表设计"]
+];
+
+module.exports = content;

+ 14 - 2
docs/dev/data-center/index.js

@@ -32,7 +32,7 @@ const content = [
             ["/dev/data-center/relations/belongs/Sh2Sh", "竖井贯通关系"],
             ["/dev/data-center/relations/belongs/Sp2Fl", "业务空间所属楼层"],
             ["/dev/data-center/relations/belongs/Sp2Sp", "业务空间邻接关系"],
-            ["/dev/data-center/relations/belongs/Sp2Sp_new", "业务空间邻接关系(新)"],
+            ["/dev/data-center/relations/belongs/Sp2Sp2", "业务空间邻接关系(新)"],
             ["/dev/data-center/relations/belongs/Sy2Bd", "系统所在建筑"],
             ["/dev/data-center/relations/belongs/Sy2Fl", "系统所在楼层"],
             ["/dev/data-center/relations/belongs/Sy2Sh", "系统所在竖井"],
@@ -44,10 +44,15 @@ const content = [
         path: "/dev/data-center/relations/",
         children: [
             ["/dev/data-center/relations/other/calc_area_v3", "计算业务空间面积"],
-            ["/dev/data-center/relations/other/calc_vertically_overlap", "计算业务空间是否在垂直方向重叠"],
             ["/dev/data-center/relations/other/other_ispace_floor_overlap", "计算元空间轮廓是否与楼层轮廓重叠"],
             ["/dev/data-center/relations/other/rel_affected_space", "计算受影响的业务空间"],
             ["/dev/data-center/relations/other/rel_str_similar", "计算字符串相似度"],
+            ["/dev/data-center/relations/other/is_vertically_overlap", "业务空间垂直方向的交通关系"],
+            ["/dev/data-center/relations/other/is_point_in_polygon_v1", "判断点是否在楼层轮廓内"],
+            ["/dev/data-center/relations/other/is_point_in_polygon_v2", "判断点是否在元空间轮廓内"],
+            ["/dev/data-center/relations/other/is_point_in_polygon_v3", "判断点是否在业务空间轮廓内"],
+            ["/dev/data-center/relations/other/rel_cilin_str_similar", "词林相似度算法"],
+            ["/dev/data-center/relations/other/sim", "词林相似度算法详细文档"],
         ]
     },
     {
@@ -59,6 +64,13 @@ const content = [
         ]
     },
     {
+        title: "现存问题",
+        path: "/dev/data-center/relations/",
+        children: [
+            ["/dev/data-center/relations/problems/problems", "现存问题"]
+        ]
+    },
+    {
         title: "代码说明",
         path: "/dev/data-center/code/",
         children: []

+ 17 - 11
docs/dev/data-center/relations/belongs/Bd2Sp.md

@@ -1,25 +1,28 @@
-建筑下的业务空间
+# 建筑下的业务空间
 ## 前置条件
-有所属楼层的业务空间(所有业务空间表都需要处理)
+    1. 业务空间必须要有所属的楼层
 ```
 FROM zone_* WHERE project_id='Pj4201050001' AND floor_id is not null
 ```
-## 处理方式
+## 处理逻辑
 
-从绑定的楼层里取建筑ID,
-将建筑ID填入设备ID(建筑ID为空,则设备的建筑ID也为空)。
+    1. 从业务空间绑定的楼层信息里取到楼层所属的建筑ID,
+    2. 取到的建筑ID即是业务空间的所属建筑 (建筑ID为空,则的建筑ID也为空).
 
 ## 实现方式
 SQL
 ```
-update zone_air_conditioning zone set zone.building_id = floor.building_id from floor where zone.floor_id = floor.id and zone.project_id = 'Pj4201050001' and zone.floor_id is not null
+update zone_space_base zone set zone.building_id = floor.building_id from floor where zone.floor_id = floor.id and zone.project_id = 'Pj4201050001' and zone.floor_id is not null
 ```
 
 # 函数
+
+<details>
+<summary>源码</summary>
+
 ```
-create or replace function public.rel_bd2sp(tables text, project_id character varying) returns boolean
-as
-$$
+CREATE OR REPLACE FUNCTION "public"."rel_bd2sp"("tables" text, "project_id" varchar)
+  RETURNS "pg_catalog"."bool" AS $BODY$
 try:
     list = tables.split(',')
     # 将下面对数据库的操作作为一个事务, 出异常则自动rollback
@@ -33,10 +36,13 @@ except Exception as e:
     return False
 else:
     return True
-$$
-LANGUAGE 'plpython3u' VOLATILE;
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
 ```
 
+</details>
+
 ## 输入
     1. 参与计算的表的全名称, 带schema名, 以英文逗号隔开
     2. 项目id

+ 10 - 5
docs/dev/data-center/relations/belongs/Eq2Bd.md

@@ -1,16 +1,16 @@
-设备所在建筑
+# 设备所在建筑
 ## 前置条件
-设备已经绑定楼层
+    1. 设备已经绑定楼层
 ```
 FROM equipment WHERE project_id='Pj4201050001' AND floor_id is not null
 ```
 
 ## 依赖函数
     Eq2Fl
-## 处理方式
+## 处理逻辑
 
-从绑定的楼层里取建筑ID,
-将建筑ID填入设备ID(建筑ID为空,则设备的建筑ID也为空)。
+    1. 设备绑定的楼层里取楼层所属的建筑ID,
+    2. 将取到的建筑ID填入设备的所属建筑中(建筑ID为空,则设备的所属建筑ID也为空)。
 
 ## 实现方式
 SQL
@@ -20,6 +20,9 @@ UPDATE equipment SET building_id = (SELECT building_id FROM "floor" WHERE id = e
 
 # 函数
 
+<details>
+<summary>源码</summary>
+
 ```plpython
 create or replace function public.rel_eq2bd(project_id character varying) returns boolean
 as
@@ -38,6 +41,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ```
 
+</details>
+
 
 ## 入参
     1. 项目id

+ 16 - 9
docs/dev/data-center/relations/belongs/Eq2Fl.md

@@ -1,20 +1,26 @@
 设备所在楼层
 ## 前置条件
-    1. 设备有ModelId信息点
-    2. 楼层有ModelId信息点
-    3. 楼层的ModelId信息点等于设备的ModelId所属模型楼层的信息点
-    4. 设备没有所在楼层关系
-    5. 设备有Location(非必要)
-    6. 楼层有Outline(非必要)
+    1. 设备有ModelId信息点  (模型web服务的模型id)
+    2. 楼层有ModelId信息点  (模型web服务的楼层id)
+    3. 设备没有所在楼层关系
+    4. 设备有Location(非必要)
+    5. 楼层有Outline(非必要)
     
 
-## 处理方式
-    1. 如果楼层有Outline, 设备有Location, 做点(Location)在多边形(Outline)内的判断, 在多边形内则认为有关系
-    2. 如果不满足条件1, 则判断ModelId信息点的值, 相等则认为有关系
+## 处理逻辑
+    1. 如果楼层有Outline, 设备有Location, 做点(Location)在多边形(Outline)内的判断, 点在多边形内则认为有关系
+    2. 如果不满足条件1, 即楼层没有Outline, 设备没有Location, 则判断它们ModelId信息点的值, 相等则认为有关系   
+        (此处的相等表示设备上的ModelId信息点在关系上从属于楼层上的ModelId信息点, 即模型web服务中的模型id属于楼层id)
+
+## 技术细节
+    1. 做点在多边形内的判断, 使用到了python的 shapely 库 中的 Path 类的contains_points 方法
 
 # 函数
 
 ## 代码
+<details>
+<summary>源码</summary>
+
 ```
 -- 设备所在楼层
 CREATE OR REPLACE FUNCTION "public"."rel_eq2fl"("project_id" varchar)
@@ -101,6 +107,7 @@ $BODY$
 
 select public.rel_eq2fl('Pj1101010015');
 ```
+</details>
 
 ## 输入
     1. 项目id

+ 13 - 6
docs/dev/data-center/relations/belongs/Eq2Sh.md

@@ -1,14 +1,19 @@
-设备所在竖井关系计算
+# 设备所在竖井关系计算
 ## 前置条件
-    1. 首先需要有设备所在业务空间关系
-    2. 需要有竖井包含业务空间关系
+    1. 设备需要有所在业务空间关系
+    2. 竖井需要有包含业务空间关系
     
 ## 依赖函数
     Eq2Sp
-## 计算过程
-    1. 通过 竖井--> 业务空间 --> 设备的间接关系, 堆出竖井和设备的关系
-    2. 结果保存到r_eq_in_sh表中
+    
+## 处理逻辑
+    1. 通过 竖井 --> 业务空间 --> 设备 的间接所属关系, 推出竖井和设备的关系
+    
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 设备所在竖井
 create or replace function public.rel_eq2sh(project_id character varying) returns boolean
@@ -43,6 +48,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ```
 
+</details>
+
 ## 入参
     1. 项目id
     

+ 27 - 18
docs/dev/data-center/relations/belongs/Eq2Sp.md

@@ -1,21 +1,24 @@
-设备所在业务空间
+# 设备所在业务空间
 ## 前置条件
-    1. 业务空间有所属楼层
-    2. 设备有所属楼层
-    3. 业务空间有轮廓数据(outline)
-    4. 设备有坐标信息(bimLocation)
+    1. 业务空间有所属楼层关系
+    2. 设备有所属楼层关系
+    3. 业务空间有轮廓数据(outline信息点)
+    4. 设备有坐标信息(bimLocation信息点)
 ## 依赖函数
-    Eq2Fl
-## 处理方式
-    将在同一楼层内的设备和业务空间取出, 判断设备的bim_location是否在业务空间的outline内, 
-    如果在, 则添加进对应的关系表内, 控制sign = 2
+    Eq2Fl, Sp2Fl
+## 处理逻辑
+    1. 取出项目内的所有业务空间和设备, 将在同一楼层内的设备和业务空间分成一组
+    2. 在一组内, 判断设备的bim_location是否在业务空间的outline内, 即做点在多边形内的判断, 点在多边形内则认为有关系
 
 # 函数
 ## 代码
+
+<details>
+<summary>源码</summary>
+
 ```
-create or replace function public.rel_eq2sp(tables text, out_tables text, project_id character varying, sign1 integer, sign2 integer) returns boolean
-as
-$$
+CREATE OR REPLACE FUNCTION "public"."rel_eq2sp"("tables" text, "out_tables" text, "project_id" varchar, "sign1" int4, "sign2" int4)
+  RETURNS "pg_catalog"."bool" AS $BODY$
 from matplotlib.path import Path
 import json
 
@@ -80,8 +83,9 @@ with plpy.subtransaction():
             if len(equips) == 0:
                 continue
             # 获取楼层下的业务空间
-            space_plan = plpy.prepare("select id, outline from {0} as sp where project_id = $1 and outline is not null and floor_id = $2".format(in_table_name), ["text", "text"])
-            spaces = space_plan.execute([project_id, floor_id])
+
+            space_plan = plpy.prepare("select sp.id, sp.outline, sp.object_type from public.r_sp_in_fl rel inner join {0} sp on rel.space_id = sp.id where outline is not null and rel.floor_id = $1".format(in_table_name), ["text"])
+            spaces = space_plan.execute([floor_id])
             if len(spaces) == 0:
                 continue
             # 判断设备的bim_location是否在业务空间的outline内
@@ -91,18 +95,23 @@ with plpy.subtransaction():
                         location = equip['bim_location'].split(',')
                         if is_point_in_polygon(location[0], location[1], space['outline']):
                             # 设备在业务空间内, 添加关系
-                            insert_plan = plpy.prepare("insert into {0}(equip_id, space_id, project_id, sign) values($1, $2, $3, 2) ".format(out_table_name.strip()), ["text", "text", 'text'])
-                            insert_plan.execute([equip['id'], space['id'], project_id])
+                            insert_plan = plpy.prepare("insert into {0}(eq_id, sp_id, project_id, sign, type, zone_type) values($1, $2, $3, 2, 'eq2sp_in', $4)".format(out_table_name.strip()), ["text", "text", "text", "text"])
+                            insert_plan.execute([equip['id'], space['id'], project_id, space['object_type']])
                     except Exception as ex:
+                        plpy.warning(ex)
                         continue
 return True
-$$
-LANGUAGE 'plpython3u' VOLATILE;
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
 
 
 例子:
 select public.rel_eq2sp('zone_general,zone_lighting', 'r_eq_in_sp_zone_general,r_eq_in_sp_zone_lighting', 'Pj1101010015', 2, 2);
 ```
+</details>
+
+
 ## 输入
     1. 参与计算的业务空间表的全名称, 带schema名, 以英文逗号隔开
     2. 关系计算结果存储的表, 跟第一个参数一一对应, 带schema名, 以英文逗号隔开

+ 11 - 7
docs/dev/data-center/relations/belongs/Fl2Fl.md

@@ -1,17 +1,19 @@
-楼层贯通关系
+# 楼层贯通关系
 ## 前置条件
-两个楼层的model_id信息点需要一致并不能为空, 则认为两个楼层是贯通关系
+
+    1. 两个楼层的model_id信息点需要一致且不能为空, 则认为两个楼层是贯通关系
 ```
 FROM floor WHERE project_id='Pj4201050001' AND model_id is not null
 ```
-## 处理方式
-    1. 先删除项目下所有的贯通关系(只删除sign为2的关系)
-    2. 多表连接更新:
-        1. 根据model_id信息点多表连接
-        2. 将结果插入到r_fl_through_fl表中, sign置为2
+## 处理逻辑
+    1. 拿到所有楼层
+    2. 如果两个楼层的ModelId信息点相同, 则认为两楼层有贯通关系
 
 # 函数
 
+<details>
+<summary>源码</summary>
+
 ```
 create or replace function public.rel_fl2fl(project_id character varying, sign1 integer, sign2 integer) returns boolean
 as
@@ -40,6 +42,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ```
 
+</details>
+
 ## 输入
     1. 项目id
     2. 表示r_fl_through_fl表中要被删除的sign值

+ 9 - 3
docs/dev/data-center/relations/belongs/Pe2Bd.md

@@ -1,13 +1,17 @@
-资产所在建筑
+# 资产所在建筑
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在建筑
 ## 依赖函数
     Eq2Bd
-## 计算流程
-    根据 资产 --> 设备/部件 --> 建筑 的间接关系, 来获取资产和建筑的所在关系
+## 处理逻辑
+    根据 资产 --> 设备/部件 --> 建筑 的间接从属关系, 来获取资产和建筑的所在关系
     
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 资产属于建筑体
 create or replace function public.rel_pe2bd(project_id character varying) returns boolean
@@ -30,6 +34,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_pe2bd('Pj1101010015');
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 8 - 2
docs/dev/data-center/relations/belongs/Pe2Fl.md

@@ -1,13 +1,17 @@
-资产所在楼层
+# 资产所在楼层
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在楼层
 ## 依赖函数
     Eq2Fl
-## 计算流程
+## 处理逻辑
     根据 资产 --> 设备/部件 --> 楼层 的间接关系, 来获取资产所在建筑的关系
     
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 资产属于楼层
 create or replace function public.rel_pe2fl(project_id character varying) returns boolean
@@ -29,6 +33,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_pe2fl('Pj1101010015');
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 7 - 1
docs/dev/data-center/relations/belongs/Pe2Sh.md

@@ -1,4 +1,4 @@
-资产所在竖井
+# 资产所在竖井
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在竖井关系
@@ -8,6 +8,10 @@
     根据 资产 --> 设备/部件 --> 竖井 的间接关系, 来获取资产所在竖井的关系
     
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 资产所在竖井
 create or replace function public.rel_pe2sh(project_id character varying) returns boolean
@@ -32,6 +36,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_pe2sh('Pj1101010015');
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 7 - 1
docs/dev/data-center/relations/belongs/Pe2Sp.md

@@ -1,4 +1,4 @@
-资产所在业务空间
+# 资产所在业务空间
 ## 前置条件
     1. 资产有绑定的设备或部件
     2. 绑定的设备或部件有所在业务空间关系
@@ -8,6 +8,10 @@
     根据 资产 --> 设备/部件 --> 业务空间 的间接关系, 来获取资产所在业务空间的关系
     
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 资产所在业务空间
 create or replace function public.rel_pe2sp(project_id character varying) returns boolean
@@ -37,6 +41,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_pe2sp('Pj1101010015');
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 8 - 3
docs/dev/data-center/relations/belongs/Sh2Bd.md

@@ -1,14 +1,17 @@
-竖井关联的建筑
+# 竖井关联的建筑
 
 # 计算流程
     
     根据竖井关联的空间关系来推导
     
-# 处理流程
-    1. 竖井包含有业务空间, 并且业务空间有所属建筑
+## 处理逻辑
+    1. 根据 竖井 --> 业务空间 --> 建筑 的间接关系, 来获取资产所在业务空间的关系
     
 # 函数
 
+<details>
+<summary>源码</summary>
+
 ```
 
 CREATE OR REPLACE FUNCTION "public"."rel_sh2bd"("project_id" varchar)
@@ -41,6 +44,8 @@ $BODY$
 select public.rel_sh2bd('Pj1102290002')
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 9 - 2
docs/dev/data-center/relations/belongs/Sh2Sh.md

@@ -1,9 +1,14 @@
-竖井贯通关系
+# 竖井贯通关系
 ## 前置条件
     1. 竖井包含的有元空间(竖井在r_sh_contain_si表中有数据)
-## 处理流程
+## 处理逻辑
     1. 竖井包含有相同的元空间, 则认为两竖井贯通
+    (竖井包含元空间的数据是前端做划分)
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 竖井贯通关系
 create or replace function public.rel_sh2sh(project_id character varying) returns boolean
@@ -51,6 +56,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_sh2sh('Pj1102290002')
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 11 - 5
docs/dev/data-center/relations/belongs/Sp2Fl.md

@@ -1,16 +1,21 @@
-在多个楼层划分一个模型时, 根据已有的业务空间所属楼层数据重新计算业务空间所属楼层
+# 业务空间所属楼层 (关系由前端生成, 此算法是在多个楼层划分一个模型时, 根据已有的业务空间所属楼层数据重新计算业务空间所属楼层)
 ## 前置条件
     1. 楼层有外轮廓
     2. 业务空间有外轮廓
     3. 有2个或2个以上的楼层的ModelId相同(意思是一个模型划分成了多个楼层)
     4. 这些ModelId相同的楼层下有所属的业务空间关系
     5. 业务空间所属楼层表内维护的关系是正确的
-## 处理流程
-    1. 查出项目内所有ModelId相同的楼层(如果没有则返回)
-    2. 按照ModelId将楼层分组, 相同ModelId的楼层为一组, 每组内按照以下规则计算
-    3. 获取组内所有楼层下的业务空间, 将查出的业务空间的轮廓与楼层的轮廓比对是否有重叠部分(所有业务空间 X 所有楼层次对比), 如果有重叠则认为该业务空间和该楼层有关系
+    
+## 处理逻辑
+    1. 查出项目内所有ModelId相同的楼层(如果没有则结束)
+    2. 按照ModelId信息点将楼层分组, 相同ModelId的楼层为一组, 每组内按照以下规则计算
+    3. 获取组内所有楼层下的业务空间, 将查出的业务空间的轮廓与组内楼层的轮廓比对是否有重叠部分(所有业务空间 X 组内楼层个数次对比), 如果有重叠则认为该业务空间和该楼层有关系
     4. 在业务空间所属楼层表内删除该组楼层下的所有业务空间关系, 并插入新计算出的业务空间所属楼层的关系
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 
 CREATE OR REPLACE FUNCTION "public"."rel_sp2fl"("project_id" varchar)
@@ -171,6 +176,7 @@ $BODY$
 
 select public.rel_sp2fl('Pj1101050001')
 ```
+</details>
 
 ## 入参
     1. 项目id

+ 12 - 6
docs/dev/data-center/relations/belongs/Sp2Sp.md

@@ -1,17 +1,21 @@
-业务空间邻接关系
+# 业务空间邻接关系
 ## 前置条件
     1. 业务空间有所在楼层
     2. 业务空间有外轮廓
-## 处理流程
+## 处理逻辑
     1. 查出所有有所在楼层, 并且外轮廓不是null的业务空间
-    2. 根据所在楼层, 业务空间分区来将业务空间分组
-    3. 计算每个分组内的业务空间的相邻关系
+    2. 根据所在楼层, 业务空间分区类型来将业务空间分组
+    3. 分别计算每个分组内的业务空间的相邻关系
     计算相邻算法:
-    1. 首先判断围成业务空间的线段, 两两空间之间是否有近似平行的线段(线段偏转误差小于1度)
+    1. 首先判断围成业务空间轮廓的线段, 两两业务空间之间是否有近似平行的线段(线段平行偏转误差小于1度算作近似平行)
         1). 近似平行判断: 首先获取两个线段的斜率, 再计算斜率的反正切(即与x轴的角度, 不过是以pi为单位), 再判断两个角度差的绝对值是否小于1度
     2. 如果有近似平行的线段, 判断是否相互有投影在线段上, 有投影在线段上, 则认为是两平行线段有重合部分, 业务空间有相邻的可能性
-    3. 判断互相有投影点在对方线段上之后, 判断投影线的长度, 是否小于250mm(墙的最大厚度), 如果小于250mm则认为两空间相邻
+    3. 判断互相有投影点在对方线段上之后, 判断投影线的长度, 是否小于250mm(墙的最大厚度), 如果小于250mm则认为两空间相邻
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 create or replace function public.rel_sp2sp1(project_id character varying) returns boolean
 as
@@ -42,6 +46,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.rel_sp2sp1('Pj1101050001')
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 35 - 6
docs/dev/data-center/relations/belongs/Sp2Sp2.md

@@ -1,10 +1,10 @@
-业务空间邻接关系
+# 业务空间邻接关系
 ## 前置条件
     1. 业务空间有所在楼层
     2. 业务空间有外轮廓
-## 处理流程
-    1. 查出所有有所在楼层, 并且外轮廓不是null的业务空间
-    2. 根据所在楼层, 业务空间分区类型来将业务空间分组
+## 处理逻辑
+    1. 查出所有有所在楼层关系, 并且外轮廓不是null的业务空间
+    2. 根据所在楼层, 业务空间分区类型来将业务空间分为不同的 (例如 : A 楼层下的默认业务空间是一组, A楼层下的空调分区是另外一组)
     3. 计算每个分组内的业务空间的相邻关系
     计算相邻算法 (如下图):
     1. 在一个分组内, 遍历每个业务空间上组成外轮廓的每条线段, 根据线段的长度, 是否超过delta_distance来区分成两种情况判断
@@ -12,12 +12,39 @@
         在P5点处作AB线段的垂线线段, 上下两边长度均为door_length长, 找到点P4和P6. 同理可以找到点P7和P9. 
         2). 如果线段长度小于或等于delta_distance, 假设线段AE长度小于delta_distance, 则在线段中间点P2处作垂直于AE的垂线线段, 
         上下两边长度均为door_length长, 找到点P1和P3.
-    2. 将上面找到的点, 依次与其他业务空间外轮廓做一次点是否在多边形内的判断, 如果在, 则认为该多边形与图中多边形相邻
+    2. 将上面找到的点, 依次与组内其他业务空间外轮廓做一次点是否在多边形内的判断, 如果在, 则认为该多边形与图中多边形相邻
     
    
-  ![Image text](img/sp2sp2-1.PNG)
+![image](./img/sp2sp2-1.png)
+
 
 ## 函数
+
+###  业务空间轮廓结构
+```
+[
+    [
+        [
+            {点坐标},
+            {点坐标}...
+        ], // 子轮廓的外轮廓
+        [
+            {点坐标},
+            {点坐标}...
+        ], // 子轮廓的第n个需要被排除的轮廓
+    ], // 子轮廓
+    [
+        [
+            {点坐标},
+            {点坐标}...
+        ]
+    ],
+]
+```
+
+<details>
+<summary>源码</summary>
+
 ```
 create function rel_sp2sp_v2(project_id character varying) returns boolean
     language plpython3u
@@ -300,6 +327,8 @@ alter function rel_sp2sp_v2(varchar) owner to postgres;
 select public.rel_sp2sp_v2('Pj1101050001')
 ```
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 0 - 34
docs/dev/data-center/relations/belongs/Sp2Sp_new.md

@@ -1,34 +0,0 @@
-计算业务空间邻接关系
-# 函数依赖于
-    sp2fl
-# 业务空间轮廓结构
-```
-[
-    [
-        [
-            {点坐标},
-            {点坐标}...
-        ], // 子轮廓的外轮廓
-        [
-            {点坐标},
-            {点坐标}...
-        ], // 子轮廓的排除轮廓n
-    ], // 子轮廓
-    [
-        [
-            {点坐标},
-            {点坐标}...
-        ]
-    ],
-]
-```
-# 计算细节
-## 参与计算的业务空间
-    1. 找到项目下所有的楼层
-    2. 按照楼层, 分别找出每个楼层下的业务空间, 将一个楼层下的业务空间分组, 在一个组内计算业务空间的相邻关系
-## 在每个子轮廓的外轮廓的相邻两个顶点的线段上做"开门"操作
-    
-    1. 在线段长度大于等于一个门宽度的时候, 虚拟的在这个线段的两端分别各安装一扇门, 在门打开的过程中(两边都能打开), 扫过的面积如果跟其他空间(比如空间A)的面积有重叠时, 
-    则认为这个空间与空间A相邻, 依次找出所有与该空间相邻的空间.
-    2. 在线段长度不超过一个门的宽度时, 将继续寻找下一个点, 直到长度大于等于一个门的宽度时, 执行1
-    将此过程应用到所有空间上, 找出所有业务空间的相邻关系

+ 9 - 3
docs/dev/data-center/relations/belongs/Sy2Bd.md

@@ -1,14 +1,18 @@
-系统所在建筑
+# 系统所在建筑
 ## 前置条件
     1. 系统下有设备
     2. 系统下的设备有所属建筑的关系
 ## 依赖函数
     Eq2Bd
-## 计算流程
+## 处理逻辑
     1. 通过 系统 --> 设备 --> 建筑 的间接关系, 获取系统所在建筑的关系
-    2. 结果存储在 r_sy_in_bd 表中
+    2. 结果存储在 r_sy_in_bd 表中 (先删除以前的自动计算结果)
     
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ~~~
 -- 系统所在建筑
 CREATE OR REPLACE FUNCTION "public"."rel_sy2bd"("project_id" varchar)
@@ -45,6 +49,8 @@ $BODY$
   COST 100
 ~~~
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 9 - 3
docs/dev/data-center/relations/belongs/Sy2Fl.md

@@ -1,13 +1,17 @@
-系统所在楼层
+# 系统所在楼层
 ## 前置条件
     1. 系统下有设备
     2. 系统下的设备有所属楼层关系
 ## 依赖函数
     Eq2Fl
-## 计算流程
+## 处理逻辑
     1. 通过 系统 --> 设备 --> 楼层 的间接关系, 获取系统所在楼层的关系
-    2. 计算关系存储在表 r_sy_in_fl 中
+    2. 计算关系存储在表 r_sy_in_fl 中 (先删除以前的自动计算结果)
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ~~~
 -- 系统所在楼层
 create or replace function public.rel_sy2fl(project_id character varying) returns boolean
@@ -42,6 +46,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ~~~
 
+</details>
+
 ## 入参
     1. 项目id
 ## 例子

+ 9 - 3
docs/dev/data-center/relations/belongs/Sy2Sh.md

@@ -1,13 +1,17 @@
-系统所在竖井
+# 系统所在竖井
 ## 前置条件
     1. 系统下有设备
     2. 系统下的设备有所在竖井关系
 ## 依赖函数
     Eq2Sh
-## 计算流程
+## 处理逻辑
     1. 根据 系统 --> 设备 --> 竖井 来间接获取系统所属竖井关系
-    2. 计算后的关系存储在表 r_sy_in_sh
+    2. 计算后的关系存储在表 r_sy_in_sh (先删除以前的自动计算结果)
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 系统所在竖井
 create or replace function public.rel_sy2sh(project_id character varying) returns boolean
@@ -41,6 +45,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ```
 
+</details>
+
 ## 输入
     1. 项目id
 

+ 8 - 2
docs/dev/data-center/relations/belongs/Sy2Sp.md

@@ -4,10 +4,14 @@
     2. 系统下的设备有所在业务空间关系
 ## 依赖函数
     Eq2Sp
-## 计算流程
+## 处理逻辑
     1. 根据 系统 --> 设备 --> 业务空间 的间接关系, 获取系统和业务空间的关系
-    2. 计算结果存储在r_sy_in_sp_*
+    2. 计算结果存储在r_sy_in_sp中 (先删除以前的自动计算结果)
 ## 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 -- 系统所在楼层
 create or replace function public.rel_sy2sp(project_id character varying) returns boolean
@@ -55,6 +59,8 @@ $BODY$
   COST 100
 ```
 
+</details>
+
 ## 输入
     1. 项目id
 

+ 9 - 3
docs/dev/data-center/relations/belongs/f_rel_calc.md

@@ -1,4 +1,4 @@
-管理关系计算函数依赖和函数输入类型
+# 管理关系计算函数依赖和函数输入类型
 
 # 说明
     classify 该变量是根据函数的输入将函数分类
@@ -6,12 +6,16 @@
 
 # 函数
 ## 代码
+
+<details>
+<summary>源码</summary>
+
 ```
 CREATE OR REPLACE FUNCTION "public"."f_rel_calc"("func" text, "project_id" varchar, "tables" text, "out_tables" text, "sign1" int4, "sign2" int4)
   RETURNS "pg_catalog"."int4" AS $BODY$
 # 根据函数输入类型分类
 classify = {"eq2bd":1, "eq2fl":1, "sp2fl":1, "eq2sh":1, "pe2bd":1, "pe2fl":1, "pe2sh":1, "pe2sp":1, "sh2sh":1, "sy2bd":1,
-    "sy2fl":1, "sy2sh":1, "sy2sp":1, "bd2sp":2, "eq2sp":3, "fl2fl":4}
+    "sy2fl":1, "sy2sh":1, "sy2sp":1, "sh2bd":1, "bd2sp":2, "eq2sp":3, "fl2fl":4}
 dependency = {"eq2bd":["eq2fl"], "eq2sh":["eq2sp"], "eq2sp":["eq2fl", "sp2fl"], "pe2bd":["eq2bd"], "pe2fl":["eq2fl"], "pe2sh":["eq2sh"],
     "pe2sp":["eq2sp"], "sy2bd":["eq2bd"], "sy2fl":["eq2fl"], "sy2sh":["eq2sh"], "sy2sp":["eq2sp"]}
 def get_type_by_func_name(func_name):
@@ -76,10 +80,12 @@ $BODY$
   LANGUAGE plpython3u VOLATILE
   COST 100
 
-
 例子:
 select public.f_rel_calc('rel_eq2sh', 'Pj*******', 'zone_space_base','relationship.r_eq2sp', 2, 2)
 ```
+
+</details>
+
 ## 输入
     1. 想要计算的函数名
     2. 项目id

BIN
docs/dev/data-center/relations/belongs/img/sp2sp2-1.png


+ 10 - 4
docs/dev/data-center/relations/other/calc_area_v3.md

@@ -1,17 +1,21 @@
 计算业务空间的面积
 ## 前置条件
 
-
+    业务空间有轮廓数据
 
-## 处理方式
+## 处理逻辑
 
-根据业务空间轮廓的格式, 以此计算内部每个小轮廓的面积, 加和在一起为最终结果
-小轮廓面积计算: 计算首个子轮廓面积, 并减去随后所有子轮廓的面积. 结果为小轮廓面积
+    根据业务空间轮廓的格式, 以此计算内部每个小轮廓的面积, 加和在一起为最终结果
+    小轮廓面积计算: 计算首个子轮廓面积, 并减去随后所有子轮廓的面积. 结果为小轮廓面积
 
 ## 实现方式
 
 
 # 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 CREATE OR REPLACE FUNCTION "public"."calc_area_v3"("json_poly" jsonb)
   RETURNS "pg_catalog"."float8" AS $BODY$
@@ -66,6 +70,8 @@ $BODY$
   COST 100
 ```
 
+</details>
+
 ## 输入
     1. 业务空间的轮廓
 

BIN
docs/dev/data-center/relations/other/img/rel_cilin-1.png


+ 88 - 0
docs/dev/data-center/relations/other/is_point_in_polygon_v1.md

@@ -0,0 +1,88 @@
+# 判断一个点是否在楼层的轮廓里
+## 前置条件
+    
+    楼层必须有轮廓, 且合法
+    
+## 处理逻辑
+
+    1. 楼层外轮廓数据只有一个由点组成的数组围成, 因此直接判断指定的点是否在点数组围成的多边形内即可
+
+## 楼层轮廓格式示例
+```
+
+[
+    {点坐标的XYZ信息},
+    {点坐标的XYZ信息}...
+]
+```
+
+
+# 函数
+## 版本1
+
+<details>
+<summary>输入为浮点型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v1"("x" float8, "y" float8, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+try:
+    poly = []
+    polygon = json.loads(json_poly)
+    l = len(polygon)
+    points = (x, y)
+    for i in range(l):
+        pair = polygon[i]
+        poly.append((pair["X"], pair["Y"]))
+
+    p = Path(poly)
+except Exception as e:
+    return False
+else:
+    return p.contains_points([points], None, -0.0001)
+
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 版本2
+<details>
+<summary>输入为字符串类型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v1_str"("x" varchar, "y" varchar, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+try:
+    poly = []
+    polygon = json.loads(json_poly)
+    l = len(polygon)
+    points = (float(x), float(y))
+    for i in range(l):
+        pair = polygon[i]
+        poly.append((pair["X"], pair["Y"]))
+
+    p = Path(poly)
+except Exception as e:
+    return False
+else:
+    return p.contains_points([points], None, -0.0001)
+
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 输入
+    1. 点的x坐标
+    2. 点的y坐标
+    3. 楼层的轮廓
+## 返回结果
+    true    成功
+    false   失败

+ 126 - 0
docs/dev/data-center/relations/other/is_point_in_polygon_v2.md

@@ -0,0 +1,126 @@
+# 判断一个点是否在元空间的轮廓里
+## 前置条件
+    
+    元空间必须有轮廓, 且合法
+    
+## 处理逻辑
+
+    1. 元空间外轮廓数据格式由如下示例所示
+    2. 需要判断点在外轮廓内, 且不在任意1个被排除的轮廓内
+
+## 元空间轮廓示例
+```
+
+[
+    [
+        {点坐标的XYZ信息},
+        {点坐标的XYZ信息}...
+    ], // 轮廓的外层轮廓
+    [
+        {点坐标的XYZ信息},
+        {点坐标的XYZ信息}...
+    ], // 轮廓的第n个需要被排除的轮廓, 可能有若干个
+]
+
+```
+
+
+# 函数
+## 版本1
+
+<details>
+<summary>输入为浮点型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v2"("x" float8, "y" float8, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+
+def is_in_meta_polygon(point, single_poly, radius):
+    poly_len = len(single_poly)
+    poly = []
+    for i in range(poly_len):
+        pair = single_poly[i]
+        poly.append((pair["X"], pair["Y"]))
+    p = Path(poly)
+    return p.contains_points([point], None, radius)
+
+try:
+    polygons = json.loads(json_poly)
+    total_len = len(polygons)
+    point_pair = (x, y)
+    if total_len == 0:
+        return False
+    for i in range(total_len):
+        polygon = polygons[i]
+        if(i == 0):
+            if not is_in_meta_polygon(point_pair, polygon, -0.001):
+                return False
+        else:
+            if is_in_meta_polygon(point_pair, polygon, 0.001):
+                return False
+    return True
+except Exception as e:
+    return False
+else:
+    return True
+
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 版本2
+<details>
+<summary>输入为字符串类型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v2_str"("x" varchar, "y" varchar, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+
+def is_in_meta_polygon(point, single_poly, radius):
+    poly_len = len(single_poly)
+    poly = []
+    for i in range(poly_len):
+        pair = single_poly[i]
+        poly.append((pair["X"], pair["Y"]))
+    p = Path(poly)
+    return p.contains_points([point], None, radius)
+
+try:
+    polygons = json.loads(json_poly)
+    total_len = len(polygons)
+    point_pair = (float(x), float(y))
+    if total_len == 0:
+        return False
+    for i in range(total_len):
+        polygon = polygons[i]
+        if(i == 0):
+            if not is_in_meta_polygon(point_pair, polygon, -0.001):
+                return False
+        else:
+            if is_in_meta_polygon(point_pair, polygon, 0.001):
+                return False
+    return True
+except Exception as e:
+    return False
+else:
+    return True
+
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 输入
+    1. 点的x坐标
+    2. 点的y坐标
+    3. 元空间的轮廓
+## 返回结果
+    true    成功
+    false   失败

+ 142 - 0
docs/dev/data-center/relations/other/is_point_in_polygon_v3.md

@@ -0,0 +1,142 @@
+# 判断一个点是否在楼层的轮廓里
+## 前置条件
+    
+    业务空间必须有轮廓, 且合法
+    
+## 处理逻辑
+
+    1. 业务空间外轮廓数据格式由如下示例所示, 由若干个元空间(子轮廓)的轮廓组成
+    2. 判断点在是否在某一个子轮廓内, 如果在, 则点在业务空间内(返回true)
+        1). 判断点在子轮廓内, 需要判断点在子轮廓的外轮廓内, 且不在任意1个子轮廓被排除的轮廓内
+
+##  业务空间轮廓结构示例
+```
+[
+    [
+        [
+            {点坐标的XYZ信息},
+            {点坐标的XYZ信息}...
+        ], // 子轮廓的外轮廓
+        [
+            {点坐标的XYZ信息},
+            {点坐标的XYZ信息}...
+        ], // 子轮廓的第n个需要被排除的轮廓, 可能有若干个
+    ], // 子轮廓
+    [
+        [
+            {点坐标的XYZ信息},
+            {点坐标的XYZ信息}...
+        ]
+    ],
+]
+```
+
+# 函数
+## 版本1
+
+<details>
+<summary>输入为浮点型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v3"("x" float8, "y" float8, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+
+def is_in_meta_polygon(point, single_poly, radius):
+    poly_len = len(single_poly)
+    poly = []
+    for i in range(poly_len):
+        pair = single_poly[i]
+        poly.append((pair["X"], pair["Y"]))
+    p = Path(poly)
+    return p.contains_points([point], None, radius)
+
+
+def is_in_polygon(point, polygons):
+    length = len(polygons)
+    if length == 0:
+        return False
+    for j in range(length):
+        polygon = polygons[j]
+        if j == 0:
+            if not is_in_meta_polygon(point, polygon, -0.001):
+                return False
+        else:
+            if is_in_meta_polygon(point, polygon, 0.001):
+                return False
+    return True
+
+try:
+    polygon_list = json.loads(json_poly)
+    total_len = len(polygon_list)
+    point_pair = (x, y)
+    for index in range(total_len):
+        if is_in_polygon(point_pair, polygon_list[index]):
+            return True
+    return False
+except Exception as e:
+    return False
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 版本2
+<details>
+<summary>输入为字符串类型</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."is_point_in_polygon_v3_str"("x" varchar, "y" varchar, "json_poly" jsonb)
+  RETURNS "pg_catalog"."bool" AS $BODY$
+from matplotlib.path import Path
+import json
+
+def is_in_meta_polygon(point, single_poly, radius):
+    poly_len = len(single_poly)
+    poly = []
+    for i in range(poly_len):
+        pair = single_poly[i]
+        poly.append((pair["X"], pair["Y"]))
+    p = Path(poly)
+    return p.contains_points([point], None, radius)
+
+
+def is_in_polygon(point, polygons):
+    length = len(polygons)
+    if length == 0:
+        return False
+    for j in range(length):
+        polygon = polygons[j]
+        if j == 0:
+            if not is_in_meta_polygon(point, polygon, -0.001):
+                return False
+        else:
+            if is_in_meta_polygon(point, polygon, 0.001):
+                return False
+    return True
+
+try:
+    polygon_list = json.loads(json_poly)
+    total_len = len(polygon_list)
+    point_pair = (float(x), float(y))
+    for index in range(total_len):
+        if is_in_polygon(point_pair, polygon_list[index]):
+            return True
+    return False
+except Exception as e:
+    return False
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 输入
+    1. 点的x坐标
+    2. 点的y坐标
+    3. 业务空间的轮廓
+## 返回结果
+    true    成功
+    false   失败

+ 35 - 14
docs/dev/data-center/relations/other/calc_vertically_overlap.md

@@ -1,21 +1,29 @@
-计算所有业务空间, 在竖直方向上的面积重叠关系
+# 计算各个建筑内不同楼层的业务空间在垂直方向的重叠关系 (业务空间的垂直交通关系?)
 ## 前置条件
-只有有轮廓的业务空间才能参与计算
-```
+    1. 楼层下有业务空间
+    2. 业务空间有轮廓
 
-```
-## 处理方式
+## 处理逻辑
+    1. 因为算法复杂度问题, 该算法分为两个版本, 区别为参与计算的业务空间的范围
+    版本一 (参与计算的业务空间 : 项目下全部的业务空间都参与计算):
+        1). 获取项目下所有有楼层关系, 并且有轮廓的业务空间
+        2). 将业务空间按照所属楼层, 业务空间类型分组
+        3). 以一群人两两握手的方式将两两楼层内的相同类型的业务空间做轮廓是否重叠判断
+        4). 如果有重叠, 则认为两业务空间有垂直方向的重叠关系
+        5). 删除上次自动计算的关系, 并插入新计算的关系
+    版本二 (参与计算的业务空间 : 指定业务空间类型下的若干个业务空间 与某一个建筑的内其他楼层的相同类型的业务空间):
+        1). 获取到指定类型的所有业务空间, 按照楼层分类
+        2). 如果某一层下有指定的业务空间, 则该楼层计算与其他楼层的垂直关系时, 那么该楼层只有指定的业务空间才参与计算轮廓重叠
+        3). 则计算结果一定是只与指定的业务空间有关系
+        4). 删除与指定的业务空间相关的关系, 并插入新计算的关系
 
-获取所有建筑, for循环获取每个建筑下所有的业务空间, 按楼层分类
-每个楼层的每个业务空间分别和别的楼层的每个业务空间判断is_vertically_overlap
-将结果是true的两个业务空间保存起来
-删除旧业务空间的垂直交通关系(自动计算的), 添加新关系
 
-## 实现方式
+# 函数
+## 版本1
 
+<details>
+<summary>版本1 : 计算一个项目内, 所有业务空间类型的业务空间垂直交通关系</summary>
 
-# 函数
-## 版本1 (计算一个项目内, 所有业务空间类型的业务空间垂直交通关系)
 ```
 CREATE OR REPLACE FUNCTION "public"."is_vertically_overlap"("project_id" varchar)
   RETURNS "pg_catalog"."bool" AS $BODY$
@@ -159,9 +167,15 @@ $BODY$
   LANGUAGE plpython3u VOLATILE
   COST 100
 ```
+</details>
+
+
 
 ## 版本2
-    计算一个建筑内, 同一业务空间类型下的某几个业务空间的垂直交通关系
+<details>
+<summary>版本2 : 计算一个建筑内, 同一业务空间类型下的某几个业务空间的垂直交通关系</summary>
+
+    
 ```
 CREATE OR REPLACE FUNCTION "public"."is_vertically_overlap"("project_id" varchar, "_building_id" varchar, "zone_type" varchar, "space_ids" _varchar)
   RETURNS "pg_catalog"."bool" AS $BODY$
@@ -325,9 +339,16 @@ $BODY$
   LANGUAGE plpython3u VOLATILE
   COST 100
 ```
+</details>
 
 ## 输入
-    1. 项目id
+    1. 版本一
+        1). 项目id
+    2. 版本二
+        1). 项目id
+        2). 建筑id
+        3). 业务空间类型
+        4). 指定参与计算的业务空间id
 ## 返回结果
     true    成功
     false   失败

+ 7 - 1
docs/dev/data-center/relations/other/other_ispace_floor_overlap.md

@@ -3,11 +3,15 @@
     1. 元空间和楼层必须都有轮廓
     2. 轮廓必须符合规则
     
-# 处理方式
+# 处理逻辑
 
     将楼层的外轮廓与元空间的最外层轮廓做是否重叠检查操作
 
 # 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 CREATE OR REPLACE FUNCTION "public"."other_ispace_floor_overlap"("ispace_outline" jsonb, "floor_outline" jsonb)
   RETURNS "pg_catalog"."bool" AS $BODY$
@@ -46,6 +50,8 @@ $BODY$
 
 ```
 
+</details>
+
 ## 输入
     1. 元空间轮廓
     2. 楼层轮廓

+ 6 - 6
docs/dev/data-center/relations/other/rel_affected_space.md

@@ -4,12 +4,10 @@
     2. 划分了业务空间
     3. 该模型上传时, 该楼层上必须已有模型
     4. 原模型有元空间信息
-```
-```
 
 ## 依赖函数
-## 处理方式
+## 处理逻辑
 
     1. 查询出所有绑定该revit模型楼层的数据中心楼层
         SELECT id FROM public.floor where model_id = 'revit模型楼层'
@@ -25,13 +23,13 @@
     4. 根据2, 3中改变的元空间来判断 1中获取的关系中哪些业务空间因元空间的改变而发生了改变
     5. 返回4中得到的业务空间
 
-## 实现方式
 
-```
-```
 
 # 函数
 
+<details>
+<summary>源码</summary>
+
 ```plpython
 CREATE OR REPLACE FUNCTION rel_affected_space(floor_id character varying) RETURNS boolean AS
 $$
@@ -97,6 +95,8 @@ $$
 LANGUAGE 'plpython3u' VOLATILE;
 ```
 
+</details>
+
 
 ## 入参
     1. web模型服务中的floor_id, 格式是uuid

+ 43 - 0
docs/dev/data-center/relations/other/rel_cilin_str_similar.md

@@ -0,0 +1,43 @@
+# 根据词林相似度算法匹配相似度最高的字符串
+## 前置条件
+    
+    输入合法即可
+    
+## 处理逻辑
+
+[文档](http://adm.sagacloud.cn:8080/doc/dev/data-center/relations/other/sim.html)
+[git地址 : http://git.sagacloud.cn/chenhaiyang/sim](http://git.sagacloud.cn/chenhaiyang/sim)
+
+
+# 函数
+
+<details>
+<summary>源码</summary>
+
+```
+CREATE OR REPLACE FUNCTION "public"."rel_cilin_str_similar"("word" varchar, "possibilities" _varchar, "num" int4)
+  RETURNS "pg_catalog"."text" AS $BODY$
+
+from sim.text_sim import most_similar_items
+
+try:
+    result = most_similar_items(word, possibilities, num)
+    return result
+except Exception as e:
+    plpy.warning(e)
+    return ""
+else:
+    plpy.warning(e)
+$BODY$
+  LANGUAGE plpython3u VOLATILE
+  COST 100
+```
+</details>
+
+## 输入
+    1. word : 需要匹配的字符串
+    2. possibilities : 被匹配的字符串
+    3. num : 指定返回匹配到的字符串中相似度最高的num个字符串
+## 返回结果
+    
+![rel_cilin_1](./img/rel_cilin-1.png)

+ 6 - 6
docs/dev/data-center/relations/other/rel_str_similar.md

@@ -1,4 +1,4 @@
-计算字符的相似度 (使用编辑距离)
+# 计算字符的相似度 (使用编辑距离)
 ## 前置条件
 ```
@@ -6,17 +6,16 @@
 
 ## 依赖函数
-## 处理方式
+## 处理逻辑
 
     根据编辑距离来计算相似度
 
-## 实现方式
-
-```
-```
 
 # 函数
 
+<details>
+<summary>源码</summary>
+
 ```plpython
 CREATE OR REPLACE FUNCTION "public"."rel_str_similar"("word" varchar, "possibilities" _varchar, "num" int4, "sim" float8)
   RETURNS "pg_catalog"."text" AS $BODY$
@@ -69,6 +68,7 @@ $BODY$
   COST 100
 ```
 
+</details>
 
 ## 入参
     1. "word" varchar                    需要匹配的字符串

+ 110 - 0
docs/dev/data-center/relations/other/sim.md

@@ -0,0 +1,110 @@
+# sim-dict
+
+## 简介 Introduction
+
+sim-dict 是一个计算文本相似度的模块,支持词语、短文本、长文本相似度计算;对中文字符提供包含语义的相似度计算,非中文字符只支持字符层面的相似度计算。
+
+## 快速上手 Getting Started
+
+```python
+>>> from sim.text_sim import get_similarity
+>>> get_similarity('环境算法实现', '温度控制策略')
+0.7166666666666667
+```
+
+## 入门 Basics
+
+### 环境准备 Prerequisite
+
+建议使用 [virtualenv](https://virtualenv.pypa.io/en/latest/) 创建虚拟环境作为开发和生产环境,virtualenv 是用来为应用创建一套“隔离”的 Python 运行环境的工具。
+
+首先,用 pip 安装 virtualenv
+
+```bash
+$ pip3 install virtualenv
+```
+
+假如我们要开发一个新的项目,需要一套独立的 Python 运行环境,可以这么做:
+
+第一步,创建目录:
+
+```bash
+~ mkdir myproject
+~ cd myproject
+```
+
+第二步,创建一个独立的 Python 运行环境,命名为 venv:
+
+```bash
+~/myproject virtualenv -p /usr/bin/python venv
+Running virtualenv with interpreter /usr/bin/python
+Already using interpreter /System/Library/Frameworks/Python.framework/Versions/2.7/Resources/Python.app/Contents/MacOS/Python
+New python executable in /Users/highing/code/python/test/venv/bin/python
+Installing setuptools, pip, wheel...
+done.
+```
+
+参数 p 用来指定创建环境使用的 Python 解释器的路径,比如我们要使用 Python 3.8 版本的虚拟环境,可以用版本为 3.8 的解释器路径来替
+代 -p 后边的参数,这样创建的环境也就是 Python 3.8 了
+
+命令 virtualenv 就可以创建一个独立的 Python 运行环境,新建的 Python 环境就被放到当前目录下的 venv 目录。我们可以通过 source 命令进入环境
+
+```bash
+~/myproject source venv/bin/activate
+(venv) ~/myproject
+```
+
+### 安装 Installation
+
+sim-dict 目前已经被打包放在公司的[私服仓库](http://dev.dp.sagacloud.cn:8082/#admin/repository/repositories)了,我们可以在创建好的虚拟环境安装它
+
+```bash
+(venv) ~/myproject pip install short-text-sim -i http://dev.dp.sagacloud.cn:8082/repository/saga-pypi-group/simple --trusted-host dev.dp.sagacloud.cn
+```
+
+上述命令可以加上 --upgrade 参数完成更新操作。
+
+## 进阶篇 Advanced
+
+在 sim-dict 实现的文本相似度计算方法中,大概分为分词、词相似度计算、文本相似度计算三个步骤。
+
+### 关于词林
+
+[「同义词词林」](https://baike.baidu.com/item/%E5%90%8C%E4%B9%89%E8%AF%8D%E8%AF%8D%E6%9E%97)是梅家驹等人与 1983 年词林编撰完成的,后经哈工大更新扩展,sim-dict 是在扩展版基础上实现的。
+词林根据词语的含义、类型、词性将所收录的汉语词分为了 12 大类,从大到小一共五层,第五层成为原子词群,意为不可再分,每个原子词群都有一个五层结构的编码,比如 Aa01C02=。
+
+### 词相似度计算
+
+根据词林建立一个「词——编码」的哈希表,通过这样的哈希表,就可以查询词的编码。获取两个待计算相似度词的编码,对比两个编码,根据匹配程度计算相似度。编码具有五个层级,
+从大到小匹配得分分别为 3,3,2,1,1,总分为 10 分,匹配累计得分与总分的比值即为相似度。
+
+### 文本相似度计算
+
+ 将两个待计算相似度的文本进行分词操作,我们这里用的分词工具是[结巴分词](https://github.com/fxsjy/jieba)。根据分词结构计算词相似度,得到如下的词相似度矩阵
+ 分别获取该矩阵每行、每列的最大值的均值,计算这两个平均值的均值,即为这两个文本的相似度。
+
+ -   | 环境 | 算法 | 实现
+ ----| ----| --- | ---
+ 温度 | 0.4 | 0.3 | 0.2
+ 控制 | 0.1 | 0.3 | 0.4
+ 策略 | 0.4 | 0.6 | 0.2
+
+### 更新词林
+
+往词林是添加新词(词林未收录的词)没有明确统一的方法,主要基于个人对于词林对理解,下边是我们常用的思路。
+
+对于一个新词,尝试列举它的同义词、近义词,如果它的同/近义词在词林里,那么将该新词直接放在它的同/近义词所在的原子词群即可,这样通过词林计算二者相似度的时候即可得到最高的分数,
+与我们认为的二者是同义/近义是相符的。
+
+如果无法列举该词合适的同/近义词,或者该词的同/近义词未被词林收录,我们要尝试总结该词的类型、词性、词义,并根据词林分类的逻辑,将其放入合适的词群或者建立新的词群和与之对应的编码。
+比如“空调主机”要放在第一大类“物”里,第二大类“机具”里,第三类“机器 工具 泵”里……
+
+如果该词是多义的,对于每一个词义,按照上述逻辑分别执行添词操作即可。
+
+由于基于词林方法的性质,即通过人的理解将词分类,并以此为基础进行词、句相似度的计算,所以目前来说无法通过机器自动完成新词添加操作,这也是这种方法维护最为繁琐的地方。
+
+## 附录 Appendix
+
+[基于同义词词林的词语相似度计算方法](http://gb.oversea.cnki.net/KCMS/detail/detail.aspx?filename=CCYD201006010&dbcode=CJFD&dbname=CJFD2010)
+
+[Final_word_Similarity](https://github.com/yaleimeng/Final_word_Similarity)

+ 58 - 0
docs/dev/data-center/relations/problems/problems.md

@@ -0,0 +1,58 @@
+### 下面列出所有问题, 每个问题需要标注问题解决人, 问题类型
+
+## 模型web服务历史和现存问题
+### 已解决
+#### 一般问题
+    1. 回退模型版本时出现异常Bug(邢景灏)
+    2. 连接件的关系不能支持1对多(邢景灏)
+    3. 模型文件上传不显示正在上传楼层的进度(邢景灏, 张宇)
+        解决: 由传统上传方式改为分片上传文件
+    4. 轴网检查, 标高检查结果异常(邢景灏)
+    5. 模型删除的通知缺失(邢景灏)
+    6. 模型导出之后没有元空间数据(李浩然)
+    7. 模型上传一半失败的情况下不能替换模型(邢景灏, 张宇)
+    8. 模型版本在2以后不再增长问题(邢景灏)
+        
+#### 性能问题
+    1. 通过接口同步数据到数据中心在数据量较大时容易失败(邢景灏)
+        解决: 改为多次小批量同步数据
+    2. 模型导出的json接口, 功能聚合度过高, 处理时间过长, 容易引发接口请求超时的问题(邢景灏)
+        解决: 接口功能拆分, 遵守接口的单一职责原则
+    
+## 数据中心计算历史和现存问题
+### 已解决
+    1. 模型对象外轮廓信息不标准导致受影响的业务空间计算异常(邢景灏)
+    2. 由关系表迁移和楼层ModelId引起的多个算法计算失败(邢景灏)
+### <font color=red>未解决</font>
+    1. 管网计算分块逻辑有问题 (邢景灏)
+        暂未详细查找原因
+        
+## 调度器历史和现存问题
+### 已解决
+#### 性能问题
+    1. 派发任务效率较低 (邢景灏)
+    2. 任务返回结果数据量过大, 导致全局数据操作变慢(邢景灏)
+
+#### 架构问题
+    1. 在tcp连接时, 线上环境偶尔出现假死状态, 客户端和服务器不能正常通信(邢景灏)
+    2. 在tcp长连接断网时需要添加自动重连机制, 否则需要人工介入重启服务(邢景灏)
+    3. 由基于tcp/ip的CS架构切换为http接口调用方式, 服务器端的接口和结构调整(邢景灏)
+    4. 客户端在切换处理对象(服务器端)时, 因为id格式和后台限制原因不能正常工作(邢景灏)
+
+#### 架构问题
+    1. 由基于tcp/ip的CS架构切换为http接口调用方式, 客户端的调整(庞利祥)
+    2. 服务器端未与新客户端完成对接 (庞利祥, 邢景灏)
+    
+
+
+## 模型检查和导出客户端问题
+
+### 已解决
+    1. 缺少软管, 软水管数据, 导致管网计算不能正常计算 (孟向歌)
+    2. 模型的导出数据有残缺, 出现过多个不同的bug(孟向歌)
+    3. 模型检查结果异常, 出现过多个不同的bug(孟向歌)
+    4. 因为网络不稳定导致下载模型文件失败, 用户经常需要重新上传模型(邢景灏)
+### <font color=red>未解决</font>
+    1. 模型检查报告异常, 有错误没检查出来 (孟向歌)
+    2. 模型检查进程不能正常结束 (孟向歌)
+        已有解决方案

+ 21 - 14
docs/dev/data-center/relations/topology/sys_block.md

@@ -1,23 +1,27 @@
-管网系统设备分块
+# 管网系统设备分块
 ## 前置条件
-1. 项目下的模型文件已上传;
-2. 所有管网已正确连接;
-3. 相邻层立管开放端口坐标位置相等(距离差值不能超过0.01)
-4. (非强制)通过模型检查:连接件检查、系统类型名称检查、管网及相关设备检查、管段检查
+    1. 项目下的模型文件已上传;
+    2. 所有管网已正确连接;
+    3. 相邻层立管开放端口坐标位置相等(距离差值不能超过0.01)
+    4. (非强制)通过模型检查:连接件检查、系统类型名称检查、管网及相关设备检查、管段检查
 
-## 处理方式
+## 处理逻辑
 
-1. 获取所有当前项目project_id下的的有模型文件models; 表:revit.model_folder、revit.model_floor、revit.model_file
-2. 遍历models,获取model层的系统图systemGraphs;
-    1. 获取model下且domain、systemName符合条件的connector,connectors,表:revit.connector
-    2. 获取model下所有的设备、部件、其它、风管、水管,表:revit.equipment、revit.component、revit.other、revit.pipe、revit.duct
-    3. 获取model层的系统图数据,存在systemGraphs中。
-3. 获取systemGraphs中所有的开放立管,按开放立管对连接的系统图systemGraphs进行合并;
-4. 删除本项目下project_id、指定系统类型systemName,指定域domain,所有数据,表revit_calc.connected_block
-4. 将合并后的数据存入数据库,表:revit_calc.connected_block。
+    1. 获取所有当前项目project_id下的的有模型文件models; 表:revit.model_folder、revit.model_floor、revit.model_file
+    2. 遍历models,获取model层的系统图systemGraphs;
+        1. 获取model下且domain、systemName符合条件的connector,connectors,表:revit.connector
+        2. 获取model下所有的设备、部件、其它、风管、水管,表:revit.equipment、revit.component、revit.other、revit.pipe、revit.duct
+        3. 获取model层的系统图数据,存在systemGraphs中。
+    3. 获取systemGraphs中所有的开放立管,按开放立管对连接的系统图systemGraphs进行合并;
+    4. 删除本项目下project_id、指定系统类型systemName,指定域domain,所有数据,表revit_calc.connected_block
+    4. 将合并后的数据存入数据库,表:revit_calc.connected_block。
 
 
 # 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 create or replace function public.sys_block(project_id character varying,building_id character varying,system_name character varying,domain character varying) returns boolean
 as
@@ -130,6 +134,9 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.sys_block('Pj1101010015','Bd11010100153c05821ed8fd11e9b8f2d79d0a5b4bf6','冷冻水供水管','DomainPiping')
 ```
 
+</details>
+
+
 ## 输入
     1. 项目id
     2. 需要计算的building_id,如果没有提供时请传入null,不能传""

+ 14 - 8
docs/dev/data-center/relations/topology/sys_direction.md

@@ -1,18 +1,22 @@
-管网系统确定流向
+# 管网系统确定流向
 ## 前置条件
 
-1. 通过管网系统分块计算;
-2. 指定源。
+    1. 通过管网系统分块计算;
+    2. 指定源。
 
-## 处理方式
+## 处理逻辑
 
-1. 从connected_block表中取出所有关系,构建无向图
-2. 从connected_block_source表中取出所有的源
-3. 由图算法确定流向,构建有方向的图
-4. 更新connected_block表
+    1. 从connected_block表中取出所有关系,构建无向图
+    2. 从connected_block_source表中取出所有的源
+    3. 由图算法确定流向,构建有方向的图
+    4. 更新connected_block表
 
 
 # 函数
+
+<details>
+<summary>源码</summary>
+
 ```
 create or replace function public.sys_direction(project_id character varying,building_id character varying,block_id character varying, system_name character varying,domain character varying,is_source boolean default true) returns boolean
 as
@@ -72,6 +76,8 @@ LANGUAGE 'plpython3u' VOLATILE;
 select public.sys_direction('Pj1101010015','Bd11010100153c05821ed8fd11e9b8f2d79d0a5b4bf6','0','冷冻水供水管','DomainPiping',true)
 ```
 
+</details>
+
 ## 输入
     1. 项目id
     2. 需要计算的building_id,如果没有提供时请传入null,不能传""

+ 222 - 5
docs/dev/paas/data-dict.md

@@ -1,4 +1,3 @@
-# 数据字典接口文档
 ### 术语说明:
 
 #### 平台级字典
@@ -33,13 +32,13 @@
 站在用户或数据字典使用方的角度来看数据字典有三层:平台级字典,集团级字典,项目级字典
 类型相同或信息点相同时项目级字典优先级最高,集团级次之,平台级字典最低,优先级高的会覆盖优先级低的
 
-使用数据字典时明确"使用的字典位于哪个层级"对需求的分析和理解会有很大帮
+使用数据字典时明确"使用的字典位于哪个层级"对需求的分析和理解会有很大帮
 
 集团级数据、集团方案、项目级数据是数据字典内部逻辑概念
 应用和服务应该关注的是项目级字典和应用订阅内容
 
 ```
-		
+
 
 ### 字段约定
 
@@ -118,9 +117,9 @@
 使用新的数据类型时,使用新的数据类型时,创建或编辑信息点需要明确指出数据类型、动静分类、是否复数、是否区间、长度(可选)、取值区间(可选)、格式(可选)
 Tree、Topology、Route、Function四种类型不再支持(有需求再加回来)
 
-动静分类(静态、脉冲、时序、阶段)应该是信息点的一个分类,不是数据类型的属性,放在这里是为了更直观更容易理解
+动静分类(静态 STATIC、脉冲 PULSE、时序 SEQUENTIAL、阶段 GRADATION)应该是信息点的一个分类,不是数据类型的属性,放在这里是为了更直观更容易理解
 根据动静分类区分动态量或静态量,静态量的值存储的是具体的数据,动态量的值存储的是表号-功能号,动态量包括脉冲量、时序量和阶段量
-根据是否区间来判断存储的值是具体值还是区间, 比如INT非区间的值12, 区间值[8, 15],为了区分开闭区间,这里实际存储为{$gt: 12, $lte: 15}, 其中$gt大于,$lt小于,$gte大于等于,$lte小于等于
+根据是否区间来判断存储的值是具体值还是区间, 比如INTEGER非区间的值12, 区间值[8, 15],为了区分开闭区间,这里实际存储为{$gt: 12, $lte: 15}, 其中$gt大于,$lt小于,$gte大于等于,$lte小于等于
 根据是否复数区分存储的值是单个值还是多个值,单个值存储形式为xxx,多个值存储形式为[xxx, yyy],如果同时是复数和区间,存储的是多个区间
 取值区间可以约束值的取值范围,可以通过取值区间做一次校验,如果是区间值,区间也应该是在取值区间的内部
 统一用DATETIME表示日期和时间,通过格式设定具体存储的内容,格式由数据字典进行维护,物理世界存储的数据严格符合格式
@@ -669,4 +668,222 @@ POST: /req/query
 |                         |        |                                      |      |
 |                         |        |                                      |      |
 
+#### 基础接口:批量添加应用订阅信息
+
+请求地址
+
+```
+POST: /app/funcid/add?groupId=SN&projectId=Pj01&app=test&classCode=project
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |   备注   |
+| --------- | --------------------------------------- | ---- |
+| classCode   | 类型编码                                | 必填 |
+| groupId   | 集团id                                  | 必填 |
+| projectId | 项目id                                  | 必填 |
+| app     | 应用id| 必填 |
+| json参数          |信息点列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+
+#### 基础接口:批量删除应用订阅信息
+
+请求地址
+
+```
+POST: /app/funcid/remove?groupId=SN&projectId=Pj01&app=test&classCode=project
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |   备注   |
+| --------- | --------------------------------------- | ---- |
+| classCode   | 类型编码                                | 必填 |
+| groupId   | 集团id                                  | 必填 |
+| projectId | 项目id                                  | 必填 |
+| app     | 应用id| 必填 |
+| json参数          |信息点列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+
+#### 基础接口:批量添加应用订阅类型
+
+请求地址
+
+```
+POST: /app/class/add?groupId=SN&projectId=Pj01&app=test
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |  备注    |
+| --------- | --------------------------------------- | ---- |
+| groupId   | 集团id                                  | 必填 |
+| projectId | 项目id                                  | 必填 |
+| app     | 应用id| 必填 |
+| json参数          |类型列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+#### 基础接口:批量删除应用订阅类型
+
+请求地址
+
+```
+POST: /app/class/remove?groupId=SN&projectId=Pj01&app=test
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |   备注   |
+| --------- | --------------------------------------- | ---- |
+| groupId   | 集团id                                  | 必填 |
+| projectId | 项目id                                  | 必填 |
+| app     | 应用id| 必填 |
+| json参数          |类型列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+
+
+#### 基础接口:批量添加方案订阅信息
+
+请求地址
+
+```
+POST: /scheme/funcid/add?schemeId=test&classCode=project
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |  备注    |
+| --------- | --------------------------------------- | ---- |
+| classCode   | 类型编码                                | 必填 |
+| schemeId     | 方案id| 必填 |
+| json参数          |信息点列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+
+#### 基础接口:批量删除方案订阅信息
+
+请求地址
+
+```
+POST: /scheme/funcid/remove?projectId=Pj01&schemeId=test&classCode=project
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |   备注   |
+| --------- | --------------------------------------- | ---- |
+| classCode   | 类型编码                                | 必填 |
+| projectId | 项目id                                  | 必填 |
+| schemeId     | 方案id| 必填 |
+| json参数          |信息点列表                                         |  列表size大于0    |
+
+返回参数
 
+```
+{
+    "result": "success"
+}
+```
+
+#### 基础接口:批量添加方案订阅类型
+
+请求地址
+
+```
+POST: /scheme/class/add?schemeId=test
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |   备注   |
+| --------- | --------------------------------------- | ---- |
+| schemeId     | 方案id| 必填 |
+| json参数          |类型列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```
+#### 基础接口:批量删除方案订阅类型
+
+请求地址
+
+```
+POST: /scheme/class/romove?schemeId=test
+```
+
+请求参数
+```json
+["ProjUnderArea","Group"]
+```
+
+| 参数名    | 说明                                    |    备注  |
+| --------- | --------------------------------------- | ---- |
+| schemeId     | 方案id| 必填 |
+| json参数          |类型列表                                         |  列表size大于0    |
+
+返回参数
+
+```
+{
+    "result": "success"
+}
+```

+ 10 - 0
docs/dev/saga-graphy/floor-map/mapDemo.md

@@ -0,0 +1,10 @@
+# 可编辑直线示例
+::: details 目录
+[[toc]]
+:::
+
+<example-web-graph-MapDemo/>
+
+::: details 查看代码
+<<< @/docs/.vuepress/components/example/web/graph/mapDemo.vue
+:::

+ 5 - 0
docs/dev/saga-graphy/graphy-engine/style.md

@@ -1,5 +1,10 @@
 # 颜色与样式
+
 ::: details 目录
 [[toc]]
 :::
 
+## 阴影
+
+<example-web-graph-style-shadow /> 
+

+ 6 - 2
docs/dev/saga-graphy/index.js

@@ -25,11 +25,14 @@ const content = [
                     ["/dev/saga-graphy/scene-manage/items/clock", "时钟"],
                     ["/dev/saga-graphy/scene-manage/items/text", "文本"],
                     ["/dev/saga-graphy/scene-manage/items/image", "图片"],
-                    ["/dev/saga-graphy/scene-manage/items/edit-polygon", "可编辑多边形示例"],
+                    ["/dev/saga-graphy/scene-manage/items/editLine", "可编辑直线"],
+                    ["/dev/saga-graphy/scene-manage/items/editPolyline", "可编辑折线"],
+                    ["/dev/saga-graphy/scene-manage/items/editPolygon", "可编辑多边形示例"],
                     ["/dev/saga-graphy/scene-manage/items/imgText", "图例item(图片文本组合)"]
                 ]
             },
-            ["/dev/saga-graphy/scene-manage/undo", "Undo示例"]
+            ["/dev/saga-graphy/scene-manage/undo", "Undo示例"],
+            ["/dev/saga-graphy/scene-manage/align", "对齐示例"],
         ]
     },
     {
@@ -40,6 +43,7 @@ const content = [
             ["/dev/saga-graphy/floor-map/downloadFile", "手工下载楼层底图文件"],
             ["/dev/saga-graphy/floor-map/jsonFile", "json数据格式"],
             ["/dev/saga-graphy/floor-map/divide", "划分"],
+            ["/dev/saga-graphy/floor-map/mapDemo", "楼层平面图范例"],
         ]
     },
     {

+ 16 - 0
docs/dev/saga-graphy/scene-manage/align.md

@@ -0,0 +1,16 @@
+# 对齐示例
+
+::: details 目录
+[[toc]]
+:::
+
+<example-web-graph-scene-Align />
+
+::: details 查看代码
+<<< @/docs/.vuepress/components/example/web/graph/scene/Align.vue
+:::
+
+::: tip 注
+1、使用对齐时,至少选择2个item<br/>
+2、使用分散对齐时,至少选择3个item<br/>
+:::

+ 15 - 0
docs/dev/saga-graphy/scene-manage/items/editLine.md

@@ -0,0 +1,15 @@
+# 可编辑直线示例
+::: details 目录
+[[toc]]
+:::
+
+<example-web-graph-scene-SEditLine/>
+
+::: tip 注
+1、可以通过双击直线在编辑状态和展示状态来回切换,<br/>
+2、编辑状态时:鼠标点击在直线端点上,可拖动点;<br/>
+:::
+
+::: details 查看代码
+<<< @/docs/.vuepress/components/example/web/graph/scene/SEditLine.vue
+:::

docs/dev/saga-graphy/scene-manage/items/edit-polygon.md → docs/dev/saga-graphy/scene-manage/items/editPolygon.md


+ 15 - 0
docs/dev/saga-graphy/scene-manage/items/editPolyline.md

@@ -0,0 +1,15 @@
+# 可编辑折线示例
+
+<example-web-graph-scene-PolylineItem/>
+
+::: tip 注
+1、enter完成创建 <br/>
+2、双击折线附近,进入编辑态;再次双击进入查看态 <br/>
+3、编辑态时:点击点附近更改点位置 <br/>
+4、编辑状态时:通过ALT键 + 鼠标左键 删除顶点
+:::
+
+
+::: details 查看代码
+<<< @/docs/.vuepress/components/example/web/graph/scene/PolylineItem.vue
+:::

+ 1 - 1
docs/dev/saga-graphy/scene-manage/items/image.md

@@ -7,4 +7,4 @@
 
 ::: details 查看代码
 <<< @/docs/.vuepress/components/example/web/graph/scene/ImageItem.vue
-:::
+:::

+ 4 - 4
package.json

@@ -12,10 +12,10 @@
     "publish": "node publish.js"
   },
   "dependencies": {
-    "@saga-web/base": "^2.1.9",
-    "@saga-web/big": "^1.0.24",
-    "@saga-web/draw": "^2.1.84",
-    "@saga-web/graph": "^2.1.67",
+    "@saga-web/base": "2.1.16",
+    "@saga-web/big": "1.0.35",
+    "@saga-web/draw": "2.1.90",
+    "@saga-web/graph": "2.1.78",
     "@saga-web/feng-map": "1.0.6",
     "axios": "^0.18.1",
     "element-ui": "^2.12.0",