enter.js 32 KB

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