bill hace 1 año
padre
commit
9a0571c0e9
Se han modificado 6 ficheros con 1041 adiciones y 1251 borrados
  1. 2 1
      package.json
  2. 819 1093
      pnpm-lock.yaml
  3. 119 100
      src/model/platform.ts
  4. 58 40
      src/sdk/association/setting.ts
  5. 22 0
      src/utils/coord.ts
  6. 21 17
      src/vite-env.d.ts

+ 2 - 1
package.json

@@ -9,12 +9,13 @@
     "preview": "vite preview"
   },
   "dependencies": {
-    "simaqcore": "1.2.0",
     "@vueup/vue-quill": "^1.2.0",
     "ant-design-vue": "^3.3.0-beta.3",
     "axios": "^0.27.2",
+    "coordtransform": "^2.1.2",
     "less": "^4.1.3",
     "mitt": "^3.0.0",
+    "simaqcore": "1.2.0",
     "vite-plugin-mkcert": "^1.10.1",
     "vue": "^3.2.37",
     "vue-cropper": "1.0.2",

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 819 - 1093
pnpm-lock.yaml


+ 119 - 100
src/model/platform.ts

@@ -1,171 +1,190 @@
-import { watchEffect, nextTick } from 'vue'
-import { fuseModelsLoaded, scenes, SceneType, setting } from '@/store'
-import { fuseModel } from './'
-import { initialSDK, initialed as fuseInitialed, sdk as fuseSDK } from '@/sdk'
-import { asyncTimeout } from '@/utils'
+import { watchEffect, nextTick } from "vue";
+import { fuseModelsLoaded, scenes, SceneType, setting } from "@/store";
+import { fuseModel } from "./";
+import { initialSDK, initialed as fuseInitialed, sdk as fuseSDK } from "@/sdk";
+import { asyncTimeout } from "@/utils";
 
-import type { ModelType } from './'
+import type { ModelType } from "./";
+import { aMapToWgs84 } from "@/utils/coord";
 
-export async function modelSDKFactory (
-  type: ModelType, 
+export async function modelSDKFactory(
+  type: ModelType,
   dom: HTMLDivElement | HTMLIFrameElement
 ): Promise<ModelExpose> {
-  console.log(type, dom)
+  console.log(type, dom);
   if (type === fuseModel) {
+    const center = aMapToWgs84({
+      x: setting.value!.lonlat![0],
+      y: setting.value!.lonlat![1],
+    });
+    console.log([center.x, center.y], setting.value!.lonlat);
     if (!fuseInitialed) {
-      await initialSDK({ layout: dom, scenes: scenes.value, lonlat: setting.value!.lonlat })
+      await initialSDK({
+        layout: dom,
+        scenes: scenes.value,
+        lonlat: [center.x, center.y],
+      });
     }
-    return exposeFactory(fuseModel)
+    return exposeFactory(fuseModel);
   } else {
-    const iframe = dom as HTMLIFrameElement
+    const iframe = dom as HTMLIFrameElement;
     const win = await new Promise<Window | null>((resolve, reject) => {
       const loadedHandler = () => {
-        resolve(iframe.contentWindow)
-        cleanup()
-      }
+        resolve(iframe.contentWindow);
+        cleanup();
+      };
       const errorHandler = (err: any) => {
-        reject(err)
-        cleanup()
-      }
+        reject(err);
+        cleanup();
+      };
       const cleanup = () => {
-        iframe.removeEventListener('load', loadedHandler)
-        iframe.removeEventListener('error', errorHandler)
-      }
-      iframe.addEventListener('load', loadedHandler)
-      iframe.addEventListener('error', errorHandler)
-    })
+        iframe.removeEventListener("load", loadedHandler);
+        iframe.removeEventListener("error", errorHandler);
+      };
+      iframe.addEventListener("load", loadedHandler);
+      iframe.addEventListener("error", errorHandler);
+    });
 
     if (!win) {
-      throw new Error('场景加载失败')
+      throw new Error("场景加载失败");
     }
-    return await exposeFactory(type, win)
+    return await exposeFactory(type, win);
   }
 }
 
-
-const findObjectAttr = <T, K extends keyof T>(data: T, key: K): Promise<T[K]> => {
-  return new Promise<T[K]>(resolve => {
+const findObjectAttr = <T, K extends keyof T>(
+  data: T,
+  key: K
+): Promise<T[K]> => {
+  return new Promise<T[K]>((resolve) => {
     const query = () => {
       if (key in data) {
-        resolve(data[key])
+        resolve(data[key]);
       } else {
-        setTimeout(query, 6)
+        setTimeout(query, 6);
       }
-    }
-    query()
-  })
-}
+    };
+    query();
+  });
+};
 
