Browse Source

添加场景类型

bill 11 tháng trước cách đây
mục cha
commit
fb6c5f58b9

+ 1 - 1
.env.development

@@ -1,3 +1,3 @@
 VITE_QJ_URL=https://test.4dkankan.com/panorama
 VITE_LASER_URL=https://uat-laser.4dkankan.com/4pc
-VITE_API=https://uat-sp.4dkankan.com/
+VITE_API=https://uat-sp.4dkankan.com/api

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 9 - 2
src/lib/board/4dmap.d.ts


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 1024 - 984
src/lib/board/4dmap.js


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 6 - 6
src/lib/board/4dmap.umd.cjs


+ 3 - 2
src/request/type.ts

@@ -4,7 +4,7 @@ import {
   relicsTypeDesc,
   creationMethodDesc,
 } from "@/store/relics";
-import { SceneStatus } from "@/store/scene";
+import { SceneStatus, SceneType } from "@/store/scene";
 import { PointTypeEnum } from "drawing-board";
 
 type UserInfoRoles = {
@@ -53,6 +53,7 @@ export type ScenePoint = {
   tbStatus: number;
   createTime: string;
   updateTime: string;
+  sceneType: SceneType
   cameraType: DeviceType;
   index: number;
   id: number;
@@ -131,7 +132,7 @@ export type Scene = {
   scenePos: ScenePoint[];
   algorithmTime: string;
   endTime: string;
-  sceneSource: 0;
+  sceneSource: SceneType;
   datasets: Dataset[];
   snCode: string;
   startTime: string;

+ 13 - 4
src/store/scene.ts

@@ -2,7 +2,7 @@ import { relicsScenesFetch, updateRelicsScenePosNameFetch } from "@/request";
 import { computed, ref, watch } from "vue";
 import { Scene, ScenePoint } from "@/request/type";
 import { relics } from "./relics";
-import { DeviceType, DeviceType as SceneType } from "./device";
+import { DeviceType } from "./device";
 import { conversionFactory } from "@/helper/coord-transform";
 import { getTokenFetch } from "@/request";
 import {
@@ -39,7 +39,11 @@ export const getPointPano = (point: ScenePoint, tile = false) => {
         `https://4dkk.4dage.com/scene_view_data/${point.sceneCode}/images/tiles/4k/${point.uuid}_skybox${i}.jpg`
     );
   } else if (point.cameraType === DeviceType.VR) {
-    return `https://4dkankan.oss-cn-shenzhen.aliyuncs.com/scene_view_data/${point.sceneCode}/images/panoramas/${point.uuid}.jpg`;
+    if (point.sceneType === SceneType.VR) {
+      return `https://4dkankan.oss-cn-shenzhen.aliyuncs.com/scene_view_data/${point.sceneCode}/images/panoramas/${point.uuid}.jpg`;
+    } else {
+      return `https://4dkk.4dage.com/scene_result_data/${point.sceneCode}/caches/images/${point.uuid}.jpg`
+    }
   } else if (point.cameraType === DeviceType.CLUNT) {
     return `https://4dkk.4dage.com/scene_view_data/${point.sceneCode}/images/pan/high/${point.uuid}.jpg`;
   }
@@ -86,7 +90,6 @@ export const refreshScenes = async () => {
             let center = scenesTransform[pos.sceneCode]?.translate || [0, 0, 0];
             let rotate = scenesTransform[pos.sceneCode]?.rotate || 0;
             let [x, y, z] = pos.location;
-            console.log(pos.location);
             const cos = Math.cos(rotate);
             const sin = Math.sin(rotate);
             x = x * cos - y * sin + center[0];
@@ -96,6 +99,7 @@ export const refreshScenes = async () => {
           }
           return {
             ...pos,
+            sceneType: scene.sceneSource,
             pos: coord,
           };
         }),
@@ -142,10 +146,15 @@ export enum SceneStatus {
   // RERUN = 4,
 }
 
-export { SceneType };
+export enum SceneType {
+  VR = 6,
+  CLUNT = 5,
+  MESH = 3
+}
 export const SceneTypeDesc: { [key in SceneType]: string } = {
   [SceneType.VR]: "全景VR",
   [SceneType.CLUNT]: "点云场景",
+  [SceneType.MESH]: "mesh场景",
 };
 
 export const SceneStatusDesc: { [key in SceneStatus]: string } = {

+ 2 - 2
src/util/gl.ts

@@ -217,6 +217,7 @@ export const createFPSCamera = (
   let pitch = initView.pitch || 0;
   // 偏航角
   let yaw = initView.yaw || -Math.PI / 2;
+  yaw = Math.PI
 
   const cameraMat = mat4.identity(mat4.create());
   const updateCameraMat = () => {
@@ -228,7 +229,6 @@ export const createFPSCamera = (
     front[0] = Math.cos(pitch) * Math.cos(yaw);
     front[1] = Math.sin(pitch);
     front[2] = Math.cos(pitch) * Math.sin(yaw);
-    // console.log(pitch, yaw);
     vec3.normalize(front, front);
     vec3.cross(up, vec3.cross(vec3.create(), front, worldUp), front);
   };
@@ -286,7 +286,7 @@ export const createFPSCamera = (
     recovery() {
       vec3.copy(eys, vec3.fromValues(initEys[0], initEys[1], initEys[2]));
       pitch = initView.pitch || 0;
-      yaw = initView.yaw || -Math.PI / 2;
+      yaw = initView.yaw || 0;
       updateFront();
       updateCameraMat();
     },

+ 62 - 0
src/util/image.ts

@@ -0,0 +1,62 @@
+import { getTextBound, toDegrees } from ".";
+
+const canvas = document.createElement("canvas");
+// 水印添加函数
+export const addWatermark = (imgURL: string, pos: number[], ration: number) => {
+  const ctx = canvas.getContext("2d");
+  const image = new Image();
+  image.src = imgURL;
+  image.crossOrigin = 'anonymous';
+
+  return new Promise<Blob>((resolve, reject) => {
+    image.onload = () => {
+      canvas.width = image.width;
+      canvas.height = image.height;
+      ctx.drawImage(image, 0, 0, image.width, image.height);
+
+      const font = `${ration * 20}px Arial`;
+      const lines = `经度: ${toDegrees(pos[0])}\n纬度: ${toDegrees(pos[1])}`.split("\n");
+      const lineTopPadding = 5 * ration;
+      const lineBounds = lines.map((line) =>
+        getTextBound(line, font, [lineTopPadding, 0])
+      );
+      const bound = lineBounds.reduce(
+        (t, { width, height }) => {
+          t.width = Math.max(t.width, width);
+          t.height += height;
+          return t;
+        },
+        { width: 0, height: 0 }
+      );
+      const padding = 20 * ration;
+      const margin = 80 * ration;
+
+      const position = [
+        image.width - margin - bound.width,
+        image.height - margin - bound.height,
+      ];
+
+      ctx.rect(
+        position[0] - padding,
+        position[1] - padding,
+        bound.width + 2 * padding,
+        bound.height + 2 * padding
+      );
+      ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
+      ctx.fill();
+
+      ctx.font = font;
+      ctx.textBaseline = "top";
+      ctx.fillStyle = "#fff";
+      let itemTop = 0;
+      lines.forEach((line, ndx) => {
+        ctx.fillText(line, position[0], position[1] + itemTop + lineTopPadding);
+        itemTop += lineBounds[ndx].height;
+      });
+      canvas.toBlob(blob => {
+        resolve(blob)
+      }, "image/jpg", 1)
+    };
+    image.onerror = reject;
+  });
+};

+ 10 - 3
src/view/map/pc4Helper.ts

@@ -11,6 +11,7 @@ import {
 } from "@/util/pc4xlsl";
 import { noValidPoint } from "./install";
 import { PointTypeEnum } from "@/lib/board/4dmap";
+import { addWatermark } from "@/util/image";
 
 export const exportFile = async (
   points: ScenePoint[],
@@ -73,9 +74,15 @@ export const exportImage = async (points: ScenePoint[], name?: string) => {
 
   const downloadImages = Promise.all(
     points.map((point) => {
-      const url = getPointPano(point);
-      return fetch(url as string)
-        .then((res) => res.blob())
+      const url = getPointPano(point) as string;
+      let loadBlob: Promise<Blob>
+      if (noValidPoint(point.pos as any)) {
+        const ration = 6;
+        loadBlob = addWatermark(url, point!.pos, ration)
+      } else {
+        loadBlob = fetch(url).then(res => res.blob())
+      }
+      return loadBlob
         .then((blob) => {
           imgFolder.file(`${point.sceneCode}-${point.uuid}.jpg`, blob);
         })

+ 1 - 1
src/view/pano/env.ts

@@ -134,7 +134,7 @@ export const init = (canvas: HTMLCanvasElement) => {
     },
     [0, 1, 0],
     [0, 0, 0],
-    { yaw: glMatrix.toRadian(-180) },
+    { yaw: glMatrix.toRadian(0) },
     80
   );
   return {

+ 3 - 61
src/view/pano/pano.vue

@@ -56,6 +56,7 @@ import saveAs from "@/util/file-serve";
 import { DeviceType } from "@/store/device";
 import { initRelics, relics } from "@/store/relics";
 import { noValidPoint } from "../map/install";
+import { addWatermark } from "@/util/image";
 
 type Params = { pid?: string; relicsId?: string } | null;
 const params = computed(() => router.currentRoute.value.params as Params);
@@ -99,73 +100,14 @@ const copyGis = async () => {
   ElMessage.success("经纬度高程复制成功");
 };
 
-const canvas = document.createElement("canvas");
-// 水印添加函数
-const addWatermark = (imgURL: string, ration: number) => {
-  const ctx = canvas.getContext("2d");
-  const image = new Image();
-  image.src = imgURL;
-
-  return new Promise<string>((resolve, reject) => {
-    image.onload = () => {
-      canvas.width = image.width;
-      canvas.height = image.height;
-      ctx.drawImage(image, 0, 0, image.width, image.height);
-
-      const font = `${ration * 20}px Arial`;
-      const pos = point.value!.pos as number[];
-      const lines = `经度: ${toDegrees(pos[0])}\n纬度: ${toDegrees(pos[1])}`.split("\n");
-      const lineTopPadding = 5 * ration;
-      const lineBounds = lines.map((line) =>
-        getTextBound(line, font, [lineTopPadding, 0])
-      );
-      const bound = lineBounds.reduce(
-        (t, { width, height }) => {
-          t.width = Math.max(t.width, width);
-          t.height += height;
-          return t;
-        },
-        { width: 0, height: 0 }
-      );
-      const padding = 20 * ration;
-      const margin = 80 * ration;
-
-      const position = [
-        image.width - margin - bound.width,
-        image.height - margin - bound.height,
-      ];
-
-      ctx.rect(
-        position[0] - padding,
-        position[1] - padding,
-        bound.width + 2 * padding,
-        bound.height + 2 * padding
-      );
-      ctx.fillStyle = "rgba(0, 0, 0, 0.3)";
-      ctx.fill();
-
-      ctx.font = font;
-      ctx.textBaseline = "top";
-      ctx.fillStyle = "#fff";
-      let itemTop = 0;
-      lines.forEach((line, ndx) => {
-        ctx.fillText(line, position[0], position[1] + itemTop + lineTopPadding);
-        itemTop += lineBounds[ndx].height;
-      });
-      resolve(canvas.toDataURL("image/jpg", 1));
-    };
-    image.onerror = reject;
-  });
-};
-
 const photo = async () => {
   loading.value = true;
   await new Promise((resolve) => setTimeout(resolve, 300));
   const ration = 3;
   setSize(ration, 1920, 1080);
-  let dataURL = panoDomRef.value.toDataURL("image/jpg", 1);
+  let dataURL: Blob | string = panoDomRef.value.toDataURL("image/jpg", 1);
   if (!noValidPoint(point.value)) {
-    dataURL = await addWatermark(dataURL, ration);
+    dataURL = await addWatermark(dataURL, point.value!.pos, ration);
   }
 
   await saveAs(dataURL, `${relics.value?.name}.jpg`);

+ 58 - 14
src/view/scene.vue

@@ -4,23 +4,50 @@
       <div class="search">
         <el-form label-width="100px" inline>
           <el-form-item label="场景标题:">
-            <el-input clearable v-model="pageProps.sceneName" style="width: 250px" placeholder="请输入" />
+            <el-input
+              clearable
+              v-model="pageProps.sceneName"
+              style="width: 250px"
+              placeholder="请输入"
+            />
           </el-form-item>
           <el-form-item label="场景码:">
-            <el-input clearable v-model="pageProps.sceneCode" style="width: 250px" placeholder="请输入" />
+            <el-input
+              clearable
+              v-model="pageProps.sceneCode"
+              style="width: 250px"
+              placeholder="请输入"
+            />
           </el-form-item>
           <template v-if="!simple">
             <el-form-item label="SN码:">
-              <el-input clearable v-model="pageProps.snCode" style="width: 250px" placeholder="请输入" />
+              <el-input
+                clearable
+                v-model="pageProps.snCode"
+                style="width: 250px"
+                placeholder="请输入"
+              />
             </el-form-item>
             <el-form-item label="设备类型:">
               <el-select style="width: 250px" v-model="pageProps.cameraType" clearable>
-                <el-option :value="Number(key)" :label="type" v-for="(type, key) in DeviceTypeDesc" />
+                <el-option
+                  :value="Number(key)"
+                  :label="type"
+                  v-for="(type, key) in DeviceTypeDesc"
+                />
               </el-select>
             </el-form-item>
             <el-form-item label="拍摄时间:">
-              <el-date-picker clearable type="daterange" v-model="pageProps.shootTime" start-placeholder="请选择"
-                end-placeholder="请选择" range-separator="-" placeholder="请选择" style="width: 250px" />
+              <el-date-picker
+                clearable
+                type="daterange"
+                v-model="pageProps.shootTime"
+                start-placeholder="请选择"
+                end-placeholder="请选择"
+                range-separator="-"
+                placeholder="请选择"
+                style="width: 250px"
+              />
             </el-form-item>
             <!-- <el-form-item label="绑定账号:">
               <el-input
@@ -42,8 +69,13 @@
     </div>
 
     <div class="relics-content">
-      <el-table :data="sceneArray" border row-key="'sceneCode'" @selection-change="handleTableSelect"
-        :ref="(d) => { tableProps && ((tableProps as any).tableRef.value = d) }">
+      <el-table
+        :data="sceneArray"
+        border
+        row-key="'sceneCode'"
+        @selection-change="handleTableSelect"
+        :ref="(d) => { tableProps && ((tableProps as any).tableRef.value = d) }"
+      >
         <slot name="table"></slot>
         <el-table-column label="场景标题" v-slot:default="{ row }">
           <a class="link" @click="gotoScene(row, false)">
@@ -52,7 +84,8 @@
         </el-table-column>
 
         <el-table-column label="场景类型" v-slot:default="{ row }">
-          <TexToolTip :text="SceneTypeDesc[row.cameraType as SceneType]" />
+          {{ row.sceneSource }}
+          <TexToolTip :text="SceneTypeDesc[row.sceneSource as SceneType]" />
         </el-table-column>
         <el-table-column label="场景码" v-slot:default="{ row }">
           <TexToolTip :text="row.sceneCode" />
@@ -92,8 +125,13 @@
             <el-button link type="primary" size="small" @click="gotoScene(row, true)">
               编辑
             </el-button>
-            <el-button link type="danger" @click="delHandler(row.sceneId)" size="small"
-              v-if="row.calcStatus !== SceneStatus.RUN">
+            <el-button
+              link
+              type="danger"
+              @click="delHandler(row.sceneId)"
+              size="small"
+              v-if="row.calcStatus !== SceneStatus.RUN"
+            >
               删除
             </el-button>
           </template>
@@ -101,9 +139,15 @@
       </el-table>
     </div>
     <div class="pag-layout">
-      <el-pagination background layout="total, prev, pager, next, sizes, jumper" v-model:page-size="pageProps.pageSize"
-        :page-sizes="[10, 20, 50, 100]" :total="total" @current-change="(data: number) => pageProps.pageNum = data"
-        :current-page="pageProps.pageNum" />
+      <el-pagination
+        background
+        layout="total, prev, pager, next, sizes, jumper"
+        v-model:page-size="pageProps.pageSize"
+        :page-sizes="[10, 20, 50, 100]"
+        :total="total"
+        @current-change="(data: number) => pageProps.pageNum = data"
+        :current-page="pageProps.pageNum"
+      />
     </div>
   </div>
 </template>

+ 1 - 1
vite.config.ts

@@ -43,7 +43,7 @@ export default ({ mode }: any) =>
           target: loadEnv(mode, process.cwd()).VITE_API,
           // target: `http://192.168.0.11:8324/relics/`,
           changeOrigin: true,
-          rewrite: (path) => path.replace(/^\/api/, "/api"),
+          rewrite: (path) => path.replace(/^\/api/, ""),
         },
         // "/api": {
         //   target: `https://uat-sp.4dkankan.com/`,