sdk.ts 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393
  1. import cover from "./cover/index";
  2. import { createLoadPack, loadLib } from "@/utils";
  3. import {
  4. FuseModelAttrs,
  5. FuseModel,
  6. GuidePath,
  7. MeasureType,
  8. Measure as StoreMeasure,
  9. MeasurePosition,
  10. SceneType,
  11. scenes,
  12. Scene,
  13. } from "@/store";
  14. import type { Emitter } from "mitt";
  15. import { TaggingPositionType } from "@/api";
  16. export enum SettingResourceType {
  17. map = "map",
  18. color = "color",
  19. envImage = "img",
  20. bottomImage = "bimg",
  21. icon = "icon",
  22. }
  23. type SceneModelAttrs = FuseModelAttrs & { select: boolean };
  24. export type SceneModel = ToChangeAPI<SceneModelAttrs> & {
  25. bus: Emitter<
  26. Pick<SceneModelAttrs, "select"> & {
  27. loadError: void;
  28. loadDone: void;
  29. loadProgress: number;
  30. changeSelect: boolean;
  31. transformChanged: {
  32. position?: SceneLocalPos;
  33. scale?: number;
  34. rotation?: SceneLocalPos;
  35. bottom?: number;
  36. };
  37. }
  38. >;
  39. destroy: () => void;
  40. enterRotateMode: () => void;
  41. enterMoveMode: () => void;
  42. leaveTransform: () => void;
  43. getDefaultRotation: () => SceneLocalPos
  44. enterAlignment: () => void;
  45. leaveAlignment: () => void;
  46. enterScaleSet: () => ScaleSet;
  47. leaveScaleSet: () => void;
  48. supportPano: () => boolean;
  49. flyInPano: () => void;
  50. flyOutPano: () => void;
  51. };
  52. export interface ScaleSet {
  53. setLength: (length: number) => void;
  54. startMeasure: () => void;
  55. }
  56. export type ModelAttrRange = {
  57. [key in "opacity" | "bottom" | "scale" as `${key}Range`]: {
  58. min: number;
  59. max: number;
  60. step: number;
  61. };
  62. };
  63. export type AddModelProps = Pick<FuseModel, "url" | "id"> &
  64. FuseModelAttrs & {
  65. type: string;
  66. isDynamicAdded: boolean;
  67. mode: "many" | "single";
  68. fromType: any;
  69. } & ModelAttrRange;
  70. export type SceneGuidePath = Pick<GuidePath, "speed" | "time"> & Pose;
  71. export interface SceneGuide {
  72. bus: Emitter<{ changePoint: number; playComplete: void }>;
  73. play: () => void;
  74. pause: () => void;
  75. clear: () => void;
  76. }
  77. export type ScenePos = { localPos: SceneLocalPos; modelId: FuseModel["id"] };
  78. export type ScreenPos = {
  79. trueSide: boolean;
  80. pos: ScreenLocalPos;
  81. modelId: FuseModel["id"];
  82. };
  83. export interface CameraComeToProps {
  84. position: SceneLocalPos;
  85. target?: SceneLocalPos;
  86. dur?: number;
  87. modelId?: FuseModel["id"];
  88. distance?: 1 | 2 | 3;
  89. maxDis?:number
  90. isFlyToTag?: boolean
  91. }
  92. export type CalcPathProps = [
  93. [SceneGuidePath, SceneGuidePath],
  94. Partial<Pick<SceneGuidePath, "time" | "speed">>
  95. ];
  96. export interface MeasureBase {
  97. destroy?: () => void;
  98. show: () => void;
  99. hide: () => void;
  100. fly: () => void;
  101. bus: Emitter<{
  102. update: [MeasurePosition["point"][], MeasurePosition["modelId"][]];
  103. highlight: boolean;
  104. }>;
  105. changeSelect: (isHight: boolean) => void;
  106. setPositions: (
  107. points: MeasurePosition["point"][],
  108. modelIds: MeasurePosition["modelId"][]
  109. ) => void;
  110. }
  111. export type Measure<T extends StoreMeasure["type"] = StoreMeasure["type"]> =
  112. MeasureBase &
  113. (T extends MeasureType.area
  114. ? { getArea: () => { value: number } }
  115. : { getDistance: () => { value: number } });
  116. export type StartMeasure<T extends StoreMeasure["type"]> = Measure<T> & {
  117. bus: Emitter<{
  118. submit: [MeasurePosition["point"][], MeasurePosition["modelId"][]];
  119. cancel: void;
  120. invalidPoint: string;
  121. }>;
  122. };
  123. export type Pose =
  124. | {
  125. position: SceneLocalPos;
  126. target: SceneLocalPos;
  127. }
  128. | {
  129. panoId: any;
  130. model: SceneModel;
  131. posInModel: SceneLocalPos;
  132. rotInModel: SceneLocalPos;
  133. position: SceneLocalPos;
  134. target: SceneLocalPos;
  135. };
  136. export interface SDK {
  137. layout: HTMLDivElement;
  138. sceneBus: Emitter<{
  139. cameraChange: SceneLocalPos;
  140. panoModelChange: SceneModel;
  141. modeChange: { mode: "pano" | "fuse"; active: SceneModel };
  142. }>;
  143. setBackdrop: (
  144. drop: string,
  145. type: SettingResourceType,
  146. tb: { scale?: number; rotate?: number }
  147. ) => void;
  148. switchScene: (
  149. scene: { type: SceneType; num: string } | null
  150. ) => Promise<void>;
  151. startAddSth: () => void
  152. endAddSth: () => void
  153. addModel: (props: AddModelProps) => SceneModel;
  154. setCameraFov: (fov: number) => void;
  155. enableMap(dom: HTMLDivElement, latlng: number[]): void;
  156. switchMapType: (type: string, mapType: string) => void;
  157. showGrid: () => void;
  158. compassVisibility: (visibility: boolean) => void;
  159. canTurnToPanoMode: () => { model: SceneModel };
  160. hideGrid: () => void;
  161. calcPathInfo: (
  162. paths: CalcPathProps[0],
  163. info: CalcPathProps[1]
  164. ) => Required<CalcPathProps[1]>;
  165. getPositionByScreen: (
  166. screenPos: ScreenLocalPos,
  167. modelId?: FuseModel["id"]
  168. ) => (ScenePos & { worldPos: SceneLocalPos, localNormal: SceneLocalPos }) | null;
  169. getScreenByPosition: (
  170. localPos: SceneLocalPos,
  171. modelId?: FuseModel["id"]
  172. ) => ScreenPos | null;
  173. screenshot: (width: number, height: number) => Promise<string>;
  174. getPose: () => Pose;
  175. comeTo: (pos: CameraComeToProps) => void;
  176. enterSceneGuide: (data: SceneGuidePath[]) => SceneGuide;
  177. drawMeasure<T extends StoreMeasure["type"]>(
  178. type: T,
  179. points: MeasurePosition["point"][],
  180. modelIds: MeasurePosition["modelId"][]
  181. ): Measure<T>;
  182. startMeasure<T extends StoreMeasure["type"]>(type: T): StartMeasure<T>;
  183. createTagging: (props: Tagging3DProps) => Tagging3D
  184. createPath: (props: PathProps) => Path
  185. }
  186. export type PathProps = {
  187. // 线段名称
  188. name: string,
  189. // 是否显示名称,
  190. showName: boolean,
  191. // 文字大小
  192. fontSize: number,
  193. // 是否显示方向,
  194. showDirection: boolean,
  195. // 方向是否反向
  196. reverseDirection: boolean,
  197. line: {
  198. width: number,
  199. color: string,
  200. altitudeAboveGround: number
  201. position?: SceneLocalPos,
  202. modelId?: string
  203. },
  204. points: {
  205. // 点位名称
  206. name: string,
  207. position: SceneLocalPos,
  208. modelId: string,
  209. }[]
  210. }
  211. export type Path = {
  212. bus: Emitter<{
  213. changeLineHeight: number
  214. activePoint: number
  215. // 标注点击事件
  216. click: void;
  217. // 鼠标移入标注事件
  218. enter: void;
  219. // 鼠标移出标注事件
  220. leave: void;
  221. // 线段坐标更改事件
  222. linePositionChange: {
  223. pos: SceneLocalPos,
  224. modelId: string
  225. }
  226. focus: boolean
  227. // 路径点位置变更
  228. changePoints: PathProps['points']
  229. drawed: void
  230. }>;
  231. changeDirection: ( show: boolean, reverse: boolean ) => void
  232. changeFontSize: (fontSize: number) => void
  233. focus: (f: boolean) => void
  234. highlight: (f: boolean) => void;
  235. changeVisibilityRange: (range: number) => void
  236. changePointName: (index: number, name: string) => void
  237. // 飞向路径
  238. fly: () => void,
  239. // 更改路径点
  240. changePathPoints: (points: Omit<PathProps['points'][number], 'name'>[]) => void
  241. // 播放路径,相机沿着路径运动,传入播放完毕回调
  242. play: (playedHandler: () => void) => void
  243. // 停止播放路径
  244. pause: () => void
  245. // 是否可编辑
  246. changeCanEdit: (canMove: boolean) => void
  247. deletePoint: (index: number) => void
  248. changeEditMode: (editMode: boolean) => void
  249. // 可见性
  250. visibility: (visibility: boolean) => void
  251. // 气泡是否可见
  252. visibilityName: (visibility: boolean) => void
  253. // 更改标题气泡属性
  254. changeLine: (props: Partial<PathProps['line']>) => void
  255. // 更改标题气泡属性
  256. changeName: (name: string) => void
  257. // 线段销毁
  258. destroy: () => void
  259. }
  260. export type Tagging3DProps = {
  261. lineHeight: number
  262. fontSize: number,
  263. // 标题
  264. title: string
  265. // 标注类型 2d | 3d
  266. type: TaggingPositionType,
  267. // 模型id
  268. modelId: string,
  269. // 贴地射线获取的位置
  270. position: SceneLocalPos
  271. normal: SceneLocalPos
  272. // 是否可以移动
  273. canMove: boolean,
  274. // 贴地图片url
  275. image: string
  276. // 贴地图片的变换
  277. mat: {
  278. scale: number,
  279. rotation: number,
  280. }
  281. }
  282. export type Tagging3D = {
  283. bus: Emitter<{
  284. // 标注点击事件
  285. click: void;
  286. // 鼠标移入标注事件
  287. enter: void;
  288. // 鼠标移出标注事件
  289. leave: void;
  290. // 位置变更
  291. changePosition: {pos: SceneLocalPos, modelId: string, normal: SceneLocalPos}
  292. }>;
  293. changePosition: (position: {
  294. modelId: string,
  295. // 贴地射线获取的位置
  296. position: SceneLocalPos
  297. normal: SceneLocalPos
  298. }) => void
  299. changeFontSize: (fontSize: number) => void
  300. changeLineHeight: (lineHeight: number) => void
  301. // 设置标题
  302. changeTitle: (title: string) => void
  303. // 标题是否可见
  304. visibilityTitle: (visibility: boolean) => void
  305. // 更改可拖拽移动
  306. changeCanMove: (canMove: boolean) => void
  307. // 获取图标中心三维坐标
  308. getImageCenter: () => SceneLocalPos
  309. // 更改图标
  310. changeImage: (url: string) => void
  311. // 标注可见性
  312. visibility: (visibility: boolean) => void
  313. // 标注图片变换,传入变换
  314. changeMat: (props: Tagging3DProps['mat']) => void
  315. // 更改热点类型
  316. changeType: (val: TaggingPositionType) => void
  317. // 距离相机位置
  318. getCameraDisSquared: () => number
  319. // 标注销毁
  320. destory: () => void
  321. }
  322. export let sdk: SDK;
  323. export type InialSDKProps = {
  324. laserRoot?: string
  325. ossRoot?: string
  326. laserOSSRoot?: string
  327. panoOSSRoot?: string
  328. layout: HTMLDivElement;
  329. scenes: Scene[];
  330. lonlat?: number[];
  331. };
  332. export let initialed = false;
  333. export const initialSDK = async (props: InialSDKProps) => {
  334. if (initialed) return sdk;
  335. initialed = true;
  336. const libs = [
  337. `./lib/proj4/proj4.js`,
  338. `./lib/jquery/jquery-3.1.1.min.js`,
  339. `./lib/other/BinaryHeap.js`,
  340. `./lib/tween/tween.min.js`,
  341. `./lib/plasio/js/laslaz.js`,
  342. `./lib/plasio/vendor/bluebird.js`,
  343. `./lib/plasio/workers/laz-loader-worker.js`,
  344. `./lib/plasio/workers/laz-perf.js`,
  345. `./lib/Cesium/Cesium.js`,
  346. `./lib/shapefile/shapefile.js`,
  347. ];
  348. await Promise.all(libs.map(loadLib));
  349. await loadLib(`./lib/potree/potree.js`);
  350. console.log(props);
  351. const localSdk = cover({
  352. ...props,
  353. dom: props.layout,
  354. isLocal: false,
  355. scenes: props.scenes,
  356. lonlat: props.lonlat,
  357. mapDom: null,
  358. } as any) as unknown as SDK;
  359. (window as any).sdk = sdk = localSdk;
  360. sdk.layout = props.layout;
  361. return sdk;
  362. };
  363. export default sdk!;