123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207 |
- import { watchEffect, nextTick } from "vue";
- import {
- fuseModelsLoaded,
- scenes,
- SceneType,
- setting,
- caseProject,
- } from "@/store";
- import { fuseModel } from "./";
- import {
- initialSDK,
- initialed as fuseInitialed,
- sdk as fuseSDK,
- analysisPose,
- analysisPoseInfo,
- setPose,
- } from "@/sdk";
- import { asyncTimeout } from "@/utils";
- import { aMapToWgs84 } from "@/utils/coord";
- import type { ModelType } from "./";
- export async function modelSDKFactory(
- type: ModelType,
- dom: HTMLDivElement | HTMLIFrameElement
- ): Promise<ModelExpose> {
- let center: number[] | undefined = undefined;
- if (caseProject.value) {
- const lonlatStr = caseProject.value?.latAndLong || "22.364093,113.600356";
- const lonlat = lonlatStr.split(",").map(Number);
- const gcenter = aMapToWgs84({
- x: lonlat[1],
- y: lonlat[0],
- });
- center = [gcenter.x, gcenter.y];
- }
- if (type === fuseModel) {
- if (!fuseInitialed) {
- await initialSDK({
- laserRoot: import.meta.env.VITE_LASER_HOST,
- panoOSSRoot: import.meta.env.VITE_PANO_OSS,
- laserOSSRoot: import.meta.env.VITE_LASER_OSS,
- layout: dom,
- scenes: scenes.value,
- lonlat: center,
- });
- }
- return exposeFactory(fuseModel);
- } else {
- const iframe = dom as HTMLIFrameElement;
- const win = await new Promise<Window | null>((resolve, reject) => {
- const loadedHandler = () => {
- resolve(iframe.contentWindow);
- cleanup();
- };
- const errorHandler = (err: any) => {
- reject(err);
- cleanup();
- };
- const cleanup = () => {
- iframe.removeEventListener("load", loadedHandler);
- iframe.removeEventListener("error", errorHandler);
- };
- iframe.addEventListener("load", loadedHandler);
- iframe.addEventListener("error", errorHandler);
- });
- if (!win) {
- throw new Error("场景加载失败");
- }
- return await exposeFactory(type, win);
- }
- }
- const findObjectAttr = <T extends {}, 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]);
- } else {
- setTimeout(query, 6);
- }
- };
- query();
- });
- };
- const fuseLoaded = new Promise<void>((resolve) => {
- const stop = watchEffect(() => {
- if (fuseModelsLoaded.value) {
- resolve();
- nextTick(() => stop());
- }
- });
- });
- export interface ModelExpose {
- 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 };
- } = {
- [fuseModel]: {
- getSDK: async () => {
- 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 = analysisPose(sdk.getPose());
- return {
- image,
- flyData: JSON.stringify(pose),
- };
- },
- async setView(flyData: string) {
- console.error(JSON.parse(flyData));
- setPose(JSON.parse(flyData), sdk);
- },
- },
- },
- [SceneType.SWKK]: {
- getSDK: async () => {
- const sdk = await findObjectAttr(win, "__sdk");
- if (!sdk.Scene.loaded) {
- await new Promise((reoslve) => sdk.Scene.on("loaded", reoslve));
- }
- return sdk;
- },
- expose: {
- async getView() {
- const pose = sdk.Camera.getPose();
- const images = await sdk.Camera.screenshot(
- [{ width: 260, height: 160, name: "2k" }],
- true
- );
- return {
- image: images[0].data,
- flyData: JSON.stringify(pose),
- };
- },
- async setView(flyData: string) {
- const pose = JSON.parse(flyData);
- sdk.Camera.setPose({ dur: 300, ...pose });
- },
- },
- },
- [SceneType.SWSS]: {
- getSDK: async () => {
- 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;
- return {
- 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];
- platforms[SceneType.SWMX] = {
- getSDK: async () => findObjectAttr(win, "__sdk"),
- expose: platforms[fuseModel].expose,
- };
- if (!(sceneType in platforms)) {
- throw new Error("不支持该类型场景!");
- }
- const sdk: any = await Promise.race([
- asyncTimeout(100000).then(() => Promise.reject(new Error("加载超时"))),
- platforms[sceneType].getSDK(),
- ]);
- return platforms[sceneType].expose;
- }
|