enter.js 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078
  1. import parameter from "./parameter";
  2. import mitt from "mitt";
  3. import {
  4. CoordType
  5. }
  6. from "../../types";
  7. import {
  8. Loading
  9. }
  10. from "@kankan/components/index";
  11. import revision from "./REVISION";
  12. import {
  13. ui18n
  14. }
  15. from "@/lang";
  16. import libTransform from "coordtransform";
  17. //交通版laser 主要适用设备:MatePad Pro 11英寸
  18. var CloneJson = function (data) {
  19. var str = JSON.stringify(data);
  20. return JSON.parse(str);
  21. };
  22. var enter = ({
  23. dom,
  24. mapDom,
  25. number,
  26. //datasetId, //初始数据集
  27. webSite, //废弃,改为用dataset.webBin
  28. isLocal = false,
  29. basePath,
  30. isDebug = false,
  31. mapCompany, // 地图版本 'default' | 'google' default就跟现在一样
  32. axios,
  33. version, //'V3''V4' 废弃,改为从getDataset获取
  34. staticPrefix,
  35. cropArgs,
  36. getFileUrl,
  37. }) => {
  38. let isScreenshoting = false;
  39. let lastSiteModelData;
  40. let page; //所在页面
  41. const sceneBus = mitt();
  42. Potree.settings.isOfficial = true; //标记为正式、非测试版本
  43. Potree.settings.isDebug = isDebug;
  44. //Potree.settings.originDatasetId = datasetId;
  45. /*if (isLocal) {
  46. //本地配置
  47. Potree.settings.isLocal = isLocal;
  48. for (let i in Potree.settings.urls) {
  49. Potree.settings.urls[i] = basePath; //全部替换
  50. }
  51. }
  52. webSite && (Potree.settings.webSite = webSite);
  53. //axios && (Potree.fileServer = axios); //暂时不用,比如vision那里
  54. if (staticPrefix) {
  55. // "/dev/SS-t-4pMXagRDjk"
  56. Potree.settings.isLocal = true;
  57. Potree.settings.urls.prefix1 = Potree.settings.urls.prefix3 = staticPrefix;
  58. Potree.settings.webSite = "wwwroot";
  59. } */
  60. Potree.getFileUrl = getFileUrl //转化为另一种得到url的方法
  61. Potree.start(dom, mapDom, number);
  62. parameter.dom = dom;
  63. parameter.number = number;
  64. parameter.viewer = viewer;
  65. parameter.sceneBus = sceneBus;
  66. //Potree.settings.rotAroundPoint = false; //试验
  67. sceneBus.on("visible", (v) => {
  68. viewer.visible = v;
  69. /* if(v){
  70. viewer.dispatchEvent('content_changed') //避免白屏
  71. } */
  72. //console.log('sceneBus visible', v)
  73. });
  74. viewer.addEventListener("allLoaded", (e) => {
  75. //全部加载完,除了地图
  76. console.log('emit allLoad')
  77. sceneBus.emit("allLoaded");
  78. });
  79. viewer.addEventListener("webglError", (e) => {
  80. console.error("viewer webglError: " + e);
  81. sceneBus.emit("webglError", {
  82. msg: e.msg
  83. });
  84. });
  85. viewer.addEventListener("viewChanged", (e) => {
  86. sceneBus.emit("viewChange", e.name)
  87. });
  88. let cameraChange = (e) => {
  89. var camera = e.viewport.camera;
  90. var pos = camera.position;
  91. if (e.viewport.name == "MainView") {
  92. let meterPerPixel = viewer.mainViewport.camera.type == 'OrthographicCamera' ? 1 / viewer.mainViewport.camera.zoom : null//原本我设定的每像素代表1米, 然后再除以zoom
  93. //console.log('meterPerPixel', meterPerPixel)
  94. sceneBus.emit("posChange", {
  95. x: pos.x,
  96. y: pos.y,
  97. z: pos.z,
  98. rotate: camera.rotation,
  99. meterPerPixel,
  100. });
  101. }
  102. };
  103. viewer.addEventListener("camera_changed", cameraChange);
  104. viewer.addEventListener("shelterComputed", () => {
  105. cameraChange({
  106. viewport: viewer.mainViewport
  107. });
  108. });
  109. {
  110. Potree.loadingByTex = false;
  111. let delayShow = 400;
  112. let timer;
  113. viewer.addEventListener("loading", (e) => {
  114. //加载的等待页面
  115. if (e.show) {
  116. if (!isScreenshoting) {
  117. //截图时不显示
  118. Potree.loadingByTex = true;
  119. timer && clearTimeout(timer);
  120. timer = setTimeout(() => {
  121. if (Potree.loadingByTex) {
  122. Loading.show();
  123. }
  124. }, delayShow);
  125. }
  126. } else {
  127. Potree.loadingByTex = false;
  128. timer && clearTimeout(timer);
  129. Loading.hide();
  130. }
  131. });
  132. }
  133. let info;
  134. const units = {
  135. 1: "metric",
  136. 2: "imperial"
  137. };
  138. let getMeasureType = function (type, unit) {
  139. switch (type) {
  140. case 'BASE_LINE':
  141. info = {
  142. measureType: "Hor LINE with Text", //带有文字label的线
  143. labelText : '基准线',
  144. isBaseLine : true, //暂时只有基准线是这种measureType
  145. };
  146. break;
  147. case "LINE":
  148. info = {
  149. measureType: "Distance"
  150. };
  151. break;
  152. case "SERIES":
  153. info = {
  154. measureType: "MulDistance"
  155. };
  156. break;
  157. case "AREA":
  158. info = {
  159. measureType: "Area"
  160. };
  161. break;
  162. case "L_LINE":
  163. info = {
  164. measureType: "Hor Distance"
  165. };
  166. break;
  167. case "L_SERIES":
  168. info = {
  169. measureType: "Hor MulDistance"
  170. };
  171. break;
  172. case "L_AREA":
  173. info = {
  174. measureType: "Hor Area"
  175. };
  176. break;
  177. case "L_RECTANGLE":
  178. info = {
  179. measureType: "Hor Rect Area"
  180. };
  181. break;
  182. case "V_LINE":
  183. info = {
  184. measureType: "Ver Distance"
  185. };
  186. break;
  187. case "V_SERIES":
  188. info = {
  189. measureType: "Ver MulDistance"
  190. };
  191. break;
  192. case "V_AREA":
  193. info = {
  194. measureType: "Ver Area"
  195. };
  196. break;
  197. case "V_RECTANGLE":
  198. info = {
  199. measureType: "Ver Rect Area"
  200. };
  201. break;
  202. default:
  203. console.error("无此 measure type", type);
  204. }
  205. info.unit = units[unit];
  206. return info;
  207. };
  208. let getMeasureFunction = function (measure, bus) {
  209. measure.addEventListener("marker_dropped", (e) => {
  210. //拖拽结束后发送changeCallBack
  211. if (measure.parent) {
  212. //未被删除
  213. bus.emit("update");
  214. }
  215. });
  216. /* measure.addEventListener("highlight", (e) => {
  217. bus.emit("highlight", e.state);
  218. }); */
  219. measure.addEventListener("selected", (e) => {
  220. bus.emit("selected", e.state);
  221. });
  222. return {
  223. quit: () => {
  224. Potree.Log("quit结束且删除: " + measure.id, {
  225. font: {
  226. color: "#00c7b2"
  227. },
  228. });
  229. viewer.dispatchEvent({
  230. type: "cancel_insertions",
  231. remove: true,
  232. measure,
  233. });
  234. }, //触发结束。退出测量模式,清除之前操作
  235. clear: () => {
  236. //删除
  237. Potree.Log("clear删除: " + measure.id, {
  238. font: {
  239. color: "#00c7b2"
  240. }
  241. });
  242. viewer.dispatchEvent({
  243. type: "cancel_insertions",
  244. remove: true,
  245. measure,
  246. });
  247. viewer.scene.removeMeasurement(measure);
  248. },
  249. end: () => {
  250. //完成 相当于右键
  251. measure.dispatchEvent({
  252. type: "finish",
  253. measure
  254. });
  255. },
  256. getPoints: () => {
  257. return measure.points;
  258. },
  259. getDatasetLocations: () => {
  260. return measure.dataset_points;
  261. },
  262. getDatasets: () => {
  263. return [1]//measure.points_datasets;
  264. },
  265. getDatasetId: () => {
  266. return 1//measure.datasetId;
  267. },
  268. getArea: () => {
  269. return measure.area; //{value:area, string:..}
  270. },
  271. getDistance: () => {
  272. if (measure.points.length < 2)
  273. return null;
  274. var value = measure.getTotalDistance(); //measure.points[0].distanceTo(measure.points[1])
  275. return {
  276. value, //米
  277. string: viewer.unitConvert.convert(
  278. value,
  279. "distance",
  280. void 0,
  281. measure.unitSystem,
  282. 0.1,
  283. true),
  284. };
  285. },
  286. changeUnit: (unit) => {
  287. //公制|英制 , 1 | 2 单位
  288. measure.setUnitSystem(units[unit]);
  289. },
  290. toDataURL: (width, height) => {
  291. //截图
  292. isScreenshoting = true;
  293. var {
  294. getImagePromise,
  295. finishPromise
  296. } = viewer.startScreenshot({
  297. type: "measure",
  298. measurement: measure,
  299. hideMarkers: true,
  300. ifGetPose: true,
  301. },
  302. width,
  303. height);
  304. finishPromise.done(() => {
  305. isScreenshoting = false;
  306. });
  307. return finishPromise; //getImagePromise.done时是可以getPose的, finishPromise.done时才开始截下一张图
  308. },
  309. //手动开启或关闭:
  310. show: () => {
  311. Potree.Utils.updateVisible(measure, "inListByUser", true);
  312. viewer.dispatchEvent('content_changed')
  313. },
  314. hide: () => {
  315. Potree.Utils.updateVisible(measure, "inListByUser", false);
  316. viewer.dispatchEvent('content_changed')
  317. },
  318. /* highlight: (isHight) => {
  319. measure.setSelected(isHight, "byList");
  320. }, */
  321. selected: (state, dontMoveCamera ) => {
  322. //measure.setSelected(state, "byList");
  323. if(state){
  324. measure.focus({dontMoveCamera})
  325. }else{
  326. measure.dispatchEvent('cancelSelect')
  327. }
  328. },
  329. };
  330. };
  331. var sdk = {
  332. temp: {}, //记录
  333. debug: isDebug,
  334. scene: {
  335. getScreenByPoint(pos, canShelter) {
  336. //通过真实坐标获取DOM坐标
  337. let pos3d = new THREE.Vector3().copy(pos);
  338. if (canShelter) {
  339. if (viewer.ifPointBlockedByIntersect(pos3d)) {
  340. //console.log('shelter')
  341. return {
  342. trueSide: false
  343. };
  344. }
  345. }
  346. var viewport = viewer.mainViewport;
  347. var camera = viewport.camera;
  348. var dom = viewer.renderArea;
  349. //Potree.Log('getScreenByPoint scene' , pos3d.toArray(), {font:{toFixed:2,fontSize:10}})
  350. return Potree.Utils.getPos2d(pos3d, camera, dom, viewport);
  351. },
  352. getPointByScreen(pos2d) {
  353. //获取当前画面鼠标所在位置的三维点(必须是点云点)
  354. let position,
  355. /* datasetId,
  356. dataset_location, */
  357. intersect;
  358. let Handler = viewer.inputHandler;
  359. let needReGet =
  360. !Potree.settings.depTexLocBindDataset &&
  361. Potree.settings.useDepthTex &&
  362. Handler.intersect &&
  363. !Handler.intersect.pointcloud; //如果开启了depTexLocBindDataset,热点就可能使用深度图了,属于该漫游点。全景得到的位置更均匀
  364. if ((pos2d && pos2d.inDrag) || needReGet) {
  365. //不使用当前鼠标所在位置的intersect,单独算
  366. if (!pos2d) {
  367. // needReGet
  368. intersect = Handler.getIntersect(
  369. Handler.hoverViewport,
  370. true,
  371. null,
  372. null,
  373. true); //数据集多的时候卡顿
  374. } else {
  375. pos2d.clientX = pos2d.x;
  376. pos2d.clientY = pos2d.y;
  377. pos2d.onlyGetIntersect = true;
  378. pos2d.whichPointcloud = !Potree.settings.depTexLocBindDataset;
  379. pos2d.usePointcloud = true // 深度图不准
  380. intersect = Handler.onMouseMove(pos2d);
  381. }
  382. } else {
  383. intersect = Handler.intersect;
  384. }
  385. if (intersect && intersect.location) {
  386. position = intersect.location.clone();
  387. /* datasetId = intersect.pointcloud.dataset_id;
  388. dataset_location = Potree.Utils.datasetPosTransform({
  389. toDataset: true,
  390. pointcloud: intersect.pointcloud,
  391. position,
  392. }); */
  393. } else
  394. return null;
  395. //console.log('getPointByScreen',position )
  396. return {
  397. position,
  398. /* datasetId,
  399. dataset_location */
  400. };
  401. }, //全景模式一直获取会很卡
  402. getPose2() {
  403. const camera = viewer.scene.getActiveCamera();
  404. const target = viewer.scene.view.getPivot();
  405. const position = viewer.scene.view.position;
  406. return {
  407. position,
  408. target
  409. };
  410. },
  411. currentCamera() {
  412. return viewer.scene.getActiveCamera().position.clone();
  413. },
  414. // 切换模式 1 点云 0 全景图
  415. changeMode(v) {
  416. //Potree.settings.displayMode = Potree.settings.displayMode == 'showPointCloud' ? 'showPanos' : 'showPointCloud'
  417. Potree.settings.displayMode = v == 0 ? "showPanos" : "showPointCloud";
  418. },
  419. getCurrentMode() {
  420. return Potree.settings.displayMode == "showPanos" ? 0 : 1;
  421. },
  422. comeToTag(tag) {
  423. let dontLookUp = page == "geoRegistration"; //防止相机在地面以下
  424. return viewer.focusOnObject({
  425. position: new THREE.Vector3().copy(tag)
  426. },
  427. "tag",
  428. null, {
  429. dontLookUp,
  430. maxDis: Potree.config.panoFieldRadius,
  431. checkIntersect: true /*, sameFloor:true */,
  432. }).promise;
  433. },
  434. comeToMeasure(measure) {
  435. let result = viewer.focusOnObject(measure.object, "measure", 1200);
  436. return result.msg ? result.msg : result.promise;
  437. //返回值 1 deferred 表示即将位移 2 'posNoChange' 表示已在最佳位置 3 'tooFar' 表示距离最佳位置太远
  438. //后两种都代表停在原位
  439. },
  440. comeTo(o = {}) {
  441. //飞到某个点 暂时没写全景模式
  442. let deferred = $.Deferred();
  443. viewer.scene.view.setView(
  444. $.extend({}, o, {
  445. duration: o.dur,
  446. callback: () => {
  447. o.callback && o.callback();
  448. deferred.resolve(true);
  449. },
  450. }));
  451. return deferred.promise();
  452. },
  453. /**
  454. * 开始测量
  455. */
  456. startMeasure(type, unit, color) {
  457. const bus = mitt();
  458. let info = getMeasureType(type, unit);
  459. //info.bus = bus
  460. info.color = color
  461. let measure = viewer.measuringTool.startInsertion( info,
  462. () => {
  463. //done:
  464. bus.emit("end", ret); //完成
  465. },
  466. () => {
  467. //cancel
  468. bus.emit("quit", ret); //删除
  469. });
  470. Potree.Log("startMeasure: " + measure.id, {
  471. font: {
  472. color: "#00c7b2"
  473. },
  474. });
  475. viewer.setPointStandardMat(true);
  476. const ret = {
  477. bus,
  478. type,
  479. object: measure,
  480. ...getMeasureFunction(measure, bus),
  481. };
  482. measure.addEventListener("intersectNoPointcloud", () => {
  483. bus.emit("invalidPoint");
  484. });
  485. measure.addEventListener("firstClick", () => {
  486. bus.emit("firstClickMarker");
  487. });
  488. return ret;
  489. },
  490. quitMeasure() {
  491. viewer.setPointStandardMat(false);
  492. },
  493. /**
  494. * 绘画测量点
  495. */
  496. drawMeasure(
  497. type,
  498. unit,
  499. points,
  500. datasetId,
  501. dataset_points,
  502. points_datasets,
  503. sid, color) {
  504. const bus = mitt();
  505. /* if(!viewer.scene.measurements.find(e=>e.isBaseLine)){
  506. type = 'BASE_LINE'
  507. }
  508. */
  509. let info = getMeasureType(type, unit);
  510. info.points = points;
  511. //info.datasetId = datasetId;
  512. info.dataset_points = dataset_points;
  513. info.points_datasets = points_datasets;
  514. info.sid = sid;
  515. info.bus = bus;
  516. info.color = color
  517. let measure = viewer.measuringTool.createMeasureFromData(info);
  518. Potree.Log("drawMeasure由数据新建: " + measure.id, {
  519. font: {
  520. color: "#00c7b2"
  521. },
  522. });
  523. //console.log(info)
  524. /* if(measure.isBaseLine && viewer.mainViewport.camera.type != 'OrthographicCamera'){
  525. Potree.Utils.updateVisible(measure,'enterOrthoView',false)//基准线仅在正交视图可见
  526. } */
  527. const ret = {
  528. // 退出测量模式,清除之前操作
  529. object: measure,
  530. bus,
  531. ...getMeasureFunction(measure, bus),
  532. };
  533. viewer.dispatchEvent({type:'camera_changed', viewport:viewer.mainViewport, changeInfo:{}})//update sprite
  534. return ret;
  535. },
  536. // 开启放大镜
  537. openMagnifier() {
  538. //console.error('开启放大镜')
  539. viewer.magnifier.dispatchEvent({
  540. type: "setEnable",
  541. value: true
  542. });
  543. },
  544. // 关闭放大镜
  545. closeMagnifier() {
  546. //console.error('关闭放大镜')
  547. viewer.magnifier.dispatchEvent({
  548. type: "setEnable",
  549. value: false
  550. });
  551. },
  552. changePointDensity(levelType) {
  553. //点云密度:低中高
  554. Potree.settings.UserPointDensity = levelType;
  555. return {
  556. percent: Potree.config.pointDensity[levelType].maxLevelPercent,
  557. }; //回调需要更改密度百分比滑动条
  558. },
  559. changeDensityPercent(percent) {
  560. //点云密度百分比(细节) percent : 0-1
  561. //console.log('changeDensityPercent ', percent) //有出现过首次加载大于1的情况???
  562. Potree.settings.UserDensityPercent = percent;
  563. viewer.setPointLevels();
  564. },
  565. // 设置far
  566. changeViewRange(num) {
  567. Potree.settings.cameraFar = num;
  568. },
  569. // 设置色彩模式 0 彩色 1 海拔 2 半透明(透明色)
  570. changeColorMode: function (mode) {
  571. const modes = ["rgba", "elevation", "color"];
  572. mode = modes[mode];
  573. //console.log('设置色彩模式 ', mode)
  574. let otherChange = {};
  575. switch (mode) {
  576. case "rgba": //每个点的颜色
  577. otherChange.opacity = 1;
  578. otherChange.size = 0.4 / 4;
  579. break;
  580. case "elevation":
  581. otherChange.opacity = 0.3;
  582. otherChange.size = 0.4 / 4;
  583. break;
  584. case "color": //透明色
  585. //otherChange.color = ''
  586. otherChange.opacity = 0.3;
  587. otherChange.size = 0.4 / 4;
  588. break;
  589. }
  590. viewer.scene.pointclouds.forEach((e) => {
  591. e.material.activeAttributeName = mode;
  592. });
  593. sdk.scene.changePointSize(otherChange.size);
  594. sdk.scene.changePointOpacity(otherChange.opacity);
  595. delete otherChange.color;
  596. return otherChange;
  597. },
  598. // 设置点大小
  599. changePointSize(num) {
  600. viewer.scene.pointclouds.forEach((e) => {
  601. e.changePointSize(num);
  602. });
  603. },
  604. // 设置点透明度
  605. changePointOpacity: function (num) {
  606. //num:0-1 navvis用的是亮度
  607. viewer.scene.pointclouds.forEach((e) => {
  608. e.changePointOpacity(num);
  609. });
  610. },
  611. // 设置点形状 传入参数 1 矩形 2 圆形
  612. changePointShape(shape) {
  613. viewer.scene.pointclouds.forEach((e) => {
  614. e.material.shape =
  615. Potree.PointShape[shape == 1 ? "SQUARE" : "CIRCLE"]; // and PARABOLOID
  616. });
  617. },
  618. // 设置是否强化边缘
  619. changePointEdge(isStrong) {
  620. //console.log('强化边缘', isStrong)
  621. viewer.setEDLEnabled(isStrong);
  622. },
  623. // 设置漫游点位显示
  624. changePanoPoint(show) {
  625. Potree.settings.ifShowMarker = !!show;
  626. },
  627. getDownloadInfo() {
  628. //获取直接下载点云的参数给后台
  629. return viewer.modules.Clip.downloadNoCrop();
  630. },
  631. /* getDataSets() {
  632. //获取所有数据集对象
  633. let datasets = CloneJson(Potree.datasetData);
  634. datasets.forEach((e) => {
  635. var pointcloud = viewer.scene.pointclouds.find( (p) => p.dataset_id == e.id);
  636. e.changeDisplay = function (show) {
  637. Potree.Utils.updateVisible(pointcloud, "datasetSelection", !!show);
  638. pointcloud.panos.forEach((pano) => {
  639. //数据集隐藏时漫游点也隐藏 //还是不隐藏了,仅隐藏点云
  640. Potree.Utils.updateVisible(pano, "pointcloudVisi", show, 0);
  641. });
  642. if (
  643. viewer.modules.SiteModel.editing ||
  644. viewer.modules.Alignment.editing) {
  645. viewer.updateFpVisiDatasets();
  646. }
  647. };
  648. e.changeColor = function (color) {
  649. pointcloud.material.color = color;
  650. };
  651. e.getColor = function () {
  652. return pointcloud.material.color;
  653. };
  654. e.focus = function () {
  655. viewer.modules.Alignment.SplitScreen.focusOnPointCloud(pointcloud);
  656. };
  657. e.flyTo = function () {
  658. return viewer.flyToDataset({
  659. pointcloud
  660. }) || false;
  661. };
  662. e.getAttachPloygon = function () {
  663. //计算完后才会有
  664. return (
  665. pointcloud.belongToEntity && pointcloud.belongToEntity.polygon);
  666. };
  667. });
  668. return datasets;
  669. }, */
  670. screenshot: (width, height) => {
  671. //截图
  672. let meterPerPixel,
  673. isScreenshoting = true;
  674. var {
  675. getImagePromise,
  676. finishPromise
  677. } = viewer.startScreenshot({
  678. type: "default",
  679. hideMarkers:true,
  680. //hideMeasures:true,
  681. },
  682. width,
  683. height);
  684. finishPromise.done(() => {
  685. isScreenshoting = false;
  686. });
  687. if(viewer.mainViewport.camera.type == 'OrthographicCamera'){
  688. meterPerPixel = 1 / viewer.mainViewport.camera.zoom
  689. }
  690. return {finishPromise, meterPerPixel};
  691. },
  692. canTurnToPanoMode(pos) {
  693. /* if(viewer.hasNoPanoDataset){
  694. return
  695. } */
  696. pos = pos ? new THREE.Vector3().copy(pos) : viewer.images360.position;
  697. let pano = viewer.images360.findNearestPano(pos);
  698. if (
  699. pano &&
  700. pano.position.distanceTo(pos) < Potree.config.panoFieldRadius) {
  701. return true;
  702. }
  703. //poschange后会调用这个,如果返回false会变为点云模式,且不会自动变回原先的模式
  704. },
  705. trackScenePos(){// 单击场景某个位置 返回当前三维坐标, 调用时场景不能漫游与选择直到获取完成
  706. let deferred = $.Deferred();
  707. let quit = ()=>{ //取消获取
  708. viewer.removeEventListener('global_click',gotIntersect)
  709. Potree.settings.unableNavigate = false
  710. Potree.settings.unableUseDepTexPick = false
  711. viewer.controls.setEnable(true)
  712. }
  713. let gotIntersect = (e)=>{
  714. if(e.intersect && e.intersect.location){
  715. console.log('quit', e.intersect.location)
  716. quit()
  717. deferred.resolve(e.intersect.location)
  718. }
  719. }
  720. viewer.addEventListener('global_click',gotIntersect)
  721. Potree.settings.unableNavigate = true
  722. Potree.settings.unableUseDepTexPick = true
  723. viewer.controls.setEnable(false)
  724. return {
  725. promise: deferred.promise() , //获取的promise, 获取到了返回三维坐标,没获取到返回null
  726. quit
  727. }
  728. },
  729. getSceneCropSetting(){
  730. let boxData = viewer.modules.Clip.getBoxData()
  731. return {
  732. top : {value:boxData.scaleZ*100, minTop:0, maxTop:10},
  733. scale : {value: boxData.scaleXY*100},
  734. rotate : {value: THREE.Math.radToDeg(boxData.rotAngle)},
  735. //rotByUser : {value:boxData.rotByUser}
  736. }
  737. },
  738. //设置裁剪值
  739. setSceneCropSetting({top,scale,rotate }){
  740. viewer.modules.Clip.boxData = {
  741. scaleZ: top.value/100,
  742. scaleXY: scale.value/100,
  743. rotAngle: THREE.Math.degToRad(rotate.value),
  744. //rotByUser
  745. }
  746. viewer.modules.Clip.setBoxPose()
  747. },
  748. enterCropSetting(){
  749. let Clip = viewer.modules.Clip
  750. Clip.enter()
  751. return {
  752. quit(){
  753. Clip.leave()
  754. },
  755. enterSetScale(){
  756. Clip.box.frameHorizon.visible = true
  757. },
  758. leaveSetScale(){
  759. Clip.box.frameHorizon.visible = false
  760. },
  761. enterSetTop(){
  762. Clip.box.frameVertical.visible = true
  763. },
  764. leaveSetTop(){
  765. Clip.box.frameVertical.visible = false
  766. },
  767. enterSetRotate(){
  768. Clip.box.frameHorizon.visible = true
  769. Clip.box.frameVertical.visible = true
  770. },
  771. leaveSetRotate(){
  772. Clip.box.frameHorizon.visible = false
  773. Clip.box.frameVertical.visible = false
  774. },
  775. }
  776. },
  777. ...parameter.sceneBus,
  778. },
  779. transformPoint(point, datasetId, dataset_location) {
  780. /* //获取由dataset_location转出的position
  781. var r = datasetId != void 0
  782. ? Potree.Utils.datasetPosTransform({
  783. fromDataset: true,
  784. datasetId,
  785. position: dataset_location,
  786. })
  787. : point;
  788. return r; */
  789. return point
  790. },
  791. // 坐标转换
  792. coordTransform: (originType, pos, targetType, datasetId) => {
  793. // pos 坐标的类型, 当类型为SCREEN时为 { x, y } 其余为 {x, y, z}
  794. if (pos.z == void 0)
  795. pos.z = 0; //否则datasetPosTransform NAN 地理注册
  796. let needMeshLocal;
  797. if (originType == targetType)
  798. return pos;
  799. if (
  800. originType == CoordType.SCENE_SCREEN ||
  801. originType == CoordType.MAP_SCREEN) {
  802. let tool = originType == CoordType.SCENE_SCREEN ? sdk.scene : sdk.map;
  803. let result = tool.getPointByScreen(pos) || {}; //{ position, datasetId, dataset_location }
  804. pos = result.position;
  805. if (!pos)
  806. return;
  807. datasetId = result.datasetId;
  808. originType = CoordType.LOCAL;
  809. }
  810. let pointcloud;
  811. if (datasetId != void 0) {
  812. pointcloud = viewer.scene.pointclouds.find(
  813. (p) => p.dataset_id == datasetId);
  814. }
  815. if (originType == CoordType.MESH_LOCAL) {
  816. pos = Potree.Utils.datasetPosTransform({
  817. fromDataset: true,
  818. pointcloud,
  819. position: pos,
  820. });
  821. originType = CoordType.LOCAL;
  822. }
  823. if (targetType == CoordType.MESH_LOCAL) {
  824. needMeshLocal = true;
  825. targetType = CoordType.LOCAL; //先转化为求CoordType.LOCAL
  826. }
  827. if (originType == targetType) {
  828. //for控制点,获取点云未移动前的坐标值。暂且这么写。
  829. if (needMeshLocal) {
  830. //var invMatrix = new THREE.Matrix4().getInverse(viewer.scene.pointclouds[0].transformMatrix)
  831. pos = Potree.Utils.datasetPosTransform({
  832. toDataset: true,
  833. pointcloud,
  834. position: pos,
  835. });
  836. }
  837. return pos;
  838. }
  839. //先转成lonlat(高德)
  840. switch (originType) {
  841. //EPSG: 4550大地坐标
  842. case CoordType.EPSE:
  843. pos = viewer.transform.lonlatTo4550.inverse(pos);
  844. break;
  845. //Wgs84 经纬度
  846. case CoordType.WGS84: //84转高德
  847. //pos = wgs84ToAMap(pos)
  848. break;
  849. // 本地坐标
  850. case CoordType.LOCAL:
  851. pos = viewer.transform.lonlatToLocal.inverse(pos);
  852. }
  853. // 需要转换成什么类型的坐标
  854. switch (targetType) {
  855. case CoordType.SCENE_SCREEN: // 场景屏幕坐标
  856. pos = sdk.scene.getScreenByPoint(pos);
  857. break;
  858. case CoordType.MAP_SCREEN: // 地图屏幕坐标
  859. pos = sdk.map.getScreenByPoint(pos);
  860. break;
  861. //EPSG: 4550大地坐标
  862. case CoordType.EPSE:
  863. pos = viewer.transform.lonlatTo4550.forward(pos);
  864. break;
  865. //Wgs84 经纬度
  866. case CoordType.WGS84:
  867. //pos = aMapToWgs84(pos)
  868. break;
  869. //本地坐标
  870. case CoordType.LOCAL:
  871. pos = viewer.transform.lonlatToLocal.forward(pos);
  872. }
  873. if (needMeshLocal) {
  874. pos = Potree.Utils.datasetPosTransform({
  875. toDataset: true,
  876. pointcloud,
  877. position: pos,
  878. });
  879. }
  880. return pos;
  881. },
  882. enterMeasurement() {
  883. //进入测量模块
  884. viewer.setLimitFar(false);
  885. },
  886. leaveMeasurement() {
  887. //退出测量模块
  888. viewer.setLimitFar(true);
  889. },
  890. loadModel(info) {
  891. info.moveWithPointcloud = true;
  892. viewer.loadModel(info);
  893. },
  894. enterTopView(){
  895. viewer.navCubeViewer.dispatchEvent('enterTopView')
  896. },
  897. leaveTopView(){
  898. viewer.navCubeViewer.dispatchEvent('leaveTopView')
  899. },
  900. destroy(){//重新创建viewer,删了旧的
  901. viewer.setDisplay(false)
  902. }
  903. };
  904. Potree.sdk = sdk;
  905. return sdk;
  906. };
  907. export default enter;
  908. /*
  909. 热点poi加载到的数据中,pos是错误的,只使用dataset_location
  910. 关于webgl context lost报错:
  911. 已知有一iphoneX在创建shadowMap后才报错。
  912. 所以报错的话很可能是代码中的某一句,去除后就会正常。
  913. =======
  914. 如果遇到点云只显示一部分,很可能是裁剪范围出错
  915. */