-const fuseLoaded = new Promise<void>(resolve => {
+const fuseLoaded = new Promise<void>((resolve) => {
   const stop = watchEffect(() => {
     if (fuseModelsLoaded.value) {
-      resolve()
-      nextTick(() => stop())
+      resolve();
+      nextTick(() => stop());
     }
-  })
-})
+  });
+});
 
 export interface ModelExpose {
-  getView: () => Promise<{ image: Blob, flyData: string }>
-  setView: (flyData: string) => void
+  getView: () => Promise<{ image: Blob; flyData: string }>;
+  setView: (flyData: string) => void;
 }
 
-export async function exposeFactory(type: ModelType, win?: any): Promise<ModelExpose> {
-  const sceneType = type === fuseModel ? fuseModel : type.type
-  const platforms: {[key in any]: {getSDK: () => Promise<any>, expose: ModelExpose}} = {
+export async function exposeFactory(
+  type: ModelType,
+  win?: any
+): Promise<ModelExpose> {
+  const sceneType = type === fuseModel ? fuseModel : type.type;
+  const platforms: {
+    [key in any]: { getSDK: () => Promise<any>; expose: ModelExpose };
+  } = {
     [fuseModel]: {
       getSDK: async () => {
-        await fuseLoaded
-        return fuseSDK
+        await fuseLoaded;
+        return fuseSDK;
       },
       expose: {
         async getView() {
-          const dataURL = await sdk.screenshot(260, 160)
-          const res = await fetch(dataURL)
-          const image = await res.blob()
-          const pose = sdk.getPose()
+          const dataURL = await sdk.screenshot(260, 160);
+          const res = await fetch(dataURL);
+          const image = await res.blob();
+          const pose = sdk.getPose();
           return {
             image,
-            flyData: JSON.stringify(pose)
-          }
+            flyData: JSON.stringify(pose),
+          };
         },
         async setView(flyData: string) {
-          const pose = JSON.parse(flyData)
-          sdk.comeTo({ dur: 300, ...pose })
-        }
-      }
+          const pose = JSON.parse(flyData);
+          sdk.comeTo({ dur: 300, ...pose });
+        },
+      },
     },
     [SceneType.SWKK]: {
       getSDK: async () => {
-        const sdk = await findObjectAttr(win , '__sdk')
+        const sdk = await findObjectAttr(win, "__sdk");
         if (!sdk.Scene.loaded) {
-          await new Promise(reoslve => sdk.Scene.on('loaded', reoslve))
+          await new Promise((reoslve) => sdk.Scene.on("loaded", reoslve));
         }
-        return sdk
+        return sdk;
       },
       expose: {
         async getView() {
-          const pose = sdk.Camera.getPose()
+          const pose = sdk.Camera.getPose();
           const images = await sdk.Camera.screenshot(
-            [{ width: 260, height: 160, name: '2k' }], 
+            [{ width: 260, height: 160, name: "2k" }],
             true
-          )
+          );
           return {
-            image: images[0].data, 
-            flyData: JSON.stringify(pose)
-          }
+            image: images[0].data,
+            flyData: JSON.stringify(pose),
+          };
         },
         async setView(flyData: string) {
-          const pose = JSON.parse(flyData)
-          sdk.Camera.setPose({ dur: 300, ...pose })
-        }
-      }
+          const pose = JSON.parse(flyData);
+          sdk.Camera.setPose({ dur: 300, ...pose });
+        },
+      },
     },
     [SceneType.SWSS]: {
       getSDK: async () => {
-        await findObjectAttr(win, 'laserLoaded')
-        return await findObjectAttr(win, '__sdk')
+        await findObjectAttr(win, "laserLoaded");
+        return await findObjectAttr(win, "__sdk");
       },
       expose: {
         async getView() {
-          const dataURL = await sdk.scene.screenshot(260, 160)
-          const res = await fetch(dataURL.dataUrl)
-          const image = await res.blob()
-          const pose = await sdk.scene.getPose()
-          const mode = sdk.customMap.mode
+          const dataURL = await sdk.scene.screenshot(260, 160);
+          const res = await fetch(dataURL.dataUrl);
+          const image = await res.blob();
+          const pose = await sdk.scene.getPose();
+          const mode = sdk.customMap.mode;
 
           return {
-            image, 
-            flyData: JSON.stringify({ pose, mode })
-          }
+            image,
+            flyData: JSON.stringify({ pose, mode }),
+          };
         },
         async setView(flyData: string) {
-          const { pose, mode } = JSON.parse(flyData)
-          sdk.customMap.mode  = mode
-          sdk.scene.setPose(pose, 300)
-        }
-      }
-    }
-  }
-  platforms[SceneType.SWYDSS] = platforms[SceneType.SWSS]
-  platforms[SceneType.SWYDMX] = platforms[SceneType.SWSSMX] = platforms[SceneType.SWKJ] = platforms[SceneType.SWKK]
+          const { pose, mode } = JSON.parse(flyData);
+          sdk.customMap.mode = mode;
+          sdk.scene.setPose(pose, 300);
+        },
+      },
+    },
+  };
+  platforms[SceneType.SWYDSS] = platforms[SceneType.SWSS];
+  platforms[SceneType.SWYDMX] =
+    platforms[SceneType.SWSSMX] =
+    platforms[SceneType.SWKJ] =
+      platforms[SceneType.SWKK];
   platforms[SceneType.SWMX] = {
     getSDK: async () => {
-      const sdk = await findObjectAttr(win , '__sdk')
+      const sdk = await findObjectAttr(win, "__sdk");
       // await new Promise(resolve => setTimeout(resolve, 2000))
-      return sdk
+      return sdk;
     },
-    expose: platforms[fuseModel].expose
-  }
+    expose: platforms[fuseModel].expose,
+  };
 
   if (!(sceneType in platforms)) {
-    throw new Error('不支持该类型场景!')
+    throw new Error("不支持该类型场景!");
   }
 
   const sdk: any = await Promise.race([
-    asyncTimeout(100000)
-      .then(() => Promise.reject(new Error('加载超时'))),
-    platforms[sceneType].getSDK()
-  ])
-  return platforms[sceneType].expose
-}
+    asyncTimeout(100000).then(() => Promise.reject(new Error("加载超时"))),
+    platforms[sceneType].getSDK(),
+  ]);
+  return platforms[sceneType].expose;
+}

