Преглед на файлове

蜂鸟解析器添加,底图item格式修改;引擎增加mesuretext

haojianlong преди 5 години
родител
ревизия
636b0e6804

+ 1 - 1
saga-web-base/package.json

@@ -18,7 +18,7 @@
     "author": "庞利祥 (sybotan@126.com)",
     "license": "ISC",
     "publishConfig": {
-        "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
+        "registry": "http://192.168.200.80:8081/repository/npm-hosted/"
     },
     "devDependencies": {
         "@typescript-eslint/eslint-plugin": "^1.12.0",

+ 2 - 2
saga-web-big/package.json

@@ -1,6 +1,6 @@
 {
     "name": "@saga-web/big",
-    "version": "1.0.4",
+    "version": "1.0.6",
     "description": "上格云Web平面图。",
     "main": "lib/index.js",
     "types": "lib/index.d.js",
@@ -18,7 +18,7 @@
     "author": "郝建龙 (1061851420@qq.com)",
     "license": "ISC",
     "publishConfig": {
-        "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
+        "registry": "http://192.168.200.80:8081/repository/npm-hosted/"
     },
     "devDependencies": {
         "@typescript-eslint/eslint-plugin": "^1.12.0",

+ 2 - 0
saga-web-big/src/index.ts

@@ -20,6 +20,7 @@ import { SEquipParser } from "./parser/SEquipParser";
 import { SZoneParser } from "./parser/SZoneParser";
 import { STopologyParser } from "./parser/STopologyParser";
 import { SFloorParser } from "./parser/SFloorParser";
+import { SParser } from "./parser/SParser";
 
 export {
     SAnchorItem,
@@ -39,6 +40,7 @@ export {
     ItemOrder,
     Transparency,
     SItemFactory,
+    SParser,
     SFloorParser,
     STopologyParser,
     SZoneParser,

+ 100 - 0
saga-web-big/src/items/SIconTextItem.ts

@@ -0,0 +1,100 @@
+import { SGraphyItem } from "@saga-web/graphy/lib";
+import { ImageData } from "../types/ImageData";
+import { SPainter, SRect } from "@saga-web/draw/lib";
+import { SMouseEvent } from "@saga-web/base/lib";
+
+/**
+ *  图标+文字item
+ *
+ * * @author  郝建龙(1061851420@qq.com)
+ */
+export class SIconTextItem extends SGraphyItem {
+    /** 标志宽度 */
+    private width: number = 20;
+    /** 标志高度 */
+    private height: number = 20;
+    /** 图片地址    */
+    url: string = "";
+    /** 图片dom */
+    Img: CanvasImageSource | undefined;
+    /** 图片item所有数据  */
+    private data: ImageData;
+    /** 绘制的文本   */
+    _text: string = "";
+    get text(): string {
+        return this._text;
+    }
+    set text(val) {
+        this._text = val;
+        this.update();
+    }
+
+    /**
+     * 构造函数
+     *
+     *  @param parent    指向父对象
+     *  @param data      图片数据
+     * */
+    constructor(parent: SGraphyItem | null, data: ImageData) {
+        super(parent);
+        this.data = data;
+        if (data.Url) {
+            this.Img = new Image();
+            this.url = data.Url;
+            this.Img.src = this.url;
+            this.Img.onload = (): void => {
+                // @ts-ignore
+                this.width = data.Width ? data.Width : this.Img.width;
+                // @ts-ignore
+                this.height = data.Height ? data.Height : this.Img.height;
+                this.update();
+            };
+        }
+        this.isTransform = false;
+    }
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param	event         事件参数
+     * @return	boolean
+     */
+    onMouseDown(event: SMouseEvent): boolean {
+        this.$emit("mousedown");
+        console.log(this);
+        this.update();
+        return true;
+    } // Function onMouseDown()
+
+    /**
+     * Item对象边界区域
+     *
+     * @return	SRect
+     */
+    boundingRect(): SRect {
+        return new SRect(
+            -this.width / 2,
+            this.height / 2,
+            this.width,
+            this.height
+        );
+    }
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter       painter对象
+     */
+    onDraw(painter: SPainter): void {
+        if (this.Img) {
+            painter.drawImage(
+                this.Img,
+                -this.width / 2,
+                this.height / 2,
+                this.width,
+                this.height
+            );
+            painter.drawText(this.text, this.width, this.height / 2);
+        }
+    } // Function onDraw()
+} // Class SImageItem

+ 68 - 0
saga-web-big/src/items/SLineItem.ts

@@ -0,0 +1,68 @@
+import { SGraphyItem } from "@saga-web/graphy/lib";
+import { SLine, SPainter, SPoint } from "@saga-web/draw/lib";
+import { SMouseEvent } from "@saga-web/base";
+
+/**
+ * 直线item
+ *
+ * */
+
+export class SLineItem extends SGraphyItem {
+    /** 线段起始点   */
+    p1: SPoint | undefined;
+    /** 线段终止点   */
+    p2: SPoint | undefined;
+
+    /**
+     * 鼠标按下事件
+     *
+     * @param   event   鼠标事件
+     * @return  是否处理事件
+     * */
+    onMouseDown(event: SMouseEvent): boolean {
+        return false;
+    } // Function onMouseDown()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param   event   鼠标事件
+     * @return  是否处理事件
+     * */
+    onMouseMove(event: SMouseEvent): boolean {
+        return false;
+    } // Function onMouseMove()
+
+    /**
+     * 鼠标移动事件
+     *
+     * @param   event   鼠标事件
+     * @return  是否处理事件
+     * */
+    onMouseUp(event: SMouseEvent): boolean {
+        return false;
+    } // Function onMouseUp()
+
+    /**
+     * 判断点是否在区域内
+     *
+     * @param   x
+     * @param   y
+     * @return  true-是
+     */
+    contains(x: number, y: number): boolean {
+
+        return false;
+    } // Function contains()
+
+    /**
+     * Item绘制操作
+     *
+     * @param   painter painter对象
+     */
+    onDraw(painter: SPainter): void {
+        if (this.p1 instanceof SPoint && this.p2 instanceof SPoint) {
+            painter.drawLine(this.p1, this.p2);
+        }
+    } // Function onDraw()
+} // Class SLineItem

+ 1 - 1
saga-web-big/src/parser/SParser.ts

@@ -13,7 +13,7 @@ export abstract class SParser {
      *
      * @param   factory 解析工厂
      * */
-    constructor(factory: SItemFactory | undefined) {
+    constructor(factory: SItemFactory | null = null) {
         if (factory) {
             this.factory = factory;
         }

+ 5 - 5
saga-web-big/src/types/floor/Column.ts

@@ -28,15 +28,15 @@ import { Place } from "../Place";
  */
 export interface Column {
     /** 名称  */
-    Name: string;
+    Name?: string;
     /** 轮廓线  */
     OutLine: Point[][];
     /** 房间边界  */
-    RoomBoundary: boolean;
+    RoomBoundary?: boolean;
     /** 位置  */
-    Location: Place;
+    Location?: Place;
     /** 模型id(外键)    */
-    ModelId: string;
+    ModelId?: string;
     /** 对应Revit模型id */
-    SourceId: string;
+    SourceId?: string;
 } // Interface Column

+ 7 - 7
saga-web-big/src/types/floor/Space.ts

@@ -28,21 +28,21 @@ import { Place } from "../Place";
  */
 export interface Space {
     /** 轮廓线段    */
-    BoundarySegments: string[];
+    BoundarySegments?: string[];
     /** 位置  */
     Location: Place;
     /** 高度  */
-    Height: number;
+    Height?: number;
     /** 模型id(外键)    */
-    ModelId: string;
+    ModelId?: string;
     /** 名称  */
-    Name: string;
+    Name?: string;
     /** 轮廓线  */
     OutLine: Point[][];
     /** 对应Revit模型id */
-    SourceId: string;
+    SourceId?: string;
     /** 补充信息    */
-    Tag: string;
+    Tag?: string;
     /** 类型  */
-    TypeId: string;
+    TypeId?: string;
 } // Interface Space

+ 4 - 4
saga-web-big/src/types/floor/VirtualWall.ts

@@ -28,13 +28,13 @@ import { Place } from "../Place";
  */
 export interface VirtualWall {
     /** 位置  */
-    Location: Place;
+    Location?: Place;
     /** 模型id(外键)    */
-    ModelId: string;
+    ModelId?: string;
     /** 名称  */
-    Name: string;
+    Name?: string;
     /** 轮廓线  */
     OutLine: Point[][];
     /** 对应Revit模型id */
-    SourceId: string;
+    SourceId?: string;
 } // interface VirtualWall

+ 6 - 6
saga-web-big/src/types/floor/Wall.ts

@@ -28,17 +28,17 @@ import { Place } from "../Place";
  */
 export interface Wall {
     /** 层id */
-    LevelId: string;
+    LevelId?: string;
     /** 位置  */
-    Location: Place;
+    Location?: Place;
     /** 模型id(外键)    */
-    ModelId: string;
+    ModelId?: string;
     /** 名称  */
-    Name: string;
+    Name?: string;
     /** 轮廓线  */
     OutLine: Point[][];
     /** 对应Revit模型id */
-    SourceId: string;
+    SourceId?: string;
     /** 厚度  */
-    Width: number;
+    Width?: number;
 } // Interface Wall

+ 1 - 1
saga-web-draw/package.json

@@ -17,7 +17,7 @@
     "author": "庞利祥 (sybotan@126.com)",
     "license": "ISC",
     "publishConfig": {
-        "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
+        "registry": "http://192.168.200.80:8081/repository/npm-hosted/"
     },
     "devDependencies": {
         "@typescript-eslint/eslint-plugin": "^1.12.0",

+ 10 - 0
saga-web-draw/src/SPainter.ts

@@ -652,6 +652,16 @@ export class SPainter extends SObject {
     } // Function painterToView()
 
     /**
+     * 预测量文本宽度
+     *
+     * @param   text    文本字符
+     * @return  文本所占长度像素
+     * */
+    textWidth(text: string): number {
+        return this.engine.textWidth(text);
+    }
+
+    /**
      * 绘制带箭头的线段
      *
      * @param   line    线段

+ 10 - 0
saga-web-draw/src/engines/SCanvasPaintEngine.ts

@@ -352,6 +352,16 @@ export class SCanvasPaintEngine extends SPaintEngine {
         }
     } // Function drawImage()
 
+    /**
+     * 预测量文本宽度
+     *
+     * @param   text    预测的文本
+     * @return  文本长度像素
+     * */
+    textWidth(text: string): number {
+        return this._canvas.measureText(text).width;
+    } // Function textWidth()
+
     // /**
     //  * 绘制带导角空心矩形
     //  *

+ 7 - 0
saga-web-draw/src/engines/SPaintEngine.ts

@@ -273,4 +273,11 @@ export abstract class SPaintEngine {
         width?: number,
         height?: number
     ): void;
+
+    /**
+     * 预测量文本宽度
+     *
+     * @param   text    预测的文本
+     * */
+    abstract textWidth(text: string): number;
 } // class SPaintEngine

+ 10 - 0
saga-web-draw/src/engines/SSvgPaintEngine.ts

@@ -318,6 +318,16 @@ export class SSvgPaintEngine extends SPaintEngine {
     } // Function drawImage()
 
     /**
+     * 预测量文本宽度
+     *
+     * @param   text    预测的文本
+     * @return  文本长度像素
+     * */
+    textWidth(text: string): number {
+        return 0;
+    } // Function textWidth()
+
+    /**
      * 获得svg需要的变形信息
      *
      * @return  变换信息

+ 4 - 3
saga-web-fengmap/package.json

@@ -17,20 +17,21 @@
     "author": "郝建龙 (1061851420@qq.com)",
     "license": "ISC",
     "publishConfig": {
-        "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
+        "registry": "http://192.168.200.80:8081/repository/npm-hosted/"
     },
     "devDependencies": {
+        "@types/jest": "^24.0.15",
         "@typescript-eslint/eslint-plugin": "^1.12.0",
         "@typescript-eslint/parser": "^1.12.0",
         "eslint": "^6.0.1",
         "eslint-config-prettier": "^6.0.0",
         "eslint-plugin-prettier": "^3.1.0",
+        "fengmap": "^2.5.3",
         "prettier": "^1.18.2",
-        "@types/jest": "^24.0.15",
         "ts-jest": "^24.0.2",
         "typescript": "^3.5.3"
     },
     "dependencies": {
-        "@saga-web/big": "1.0.4"
+        "@saga-web/big": "1.0.6"
     }
 }

+ 197 - 2
saga-web-fengmap/src/parser/SFengParser.ts

@@ -1,4 +1,10 @@
-import { SParser } from "@saga-web/big/lib/parser/SParser";
+import { SItemFactory, SParser } from "@saga-web/big/lib";
+// @ts-ignore
+import fengmap from "fengmap";
+import { Space } from "@saga-web/big/lib/types/floor/Space";
+import { Column } from "@saga-web/big/lib/types/floor/Column";
+import { VirtualWall } from "@saga-web/big/lib/types/floor/VirtualWall";
+import { Wall } from "@saga-web/big/lib/types/floor/Wall";
 
 /**
  * 蜂鸟数据解析器
@@ -59,5 +65,194 @@ export class SFengParser extends SParser {
         120008: "ParkingExit",
         120009: "ParkingEntrance",
         120010: "ParkingExitAndEntrance"
-     };
+    };
+    /** 蜂鸟:底图应用名称   */
+    appName: string = "";
+    /** 当前蜂鸟map的id  */
+    currentMapId: string = "";
+    /** 蜂鸟map绑定dom的id   */
+    domId: string = "";
+    /** 蜂鸟:底图应用秘钥   */
+    key: string = "";
+    /** 底图服务器地址 */
+    serverUrl: string = "./data/";
+    /** 蜂鸟图 */
+    private readonly fmap: fengmap.FMMap;
+    /** 属于空间类型typeid    */
+    spaceType: number[] = [
+        100000,
+        200000,
+        900000,
+        800000,
+        200004,
+        200003,
+        200103,
+        200203,
+        200005,
+        200002,
+        200006,
+        200007,
+        200017,
+        200018,
+        200019,
+        200020,
+        200014,
+        200009,
+        200008,
+        200011,
+        200012,
+        200013,
+        200015,
+        200016,
+        200021,
+        170006,
+        170008,
+        170007,
+        170003,
+        170001,
+        100001,
+        100004,
+        100005,
+        100007,
+        140002,
+        170002,
+        150010,
+        100003,
+        140004,
+        170005,
+        120001
+    ];
+    /** 属于柱子类型的typeid   */
+    columnType: number[] = [300002];
+    /** 属于墙类型的typeid    */
+    wallType: number[] = [300000, 300001];
+    /** 属于虚拟墙类型的typeid  */
+    virtualWallType: number[] = [
+        200001,
+        110001,
+        200010,
+        120008,
+        120009,
+        120010
+    ];
+
+    /** 构造体 */
+    constructor(
+        domId: string,
+        mapServerURL: string,
+        key: string,
+        appName: string,
+        factory: SItemFactory
+    ) {
+        super(factory);
+        this.domId = domId;
+        this.key = key;
+        this.serverUrl = mapServerURL;
+        this.appName = appName;
+        this.fmap = new fengmap.FMMap({
+            container: document.getElementById(this.domId),
+            mapServerURL: this.serverUrl,
+            appName: this.appName,
+            key: this.key
+        });
+    } // Constructor
+
+    /**
+     * 解析数据
+     *
+     * @param   currentMapId    当前模型id
+     * @param   groupId         当前楼层
+     * @param   _fn             查询成功回调函数(返回参数为FloorData)
+     * */
+    parseData(currentMapId: string, groupId: string, _fn: Function): void {
+        this.fmap.openMapById(currentMapId, (err: any) => {
+            console.log("错误信息", err);
+        });
+        this.fmap.on("loadComplete", () => {
+            let obj = {};
+            // 创建搜索分析对象
+            let searchAnalyser = new fengmap.FMSearchAnalyser(this.fmap);
+            // 创建搜索请求体对象
+            let searchReq = new fengmap.FMSearchRequest();
+            searchReq.groupID = groupId;
+            searchReq.type = "Model";
+            searchAnalyser.query(searchReq, (result: any) => {
+                let spaces: Space[] = [],
+                    columns: Column[] = [],
+                    walls: Wall[] = [],
+                    virtualWall: VirtualWall[] = [];
+                result = result
+                    .map((t: any) => {
+                        if (
+                            t.target &&
+                            t.target._data &&
+                            t.target._data.vertices
+                        ) {
+                            let arr = t.target._data.vertices,
+                                type = t.typeID,
+                                outline = [];
+                            for (let i = 0; i < arr.length - 1; i += 2) {
+                                outline.push({
+                                    X: arr[i] - 12982584.99,
+                                    Y: arr[i + 1] - 4911901.56
+                                });
+                            }
+                            if (this.spaceType.indexOf(type) > -1) {
+                                spaces.push({
+                                    // @ts-ignore
+                                    OutLine: [outline],
+                                    Name: t.target.name,
+                                    Location: {
+                                        // @ts-ignore
+                                        Points: [this.getAverageVal([outline])]
+                                    },
+                                    Type: t.typeID
+                                });
+                            } else if (this.columnType.indexOf(type) > -1) {
+                                // @ts-ignore
+                                columns.push({ OutLine: [outline] });
+                            } else if (this.wallType.indexOf(type) > -1) {
+                                // @ts-ignore
+                                walls.push({ OutLine: [outline] });
+                            } else if (
+                                this.virtualWallType.indexOf(type) > -1
+                            ) {
+                                // @ts-ignore
+                                virtualWall.push({ OutLine: [outline] });
+                            }
+                        }
+                    })
+                    .filter((item: any) => item);
+                obj = {
+                    Spaces: spaces,
+                    Columns: columns,
+                    Walls: walls,
+                    VirtualWalls: virtualWall
+                };
+                _fn(obj);
+            });
+        });
+    }
+
+    /**
+     * 计算平均值
+     *
+     * @param   Outline 轮廓线束
+     * @return  object  {X:X,Y:Y}x的平均值,y的平均值
+     * */
+    private getAverageVal(Outline: { X: number; Y: number }[][]): object {
+        let X = 0,
+            Y = 0,
+            len = Outline[0].length;
+        Outline[0].map(item => {
+            X += item.X;
+            Y += item.Y;
+        });
+        X = Number((X / len).toFixed(2));
+        Y = Number((Y / len).toFixed(2));
+        return {
+            X: X,
+            Y: Y
+        };
+    }
 } // class SEquipParser

+ 1 - 1
saga-web-graphy/package.json

@@ -17,7 +17,7 @@
     "author": "庞利祥 (sybotan@126.com)",
     "license": "ISC",
     "publishConfig": {
-        "registry": "http://dev.dp.sagacloud.cn:8082/repository/npm-hosted/"
+        "registry": "http://192.168.200.80:8081/repository/npm-hosted/"
     },
     "devDependencies": {
         "@typescript-eslint/eslint-plugin": "^1.12.0",