Переглянути джерело

feat: 添加矩形框ai导入绘制

bill 3 тижнів тому
батько
коміт
d6c8da53f9

+ 3 - 3
src/example/fuse/enter.ts

@@ -20,9 +20,9 @@ window.platform.login = (isBack = true) => {
   if (import.meta.env.DEV) {
     platform
       .post("/service/manage/login", {
-        password: "JwiuK95dExMjM0NTY=7nHGf5ySQWSuC4G1An",
-        username: "super-admin",
-        userName: "super-admin",
+        password: "Di8r5tFpExMjM0NTY=F39Vd0znQWfBY7W9iG",
+        username: "W测试2",
+        userName: "W测试2",
       })
       .then((res) => {
         params.value.token = res.token;

+ 128 - 6
src/example/platform/platform-draw.ts

@@ -9,6 +9,7 @@ import {
 } from "@/core/components/line/attach-server";
 import { getIconStyle, IconData } from "@/core/components/icon";
 import { defaultStyle as textDefaultStyle } from "@/core/components/text";
+import { defaultStyle as rectDefaultStyle } from "@/core/components/rectangle";
 import { Transform } from "konva/lib/Util";
 import { ElMessage } from "element-plus";
 import { ImageData } from "@/core/components/image";
@@ -16,7 +17,11 @@ import { lineLen, Pos, Size } from "@/utils/math";
 import { watchEffect } from "vue";
 import { TextData } from "@/core/components/text";
 import { SelectSceneData } from "../dialog/ai";
-import { getLineIconEndpoints, LineIconData } from "@/core/components/line-icon";
+import {
+  getLineIconEndpoints,
+  LineIconData,
+} from "@/core/components/line-icon";
+import { RectangleData } from "@/core/components/rectangle";
 
 const getSizePlaceBoxImage = ({ width, height }: Size) => {
   const borderWidth = 10;
@@ -96,7 +101,7 @@ const getCoverShapes = (cover: SceneResource["cover"]) => {
     url: cover.thumb,
     mat: mat.m,
     width,
-    key: 'kankan-floor-cover',
+    key: "kankan-floor-cover",
     height,
     lock: true,
     cornerRadius: 0,
@@ -106,6 +111,66 @@ const getCoverShapes = (cover: SceneResource["cover"]) => {
   return { geo, thumb };
 };
 
+const getTaggingBorderShapes = async (taggings: SceneResource["taggings"]) => {
+  const icons: IconData[] = [];
+  const images: ImageData[] = [];
+  const texts: TextData[] = [];
+  const now = Date.now();
+  const reqs: Promise<any>[] = [];
+
+  for (let ndx = 0; ndx < taggings.length; ndx++) {
+    const item = taggings[ndx];
+    const mat = new Transform(item.mat);
+
+    if (!item.mat && item.position) {
+      mat.translate(item.position.x, item.position.y);
+      item.rotate && mat.rotate(item.rotate);
+    }
+
+    if (item.isText) {
+      texts.push({
+        ...getBaseItem(),
+        ...textDefaultStyle,
+        key: item.key,
+        content: item.url,
+        zIndex: 1,
+        mat: mat.m,
+        createTime: now + taggings.length + ndx,
+      });
+      continue;
+    }
+    const shape = {
+      ...getBaseItem(),
+      ...(item.size || { width: 100, height: 100 }),
+      name: item.name,
+      key: item.key,
+      createTime: now + ndx,
+      url: item.url,
+      mat: mat.m,
+      zIndex: 1,
+    };
+
+    if (!item.url.includes(".svg")) {
+      images.push(shape);
+      continue;
+    }
+
+    reqs.push(
+      getIconStyle(item.url, shape.width, shape.height, item.fixed)
+        .then((style) => {
+          icons.push({ ...shape, ...style });
+        })
+        .catch(() => {})
+    );
+  }
+  await Promise.all(reqs);
+  return {
+    texts,
+    images,
+    icons,
+  };
+};
+
 const getTaggingShapes = async (taggings: SceneResource["taggings"]) => {
   const icons: IconData[] = [];
   const images: ImageData[] = [];
@@ -166,6 +231,46 @@ const getTaggingShapes = async (taggings: SceneResource["taggings"]) => {
   };
 };
 
+const getBorderTaggingShapes = (taggings: SceneResource["borderTaggings"]) => {
+  const texts: TextData[] = [];
+  const rects: RectangleData[] = [];
+  const now = Date.now();
+
+  for (let i = 0; i < taggings.length; i++) {
+    rects.push({
+      ...getBaseItem(),
+      ...rectDefaultStyle,
+      points: taggings[i].points,
+      attitude: [1, 0, 0, 1, 0, 0],
+    });
+
+    const w = Math.min(
+      taggings[i].points[1].x - taggings[i].points[0].x,
+      textDefaultStyle.fontSize * taggings[i].text.length
+    )
+    const y = taggings[i].center.y - textDefaultStyle.fontSize / 2
+    const x = taggings[i].center.x - w / 2
+
+    const mat = new Transform();
+    mat.translate(x, y);
+
+    const text = {
+      ...getBaseItem(),
+      ...textDefaultStyle,
+      content: taggings[i].text,
+      zIndex: 1,
+      mat: mat.m,
+      width: w,
+      createTime: now + taggings.length + i,
+    }
+    texts.push(text);
+  }
+  return {
+    rects,
+    texts,
+  };
+};
+
 const getWallTaggingShapes = async (
   taggings: SceneResource["wallTaggings"],
   lineData: LineData
@@ -186,7 +291,7 @@ const getWallTaggingShapes = async (
       break;
     }
 
-    console.log(item)
+    console.log(item);
     const shape: LineIconData = {
       ...getBaseItem(),
       name: item.name,
@@ -196,12 +301,12 @@ const getWallTaggingShapes = async (
       lineId: line.id,
       ...item,
     };
-    const iconPoints = getLineIconEndpoints(points, shape)
+    const iconPoints = getLineIconEndpoints(points, shape);
     reqs.push(
       getIconStyle(item.url, lineLen(iconPoints[0], iconPoints[1]), 1000000)
         .then((style) => {
-          if (shape.type === 'align-bottom') {
-            shape.height = style.height
+          if (shape.type === "align-bottom") {
+            shape.height = style.height;
           }
           lineIcons.push({ ...shape, fill: style.fill, stroke: style.stroke });
         })
@@ -270,6 +375,13 @@ const drawSceneResource = async (resource: SceneResource, draw: Draw) => {
   });
 
   const { icons, images, texts } = await getTaggingShapes(resource.taggings);
+
+  // 这版本的icons先不用 用border
+  icons.length = 0
+  const border = getBorderTaggingShapes(resource.borderTaggings)
+  texts.push(...border.texts)
+  const rects = border.rects
+
   const tagShapes = [...icons, ...images, ...texts, thumb];
   tagShapes.forEach((shape) => {
     if (shape) {
@@ -278,6 +390,15 @@ const drawSceneResource = async (resource: SceneResource, draw: Draw) => {
       bound.update({ x: shape.mat[4], y: shape.mat[5] });
     }
   });
+  const lineShapes = [...rects]
+  lineShapes.forEach(item => {
+    item.points.forEach(p => {
+      p.x += offset.x
+      p.y += offset.y
+      bound.update(p)
+    })
+  })
+
   const lineIcons = await getWallTaggingShapes(resource.wallTaggings, geo);
 
   if (oldGeo) {
@@ -293,6 +414,7 @@ const drawSceneResource = async (resource: SceneResource, draw: Draw) => {
   draw.store.addItems("icon", icons);
   draw.store.addItems("text", texts);
   draw.store.addItems("image", images);
+  draw.store.addItems('rectangle', rects)
   if (thumb) {
     draw.store.addItem("image", thumb);
   }

+ 7 - 0
src/example/platform/platform-resource.ts

@@ -44,6 +44,12 @@ export type TaggingInfo = {
   fixed?: boolean;
 };
 
+export type BorderTaggingInfo = {
+  points: Pos[];
+  center: Pos
+  text: string
+};
+
 export type WallTaggingInfo = {
   url: string,
   pointIds: string[]
@@ -55,6 +61,7 @@ export type WallTaggingInfo = {
 export type SceneResource = {
   wallTaggings: WallTaggingInfo[]
   taggings: TaggingInfo[];
+  borderTaggings: BorderTaggingInfo[]
   cover?: CoverLine;
   compass?: number;
 };

+ 73 - 2
src/example/platform/resource-swkk.ts

@@ -1,5 +1,6 @@
 import { genCache, validNum } from "@/utils/shared";
 import {
+  BorderTaggingInfo,
   CoverLine,
   getSceneApi,
   ResourceArgs,
@@ -161,9 +162,9 @@ export const getCoverLine = async (
 
 export const getCompass = async (scene: Scene) => {
   const { config, userFloorpan } = await fetchResource(scene);
-  return 'compass' in userFloorpan 
+  return "compass" in userFloorpan
     ? userFloorpan?.compass
-    : MathUtils.radToDeg(Number(config.orientation || 0))
+    : MathUtils.radToDeg(Number(config.orientation || 0));
 };
 
 export const getHotTaggingInfos = async (scene: Scene, scale: number) => {
@@ -439,6 +440,7 @@ export const getAITaggingInfos = async (
           : shape.category;
       const itemIcon = getIconItem(icon);
       const isWall = itemIcon && "wall" in itemIcon ? itemIcon.wall : false;
+      console.log(isWall, shape);
       if (isWall) continue;
 
       const name = itemIcon?.name || "";
@@ -473,6 +475,70 @@ export const getAITaggingInfos = async (
   return infos;
 };
 
+export const getAIBorderTaggingInfos = async (
+  scene: Scene,
+  subgroup: any,
+  bound: Record<string, number>
+) => {
+  const { ais } = await fetchResource(scene);
+  const infos: BorderTaggingInfo[] = [];
+  const drawBound = {
+    x: bound.x_min,
+    y: bound.y_min,
+    w: bound.x_max - bound.x_min,
+    h: bound.y_max - bound.y_min,
+  };
+
+  for (const data of ais) {
+    if (data.imagePath) {
+      const reg = data.imagePath.match(/floor_(\d)\.png/);
+      const curSubgroup = reg ? Number(reg[1]) : undefined;
+      if (curSubgroup !== subgroup) continue;
+    }
+
+    for (const shape of data.shapes) {
+      const icon =
+        shape.category in aiIconMap
+          ? (aiIconMap as any)[shape.category]
+          : shape.category;
+      const itemIcon = getIconItem(icon);
+      const isWall = itemIcon && "wall" in itemIcon ? itemIcon.wall : false;
+      if (isWall) continue;
+
+      const name = itemIcon?.name || "";
+      const isTag = icon === "Tag";
+      if (!name || isTag) continue;
+
+      const pixelCenter = {
+        x: (shape.bbox[0] + shape.bbox[2]) / 2 / data.imageWidth,
+        y: (shape.bbox[1] + shape.bbox[3]) / 2 / data.imageHeight,
+      };
+      const center = {
+        x: pixelCenter.x * drawBound.w + drawBound.x,
+        y: pixelCenter.y * drawBound.h + drawBound.y,
+      };
+      const size = {
+        width:
+          ((shape.bbox[2] - shape.bbox[0]) / data.imageWidth) * drawBound.w,
+        height:
+          ((shape.bbox[3] - shape.bbox[1]) / data.imageHeight) * drawBound.h,
+      };
+
+      infos.push({
+        text: name,
+        points: [
+          { x: center.x - size.width / 2, y: center.y - size.height / 2 },
+          { x: center.x + size.width / 2, y: center.y - size.height / 2 },
+          { x: center.x + size.width / 2, y: center.y + size.height / 2 },
+          { x: center.x - size.width / 2, y: center.y + size.height / 2 },
+        ],
+        center,
+      });
+    }
+  }
+  return infos;
+};
+
 export const getWallAITaggingInfos = async (
   scene: Scene,
   subgroup: any,
@@ -581,6 +647,7 @@ export const getResource = async ({
   const key = floor.subgroup;
   const taggings: TaggingInfo[] = [];
   const wallTaggings: WallTaggingInfo[] = [];
+  const borderTaggings: BorderTaggingInfo[] = [];
   let coverLine: CoverLine;
 
   const compass = await getCompass(scene);
@@ -597,6 +664,9 @@ export const getResource = async ({
           getAITaggingInfos(scene, key, cover.bound).then((ts) =>
             taggings.push(...ts)
           ),
+          getAIBorderTaggingInfos(scene, key, cover.bound).then((ts) =>
+            borderTaggings.push(...ts)
+          ),
         ])
       ),
   ];
@@ -624,6 +694,7 @@ export const getResource = async ({
 
   return {
     taggings: taggings,
+    borderTaggings,
     wallTaggings,
     cover: coverLine!,
     compass: compass,