+ 58 - 40
src/sdk/association/setting.ts

@@ -1,60 +1,78 @@
-import { fuseModelsLoaded, setting } from "@/store"
-import { nextTick, watchEffect } from "vue"
-import { SettingResourceType } from "@/api/setting-resource"
-import { SDK } from "../sdk"
+import { fuseModelsLoaded, setting } from "@/store";
+import { nextTick, watchEffect } from "vue";
+import { SettingResourceType } from "@/api/setting-resource";
+import { SDK } from "../sdk";
+import { aMapToWgs84 } from "@/utils/coord";
 
-
-
-let opened = false
-export const setMap = (sdk: SDK, open: boolean, latlng?: number[], type:string = 'satellite') => {
-  const mapEl = document.querySelector('#scene-map') as HTMLDivElement;
+let opened = false;
+export const setMap = (
+  sdk: SDK,
+  open: boolean,
+  latlng?: number[],
+  type: string = "satellite"
+) => {
+  const mapEl = document.querySelector("#scene-map") as HTMLDivElement;
 
   if (!latlng || !open) {
-    mapEl.style.display = 'none';
+    mapEl.style.display = "none";
     return;
   }
-  mapEl.style.display = 'block';
+  mapEl.style.display = "block";
 
+  const center = aMapToWgs84({ x: latlng[0], y: latlng[1] });
   if (!opened) {
-    sdk.enableMap(mapEl, latlng)
-    opened = true
+    sdk.enableMap(mapEl, [center.x, center.y]);
+    opened = true;
   }
-  sdk.switchMapType(type)
-}
+  sdk.switchMapType(type);
+};
 
