|
@@ -1,4 +1,4 @@
|
|
|
-import { genBound, onlyId } from "@/utils/shared";
|
|
|
+import { copy, genBound, onlyId } from "@/utils/shared";
|
|
|
import { AIExposeData } from "../dialog/ai";
|
|
|
import { Draw } from "../components/container/use-draw";
|
|
|
import { SceneFloor } from "./platform-resource";
|
|
@@ -7,6 +7,10 @@ import { LineData, defaultStyle } from "@/core/components/line";
|
|
|
import { getInitCtx, normalLineData } from "@/core/components/line/use-draw";
|
|
|
import { defaultStyle as iconDefaultStyle } from "@/core/components/icon";
|
|
|
import { Transform } from "konva/lib/Util";
|
|
|
+import { ElMessage } from "element-plus";
|
|
|
+import { ImageData } from "@/core/components/image";
|
|
|
+import { Size } from "@/utils/math";
|
|
|
+import { watchEffect } from "vue";
|
|
|
|
|
|
const scaleResource = (info: AIExposeData, scale: number) => {
|
|
|
const floors = info.floors.map((item) => ({
|
|
@@ -82,7 +86,6 @@ const getResourceLayers = (data: AIExposeData) => {
|
|
|
let box: SceneFloor["box"];
|
|
|
// if (true) {
|
|
|
if (!floor.box || !floor.box.bound.x_max || !floor.box.bound.z_max) {
|
|
|
- console.log(floor.geos)
|
|
|
const xs = floor.geos.flatMap((item) => item.map((p) => p.x));
|
|
|
const ys = floor.geos.flatMap((item) => item.map((p) => p.y));
|
|
|
const zs = floor.geos.flatMap((item) => item.map((p) => p.z));
|
|
@@ -113,9 +116,6 @@ const getResourceLayers = (data: AIExposeData) => {
|
|
|
box,
|
|
|
taggings: data.taggings
|
|
|
.filter((item) => {
|
|
|
- console.log(item.position.z === undefined ||
|
|
|
- (item.position.z >= box.bound.z_min &&
|
|
|
- item.position.z <= box.bound.z_max), item, box)
|
|
|
return (
|
|
|
item.position.z === undefined ||
|
|
|
(item.position.z >= box.bound.z_min &&
|
|
@@ -132,7 +132,33 @@ const getResourceLayers = (data: AIExposeData) => {
|
|
|
.filter((floor) => floor.taggings.length > 0 || floor.geos.length > 0);
|
|
|
};
|
|
|
|
|
|
-const drawLayerResource = (
|
|
|
+const getSizePlaceBoxImage = ({ width, height }: Size) => {
|
|
|
+ const borderWidth = 10;
|
|
|
+ const canvas = document.createElement("canvas");
|
|
|
+ canvas.width = width;
|
|
|
+ canvas.height = height;
|
|
|
+
|
|
|
+ const ctx = canvas.getContext("2d")!;
|
|
|
+
|
|
|
+ // 画背景白色
|
|
|
+ ctx.fillStyle = "#fff";
|
|
|
+ ctx.fillRect(0, 0, width, height);
|
|
|
+
|
|
|
+ // 画边框
|
|
|
+ ctx.lineWidth = borderWidth;
|
|
|
+ ctx.strokeStyle = "#000"; // 黑色边框
|
|
|
+ // 注意strokeRect位置和尺寸要配合线宽,这里我们让边框完整显示在canvas内
|
|
|
+ ctx.strokeRect(
|
|
|
+ borderWidth / 2,
|
|
|
+ borderWidth / 2,
|
|
|
+ width - borderWidth,
|
|
|
+ height - borderWidth
|
|
|
+ );
|
|
|
+
|
|
|
+ return canvas.toDataURL(); // 返回图片的Data URL字符串
|
|
|
+};
|
|
|
+
|
|
|
+const drawLayerResource = async (
|
|
|
layerResource: ReturnType<typeof getResourceLayers>[number],
|
|
|
draw: Draw
|
|
|
) => {
|
|
@@ -140,17 +166,15 @@ const drawLayerResource = (
|
|
|
const images: any[] = [];
|
|
|
const createTime = Date.now();
|
|
|
|
|
|
- let sGeo = draw.store.getTypeItems("line")[0];
|
|
|
- let geo: LineData = sGeo
|
|
|
- ? sGeo
|
|
|
- : {
|
|
|
- ...getBaseItem(),
|
|
|
- lines: [],
|
|
|
- points: [],
|
|
|
- polygon: [],
|
|
|
- attitude: [1, 0, 0, 1, 0, 0],
|
|
|
- createTime: createTime,
|
|
|
- };
|
|
|
+ let geo: LineData = {
|
|
|
+ ...getBaseItem(),
|
|
|
+ lines: [],
|
|
|
+ points: [],
|
|
|
+ polygon: [],
|
|
|
+ attitude: [1, 0, 0, 1, 0, 0],
|
|
|
+ createTime: createTime,
|
|
|
+ };
|
|
|
+
|
|
|
const geoCtx = getInitCtx();
|
|
|
|
|
|
layerResource.geos.forEach((item) => {
|
|
@@ -175,15 +199,9 @@ const drawLayerResource = (
|
|
|
geoCtx.add.points[b!] = p;
|
|
|
geo.points.push(p);
|
|
|
});
|
|
|
- draw.history.onceTrack(() => {
|
|
|
- geo = normalLineData(geo, geoCtx);
|
|
|
- if (sGeo) {
|
|
|
- draw.store.setItem("line", { id: geo.id, value: geo });
|
|
|
- } else {
|
|
|
- draw.store.addItem("line", geo);
|
|
|
- }
|
|
|
- });
|
|
|
+ geo = normalLineData(geo, geoCtx);
|
|
|
|
|
|
+ let thumb: ImageData;
|
|
|
if (layerResource.thumb) {
|
|
|
const box = layerResource.box;
|
|
|
const width = box.bound.x_max - box.bound.x_min;
|
|
@@ -193,7 +211,7 @@ const drawLayerResource = (
|
|
|
box.bound.y_min + height / 2
|
|
|
);
|
|
|
// .rotate(-MathUtils.degToRad(floor.box.rotate));
|
|
|
- const thumb = {
|
|
|
+ thumb = {
|
|
|
...getBaseItem(),
|
|
|
createTime: createTime - 1,
|
|
|
url: layerResource.thumb,
|
|
@@ -202,14 +220,68 @@ const drawLayerResource = (
|
|
|
lock: import.meta.env.DEV ? false : true,
|
|
|
height,
|
|
|
cornerRadius: 0,
|
|
|
+ zIndex: -1
|
|
|
};
|
|
|
images.push(thumb);
|
|
|
}
|
|
|
|
|
|
+ let offset = { x: 0, y: 0 };
|
|
|
+
|
|
|
+ let sGeo = draw.store.getTypeItems("line")[0];
|
|
|
+ if (sGeo?.itemName) {
|
|
|
+ ElMessage.warning("请在画图面板中选择放置位置,按右键取消");
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
+ const data = thumb ? thumb : { url: getSizePlaceBoxImage(bound.get()!) };
|
|
|
+ const key = "place-plaform";
|
|
|
+ draw.enterDrawShape("image", { ...data, key }, true);
|
|
|
+ const stopWatch = watchEffect(() => {
|
|
|
+ if (!draw.drawing) {
|
|
|
+ stopWatch();
|
|
|
+ const item = draw.store.items.find(
|
|
|
+ (item) => item.key === key
|
|
|
+ ) as ImageData;
|
|
|
+
|
|
|
+ if (!item) {
|
|
|
+ reject("用户已取消");
|
|
|
+ } else {
|
|
|
+ draw.store.delItem("image", item.id);
|
|
|
+ offset.x = item.mat[4];
|
|
|
+ offset.y = item.mat[5];
|
|
|
+ resolve();
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ });
|
|
|
+ } else if (sGeo) {
|
|
|
+ sGeo.itemName = "1";
|
|
|
+ } else {
|
|
|
+ geo.itemName = "1";
|
|
|
+ }
|
|
|
+ geo.points.forEach((p) => {
|
|
|
+ p.x += offset.x;
|
|
|
+ p.y += offset.y;
|
|
|
+ });
|
|
|
+
|
|
|
+ if (sGeo) {
|
|
|
+ sGeo.points = sGeo.points.concat(geo.points)
|
|
|
+ sGeo.lines = sGeo.lines.concat(geo.lines)
|
|
|
+ sGeo.polygon = sGeo.polygon.concat(geo.polygon)
|
|
|
+ geo = sGeo
|
|
|
+ draw.store.setItem("line", { id: geo.id, value: geo });
|
|
|
+ } else {
|
|
|
+ draw.store.addItem("line", geo);
|
|
|
+ }
|
|
|
+ if (thumb!) {
|
|
|
+ thumb.mat[4] = offset.x
|
|
|
+ thumb.mat[5] = offset.y
|
|
|
+ }
|
|
|
images.push(
|
|
|
...layerResource.taggings.map((item, ndx) => {
|
|
|
bound.update(item.position);
|
|
|
- const tf = new Transform().translate(item.position.x, item.position.y);
|
|
|
+ const tf = new Transform().translate(
|
|
|
+ item.position.x + offset.x,
|
|
|
+ item.position.y + offset.y
|
|
|
+ );
|
|
|
if (item.rotate) {
|
|
|
tf.rotate(item.rotate);
|
|
|
}
|
|
@@ -245,15 +317,30 @@ const drawLayerResource = (
|
|
|
// ids: [...images, geo.id].map((item) => item.id),
|
|
|
// });
|
|
|
|
|
|
- return bound.get();
|
|
|
+ const box = bound.get()!;
|
|
|
+ return {
|
|
|
+ ...box,
|
|
|
+ x: box.x + offset.x,
|
|
|
+ y: box.y + offset.y,
|
|
|
+ maxX: box.maxX + offset.x,
|
|
|
+ maxY: box.maxY + offset.y,
|
|
|
+ center: {
|
|
|
+ x: box.center.x + offset.x,
|
|
|
+ y: box.center.y + offset.y,
|
|
|
+ }
|
|
|
+ }
|
|
|
};
|
|
|
|
|
|
-export const drawPlatformResource = (data: AIExposeData, draw: Draw) => {
|
|
|
+export const drawPlatformResource = async (data: AIExposeData, draw: Draw) => {
|
|
|
// 默认为米,为了方便绘图 一米转为100
|
|
|
const layers = getResourceLayers(scaleResource(data, 100));
|
|
|
- const layerBounds: ReturnType<typeof drawLayerResource>[] = [];
|
|
|
+ const layerBounds: ReturnType<typeof drawLayerResource> extends Promise<
|
|
|
+ infer T
|
|
|
+ >
|
|
|
+ ? T[]
|
|
|
+ : number[] = [];
|
|
|
|
|
|
- draw.history.onceTrack(() => {
|
|
|
+ await draw.history.onceTrack(async () => {
|
|
|
// draw.store.setConfig({ proportion: { scale: 10, unit: 'mm' } });
|
|
|
draw.store.setConfig({ proportion: { scale: 10, unit: "mm" } });
|
|
|
for (const layer of layers) {
|
|
@@ -261,7 +348,7 @@ export const drawPlatformResource = (data: AIExposeData, draw: Draw) => {
|
|
|
// draw.store.addLayer(layer.name);
|
|
|
// }
|
|
|
// draw.store.setCurrentLayer(layer.name);
|
|
|
- layerBounds.push(drawLayerResource(layer, draw)!);
|
|
|
+ layerBounds.push(await drawLayerResource(layer, draw)!);
|
|
|
}
|
|
|
if (typeof data.compass === "number") {
|
|
|
draw.store.setConfig({
|