-export const setBackdrop = (sdk: SDK, back: string, type: SettingResourceType, tb?: {scale?: number, rotate?: number} ) => {
-  console.log('====>', back, type)
-  tb = type === SettingResourceType.bottomImage && tb ? tb : { scale: 1, rotate: 0 }
-  back = type === SettingResourceType.icon ? 'none' : back
-  console.log(type, back)
-  sdk.setBackdrop(back, type, tb)
-}
+export const setBackdrop = (
+  sdk: SDK,
+  back: string,
+  type: SettingResourceType,
+  tb?: { scale?: number; rotate?: number }
+) => {
+  console.log("====>", back, type);
+  tb =
+    type === SettingResourceType.bottomImage && tb
+      ? tb
+      : { scale: 1, rotate: 0 };
+  back = type === SettingResourceType.icon ? "none" : back;
+  console.log(type, back);
+  sdk.setBackdrop(back, type, tb);
+};
 
 export const associationSetting = (sdk: SDK, mountEl: HTMLDivElement) => {
   watchEffect(() => {
-    setting.value && sdk.setCameraFov(setting.value.fov)
-  })
+    setting.value && sdk.setCameraFov(setting.value.fov);
+  });
+
   watchEffect(() => {
-    setting.value && setMap(sdk, setting.value.mapOpen, setting.value.latlng, setting.value.mapType)
-  })
+    setting.value &&
+      setMap(
+        sdk,
+        setting.value.mapOpen,
+        setting.value.latlng,
+        setting.value.mapType
+      );
+  });
   const stopWatchPose = watchEffect(() => {
-    setting.value && setting.value.pose && sdk.comeTo(setting.value.pose)
-    nextTick(() => stopWatchPose())
-  })
+    setting.value && setting.value.pose && sdk.comeTo(setting.value.pose);
+    nextTick(() => stopWatchPose());
+  });
   watchEffect(() => {
     if (setting.value) {
-      const direEl = document.querySelector('#direction') as HTMLDivElement
-      direEl.style.display = setting.value.openCompass ? 'block' : 'none';
+      const direEl = document.querySelector("#direction") as HTMLDivElement;
+      direEl.style.display = setting.value.openCompass ? "block" : "none";
     }
-  })
+  });
   watchEffect(() => {
     if (setting.value) {
-      setBackdrop(
-        sdk, 
-        setting.value!.back, 
-        setting.value!.backType, 
-        { scale: setting.value!.scale, rotate: setting.value!.rotate}
-      )
+      setBackdrop(sdk, setting.value!.back, setting.value!.backType, {
+        scale: setting.value!.scale,
+        rotate: setting.value!.rotate,
+      });
     }
-  })
-}
+  });
+};

+ 22 - 0
src/utils/coord.ts

@@ -0,0 +1,22 @@
+import libTransform from "coordtransform";
+
+// 84坐标转高德
+export const wgs84ToAMap = (pos: { x: number; y: number }) => {
+  // return proj4(LocalCoord.WGS84, LocalCoord.AMap, { ...pos })
+  // proj4(from, to, { ...pos })
+  const latlng = libTransform.wgs84togcj02(pos.x, pos.y);
+  return {
+    x: latlng[0],
+    y: latlng[1],
+  };
+};
+
+// 高德坐标转84
+export const aMapToWgs84 = (pos: { x: number; y: number }) => {
+  // return proj4(LocalCoord.AMap, LocalCoord.WGS84, { ...pos })
+  const latlng = libTransform.gcj02towgs84(pos.x, pos.y);
+  return {
+    x: latlng[0],
+    y: latlng[1],
+  };
+};

+ 21 - 17
src/vite-env.d.ts

@@ -1,33 +1,37 @@
 /// <reference types="vite/client" />
 
-declare module '*.vue' {
-  import type { DefineComponent } from 'vue'
-  const component: DefineComponent<{}, {}, any>
-  export default component
+declare module "*.vue" {
+  import type { DefineComponent } from "vue";
+  const component: DefineComponent<{}, {}, any>;
+  export default component;
 }
 
+declare module "coordtransform";
+
 type ToChangeAPI<T extends Record<string, any>> = {
-  [key in keyof T as `change${Capitalize<key & string>}`]: (prop: T[key]) => void
-}
+  [key in keyof T as `change${Capitalize<key & string>}`]: (
+    prop: T[key]
+  ) => void;
+};
 
-type SceneLocalPos = { x: number, y: number, z: number }
-type ScreenLocalPos = { x: number, y: number }
+type SceneLocalPos = { x: number; y: number; z: number };
+type ScreenLocalPos = { x: number; y: number };
 
-type LocalFile = { url: string, blob: Blob }
+type LocalFile = { url: string; blob: Blob };
 type LocalMode<T, K> = T extends any[]
   ? LocalMode<T[number], K>[]
   : T extends {}
-    ? K extends keyof T
-      ? T[K] extends string
-        ? Omit<T, K> & { [key in K]: string | LocalFile }
-        : T[K] extends string[]
-          ? Omit<T, K> & { [key in K]: (string | LocalFile)[] }
-          : T
+  ? K extends keyof T
+    ? T[K] extends string
+      ? Omit<T, K> & { [key in K]: string | LocalFile }
+      : T[K] extends string[]
+      ? Omit<T, K> & { [key in K]: (string | LocalFile)[] }
       : T
     : T
+  : T;
 
 type PartialProps<T, U extends keyof T = keyof T> = {
-    [P in keyof Omit<T, U>]: T[P];
+  [P in keyof Omit<T, U>]: T[P];
 } & {
   [P in U]?: T[P];
-}
+};