enter.js 58 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627
  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. const pointMeasureColor = "#3290ff"
  19. const CloneJson = function (data) {
  20. var str = JSON.stringify(data);
  21. return JSON.parse(str);
  22. };
  23. let getPanoId = (function(){
  24. let id = 0
  25. return function(){
  26. return id++
  27. }
  28. })()
  29. var enter = ({
  30. dom,
  31. mapDom,
  32. number,
  33. //datasetId, //初始数据集
  34. webSite, //废弃,改为用dataset.webBin
  35. isLocal = false,
  36. basePath,
  37. isDebug = false,
  38. mapCompany, // 地图版本 'default' | 'google' default就跟现在一样
  39. axios,
  40. version, //'V3''V4' 废弃,改为从getDataset获取
  41. staticPrefix,
  42. cropArgs,
  43. getFileUrl,
  44. isTemp //= true
  45. }) => {
  46. let isScreenshoting = false;
  47. let lastSiteModelData;
  48. let page; //所在页面
  49. const sceneBus = mitt();
  50. const needRot90 = Potree.browser.urlHasValue('rot90')
  51. Potree.settings.isOfficial = true; //标记为正式、非测试版本
  52. Potree.settings.isDebug = isDebug;
  53. //Potree.settings.originDatasetId = datasetId;
  54. /*if (isLocal) {
  55. //本地配置
  56. Potree.settings.isLocal = isLocal;
  57. for (let i in Potree.settings.urls) {
  58. Potree.settings.urls[i] = basePath; //全部替换
  59. }
  60. }
  61. webSite && (Potree.settings.webSite = webSite);
  62. //axios && (Potree.fileServer = axios); //暂时不用,比如vision那里
  63. if (staticPrefix) {
  64. // "/dev/SS-t-4pMXagRDjk"
  65. Potree.settings.isLocal = true;
  66. Potree.settings.urls.prefix1 = Potree.settings.urls.prefix3 = staticPrefix;
  67. Potree.settings.webSite = "wwwroot";
  68. } */
  69. Potree.getFileUrl = getFileUrl //转化为另一种得到url的方法
  70. if(isTemp){
  71. Potree.settings.cloudPath = Potree.settings.urls.prefix1 + '/result/reconstruction/webcloud/cloud.js'
  72. Potree.settings.noPanos = true
  73. }
  74. Potree.start(dom, mapDom, number);
  75. parameter.dom = dom;
  76. parameter.number = number;
  77. parameter.viewer = viewer;
  78. parameter.sceneBus = sceneBus;
  79. //Potree.settings.rotAroundPoint = false; //试验
  80. viewer.fixPoints = []//固定点
  81. sceneBus.on("visible", (v) => {
  82. viewer.visible = v;
  83. });
  84. viewer.addEventListener("allLoaded", (e) => {
  85. //全部加载完,除了地图
  86. console.log('emit allLoad')
  87. if(isTemp){
  88. //Potree.settings.cloudAttributeName = 'color'
  89. //viewer.scene.pointclouds[0].material.activeAttributeName = 'color'
  90. //pointcloud.material.color = '#ffffff'
  91. //viewer.scene.pointclouds[0].material.pointSizeType = 'FIXED'
  92. if(needRot90){
  93. //旋转九十度
  94. let pointcloud = viewer.scene.pointclouds[0]
  95. pointcloud.orientationUser = new THREE.Quaternion().setFromEuler(new THREE.Euler( Math.PI/2, 0,0))
  96. pointcloud.rotateMatrix = new THREE.Matrix4().makeRotationFromQuaternion(pointcloud.orientationUser)
  97. pointcloud.transformMatrix = pointcloud.rotateMatrix.clone();//为该数据集的变化矩阵。 对应navvis的m2w_
  98. pointcloud.transformInvMatrix.copy(pointcloud.transformMatrix).invert()
  99. var pos1Matrix = new THREE.Matrix4().setPosition(pointcloud.position);//先移动到点云本身应该在的初始位置(在4dkk里和其他应用中都是在这个位置的,也能和漫游点对应上)
  100. pointcloud.matrix = new THREE.Matrix4().multiplyMatrices(pointcloud.transformMatrix, pos1Matrix);
  101. pointcloud.updateMatrixWorld(true)
  102. viewer.updateModelBound()//viewer.boundNeedUpdate = true //范围还没旋转
  103. }
  104. viewer.focusOnObject({boundingBox: viewer.bound.boundingBox},'boundingBox',0)
  105. //{boundingBox:bound},'boundingBox',800, {dontChangeCamDir:true}
  106. }
  107. sceneBus.emit("allLoaded");
  108. });
  109. viewer.addEventListener("webglError", (e) => {
  110. console.error("viewer webglError: " + e);
  111. sceneBus.emit("webglError", {
  112. msg: e.msg
  113. });
  114. });
  115. viewer.addEventListener("viewChanged", (e) => {
  116. sceneBus.emit("viewChange", e.name)
  117. });
  118. let cameraChange = (e) => {
  119. var camera = e.viewport.camera;
  120. var pos = camera.position;
  121. if (e.viewport.name == "MainView") {
  122. let meterPerPixel = viewer.mainViewport.camera.type == 'OrthographicCamera' ? 1 / viewer.mainViewport.camera.zoom : null//原本我设定的每像素代表1米, 然后再除以zoom
  123. //console.log('meterPerPixel', meterPerPixel)
  124. sceneBus.emit("posChange", {
  125. x: pos.x,
  126. y: pos.y,
  127. z: pos.z,
  128. rotate: camera.rotation,
  129. meterPerPixel,
  130. });
  131. }
  132. viewer.fixPoints.forEach(point=>{
  133. point.pos2d = Potree.Utils.getPos2d(point, e.viewport, viewer.renderArea )
  134. point.pos2d.pos3d = point.clone()
  135. })
  136. };
  137. viewer.addEventListener("camera_changed", cameraChange);
  138. viewer.addEventListener("shelterComputed", () => {
  139. cameraChange({
  140. viewport: viewer.mainViewport
  141. });
  142. });
  143. {
  144. Potree.loadingByTex = false;
  145. let delayShow = 400;
  146. let timer;
  147. viewer.addEventListener("loading", (e) => {
  148. //加载的等待页面
  149. if (e.show) {
  150. if (!isScreenshoting) {
  151. //截图时不显示
  152. Potree.loadingByTex = true;
  153. timer && clearTimeout(timer);
  154. timer = setTimeout(() => {
  155. if (Potree.loadingByTex) {
  156. Loading.show();
  157. }
  158. }, delayShow);
  159. }
  160. } else {
  161. Potree.loadingByTex = false;
  162. timer && clearTimeout(timer);
  163. Loading.hide();
  164. }
  165. });
  166. }
  167. let info;
  168. const units = {
  169. 1: "metric",
  170. 2: "imperial"
  171. };
  172. let getMeasureType = function (type, unit) {
  173. switch (type) {
  174. case 'BASE_LINE':
  175. info = {
  176. measureType: "Hor LINE with Text", //带有文字label的线
  177. labelText : '基准线',
  178. isBaseLine : true, //暂时只有基准线是这种measureType
  179. };
  180. break;
  181. case "LINE":
  182. info = {
  183. measureType: "Distance"
  184. };
  185. break;
  186. case "SERIES":
  187. info = {
  188. measureType: "MulDistance"
  189. };
  190. break;
  191. case "AREA":
  192. info = {
  193. measureType: "Area"
  194. };
  195. break;
  196. case "L_LINE":
  197. info = {
  198. measureType: "Hor Distance"
  199. };
  200. break;
  201. case "L_SERIES":
  202. info = {
  203. measureType: "Hor MulDistance"
  204. };
  205. break;
  206. case "L_AREA":
  207. info = {
  208. measureType: "Hor Area"
  209. };
  210. break;
  211. case "L_RECTANGLE":
  212. info = {
  213. measureType: "Hor Rect Area"
  214. };
  215. break;
  216. case "V_LINE":
  217. info = {
  218. measureType: "Ver Distance"
  219. };
  220. break;
  221. case "V_SERIES":
  222. info = {
  223. measureType: "Ver MulDistance"
  224. };
  225. break;
  226. case "V_AREA":
  227. info = {
  228. measureType: "Ver Area"
  229. };
  230. break;
  231. case "V_RECTANGLE":
  232. info = {
  233. measureType: "Ver Rect Area"
  234. };
  235. break;
  236. default:
  237. console.error("无此 measure type", type);
  238. }
  239. info.unit = units[unit];
  240. return info;
  241. };
  242. let getMeasureFunction = function (measure, bus, isShape) {
  243. measure.addEventListener("marker_dropped", (e) => {
  244. //拖拽结束后发送changeCallBack
  245. if (measure.parent) {
  246. //未被删除
  247. isShape ? bus.emit("graphChange", {path:measure.points, center:measure.getCenter()}) : bus.emit("update");
  248. if(measure.isBaseLine){
  249. viewer.dispatchEvent('baseLineChanged')
  250. }
  251. }
  252. });
  253. /* measure.addEventListener("highlight", (e) => {
  254. bus.emit("highlight", e.state);
  255. }); */
  256. measure.addEventListener("selected", (e) => {
  257. bus.emit(isShape ? "selectGraph":"selected", e.state)
  258. isShape && measure.mainPoint.ret.selected(e.state, true)
  259. });
  260. return {
  261. quit: () => {
  262. Potree.Log("quit结束且删除: " + measure.id, {
  263. font: {
  264. color: "#00c7b2"
  265. },
  266. });
  267. viewer.dispatchEvent({
  268. type: "cancel_insertions",
  269. remove: true,
  270. measure,
  271. });
  272. }, //触发结束。退出测量模式,清除之前操作
  273. clear: () => {
  274. //删除
  275. Potree.Log("clear删除: " + measure.id, {
  276. font: {
  277. color: "#00c7b2"
  278. }
  279. });
  280. viewer.dispatchEvent({
  281. type: "cancel_insertions",
  282. remove: true,
  283. measure,
  284. });
  285. viewer.scene.removeMeasurement(measure);
  286. if(measure.isBaseLine){
  287. viewer.dispatchEvent('baseLineRemoved')
  288. }
  289. },
  290. end: () => {
  291. //完成 相当于右键
  292. measure.dispatchEvent({
  293. type: "finish",
  294. measure
  295. });
  296. },
  297. getPoints: () => {
  298. return measure.points;
  299. },
  300. getDatasetLocations: () => {
  301. return measure.dataset_points;
  302. },
  303. getDatasets: () => {
  304. return [1]//measure.points_datasets;
  305. },
  306. getDatasetId: () => {
  307. return 1//measure.datasetId;
  308. },
  309. getArea: () => {
  310. return measure.area; //{value:area, string:..}
  311. },
  312. getDistance: () => {
  313. if (measure.points.length < 2)
  314. return null;
  315. var value = measure.getTotalDistance(); //measure.points[0].distanceTo(measure.points[1])
  316. return {
  317. value, //米
  318. string: viewer.unitConvert.convert(
  319. value,
  320. "distance",
  321. void 0,
  322. measure.unitSystem,
  323. 0.1,
  324. true),
  325. };
  326. },
  327. changeUnit: (unit) => {
  328. //公制|英制 , 1 | 2 单位
  329. measure.setUnitSystem(units[unit]);
  330. },
  331. toDataURL: (width, height) => {
  332. //截图
  333. isScreenshoting = true;
  334. var {
  335. getImagePromise,
  336. finishPromise
  337. } = viewer.startScreenshot({
  338. type: "measure",
  339. measurement: measure,
  340. hideMarkers: true,
  341. ifGetPose: true,
  342. },
  343. width,
  344. height);
  345. finishPromise.done(() => {
  346. isScreenshoting = false;
  347. });
  348. return finishPromise; //getImagePromise.done时是可以getPose的, finishPromise.done时才开始截下一张图
  349. },
  350. //手动开启或关闭:
  351. show: () => {
  352. Potree.Utils.updateVisible(measure, "forceByUser", true);
  353. viewer.dispatchEvent('content_changed')
  354. },
  355. hide: () => {
  356. Potree.Utils.updateVisible(measure, "forceByUser", false);
  357. viewer.dispatchEvent('content_changed')
  358. },
  359. /* highlight: (isHight) => {
  360. measure.setSelected(isHight, "byList");
  361. }, */
  362. selected: (state, dontMoveCamera ) => {
  363. //measure.setSelected(state, "byList");
  364. if(state){
  365. measure.focus({dontMoveCamera})
  366. }else{
  367. measure.dispatchEvent('cancelSelect')
  368. }
  369. },
  370. };
  371. };
  372. /* let getMeasurePointsInfo = (fixPoint, onlyMoveBasePoint)=>{
  373. let baseLine = viewer.scene.measurements.find(e=>e.isBaseLine && e.points.length == 2)
  374. if(!baseLine){
  375. return console.error('创建失败,因基准线不存在')
  376. }
  377. if(!fixPoint.basePoint){
  378. return //console.log('no basePoint')
  379. }
  380. let fixPoint2d = new THREE.Vector2().copy(fixPoint)
  381. let baselineP12d = new THREE.Vector2().copy(baseLine.points[0])
  382. let baselineP22d = new THREE.Vector2().copy(baseLine.points[1])
  383. let foot1_2d = Potree.math.getFootPoint(fixPoint2d, baselineP12d, baselineP22d)
  384. let minZ = Math.min(fixPoint.basePoint.z, baseLine.points[0].z, fixPoint.z)
  385. let maxZ = Math.max(fixPoint.basePoint.z, baseLine.points[0].z, fixPoint.z)
  386. let foot1_P1 = new THREE.Vector3(foot1_2d.x, foot1_2d.y, fixPoint.z)
  387. let foot1_P2 = new THREE.Vector3(foot1_2d.x, foot1_2d.y, minZ)
  388. let foot1_P3 = new THREE.Vector3(foot1_2d.x, foot1_2d.y, maxZ)
  389. let info = {
  390. disMeasure1:{
  391. points: [new THREE.Vector3().copy(fixPoint), foot1_P1],
  392. guideLinePoints : [foot1_P2, foot1_P3] //垂足上的垂线,从最低点到最高点(包含disMeasure2那一段)
  393. }
  394. }
  395. let basePoint2d = new THREE.Vector2().copy(fixPoint.basePoint)
  396. let anotherPoint2d = new THREE.Vector2().addVectors(basePoint2d, new THREE.Vector2().subVectors(baselineP12d,baselineP22d))//测量线方向上另一点
  397. let foot2_2d = Potree.math.getFootPoint(fixPoint2d, basePoint2d, anotherPoint2d)
  398. let foot2_P1 = new THREE.Vector3(foot2_2d.x, foot2_2d.y, fixPoint.basePoint.z)
  399. let foot2_P2 = new THREE.Vector3(foot1_2d.x, foot1_2d.y, fixPoint.basePoint.z)
  400. info.disMeasure2 = {
  401. points : [new THREE.Vector3().copy(fixPoint.basePoint), foot2_P1],
  402. guideLinePoints : [foot2_P1, foot2_P2 ],
  403. }
  404. fixPoint.bus.emit('measureChange',[
  405. {line: info.disMeasure1.points, dis: info.disMeasure1.points[0].distanceTo(info.disMeasure1.points[1])},
  406. {line: info.disMeasure2.points, dis: info.disMeasure2.points[0].distanceTo(info.disMeasure2.points[1])}
  407. ])
  408. return info
  409. } */
  410. let getMeasurePointsInfo = (fixPoint, baseMeasurePoints )=>{
  411. let baseLine = viewer.scene.measurements.find(e=>e.isBaseLine && e.points.length == 2)
  412. if(!baseLine){
  413. return console.error('创建失败,因基准线不存在')
  414. }
  415. if(!fixPoint.basePoint){
  416. return //console.log('no basePoint')
  417. }
  418. let fixPoint2d = new THREE.Vector2().copy(fixPoint)
  419. let baselineP12d = new THREE.Vector2().copy(baseLine.points[0])
  420. let baselineP22d = new THREE.Vector2().copy(baseLine.points[1])
  421. let foot1_2d = Potree.math.getFootPoint(fixPoint2d, baselineP12d, baselineP22d)
  422. let foot1_P1 = new THREE.Vector3(foot1_2d.x, foot1_2d.y, baseLine.points[0].z)
  423. let fixPointProj = fixPoint.clone().setZ(baseLine.points[0].z)
  424. let info = {
  425. disMeasure1:{
  426. points: [fixPointProj, foot1_P1],
  427. guideLinePoints : [new THREE.Vector3().copy(fixPoint), fixPointProj] //垂足上的垂线,从最低点到最高点(包含disMeasure2那一段)
  428. }
  429. }
  430. let basePointProj = fixPoint.basePoint.clone().setZ(baseLine.points[0].z)
  431. if(baseMeasurePoints){//初始创建
  432. info.disMeasure2 = {
  433. points : baseMeasurePoints,
  434. guideLinePoints:[fixPoint.basePoint.clone(), basePointProj,
  435. basePointProj, baseMeasurePoints[0].clone(),
  436. baseMeasurePoints[1].clone(), foot1_P1]
  437. }
  438. }else{
  439. let basePoint2d = new THREE.Vector2().copy(fixPoint.basePoint)
  440. let anotherPoint2d = new THREE.Vector2().addVectors(basePoint2d, new THREE.Vector2().subVectors(baselineP12d,baselineP22d))//测量线方向上另一点
  441. let foot2_2d = Potree.math.getFootPoint(fixPoint2d, basePoint2d, anotherPoint2d)
  442. let foot2_P1 = new THREE.Vector3(foot2_2d.x, foot2_2d.y, baseLine.points[0].z)
  443. info.disMeasure2 = {
  444. points : [basePointProj, foot2_P1 ],
  445. guideLinePoints : [fixPoint.basePoint.clone(), basePointProj, foot2_P1, foot1_P1],
  446. }
  447. }
  448. fixPoint.bus.emit('measureChange',[
  449. {line: info.disMeasure1.points, dis: info.disMeasure1.points[0].distanceTo(info.disMeasure1.points[1])},
  450. {line: info.disMeasure2.points, dis: info.disMeasure2.points[0].distanceTo(info.disMeasure2.points[1])}
  451. ])
  452. return info
  453. }
  454. //基准点处的测量线会重叠在一起,建议错开,向道路外移动。但是容易看起来很多线,为了整齐,让最长的在最里层;但需要每次排序更新所有的线……
  455. let createMeasureForPoint = (fixPoint, baseMeasurePoints)=>{
  456. let info = getMeasurePointsInfo(fixPoint, baseMeasurePoints)
  457. if(!info)return
  458. let info1 = {//垂直于基准线的水平测量线
  459. measureType : 'Hor Distance', color : pointMeasureColor ,
  460. unableDrag: true,
  461. points: info.disMeasure1.points,
  462. guideLinePoints : info.disMeasure1.guideLinePoints
  463. }
  464. let disMeasure1 = viewer.measuringTool.createMeasureFromData(info1);
  465. let info2 = {//平行于基准线的水平测量线
  466. measureType : 'Hor Distance', color : pointMeasureColor ,
  467. unableDrag: true,
  468. points: info.disMeasure2.points,
  469. guideLinePoints : info.disMeasure2.guideLinePoints
  470. }
  471. let disMeasure2 = viewer.measuringTool.createMeasureFromData(info2);
  472. //因多个measure在同一直线上,会重叠,所以使可拖拽
  473. let mouseover = (e) => {
  474. viewer.dispatchEvent({
  475. type : "CursorChange", action : "add", name:"markerMove"
  476. })
  477. };
  478. let mouseleave = (e) => {
  479. viewer.dispatchEvent({
  480. type : "CursorChange", action : "remove", name:"markerMove"
  481. })
  482. }
  483. disMeasure2.edges[0].addEventListener('mouseover', mouseover);
  484. disMeasure2.edges[0].addEventListener('mouseleave', mouseleave);
  485. let dragInfo = {}
  486. disMeasure2.edges[0].addEventListener('startDragging',(e)=>{
  487. dragInfo = {
  488. startMeasurePoints : disMeasure2.points.map(e=>e.clone()),
  489. dragPoint : e.drag.location.clone(),
  490. normal : new THREE.Vector3().copy(Potree.math.getNormal2d({p1:disMeasure2.points[0], p2:disMeasure2.points[1]})).setZ(0), //measure的法线
  491. plane: new THREE.Plane().setFromNormalAndCoplanarPoint(new THREE.Vector3(0,0,1), disMeasure2.points[0]), //水平面
  492. }
  493. })
  494. disMeasure2.edges[0].addEventListener('drag',(e)=>{ //平移
  495. let ray = Potree.Utils.mouseToRay(e.pointer, e.drag.dragViewport.camera);
  496. let I = ray.intersectPlane(dragInfo.plane, new THREE.Vector3())
  497. if(!I)return //向上了
  498. let dragVec = new THREE.Vector3().subVectors(I, dragInfo.dragPoint);
  499. dragVec.projectOnVector(dragInfo.normal)
  500. dragDisMeasure2(fixPoint, dragVec, dragInfo.startMeasurePoints)
  501. })
  502. fixPoint.disMeasure1 = disMeasure1;
  503. fixPoint.disMeasure2 = disMeasure2;
  504. let selected
  505. ;[disMeasure1,disMeasure2].forEach(measure=>{
  506. measure.addEventListener("selected", (e) => {
  507. let newState = disMeasure1.clickSelected || disMeasure2.clickSelected
  508. if(selected != newState){
  509. selected = newState
  510. console.error('selectMeasure', selected, fixPoint.index11)
  511. fixPoint.bus.emit('selectMeasure', selected)
  512. }
  513. })
  514. })
  515. }
  516. let dragDisMeasure2 = (fixPoint, dragVec, startMeasurePoints)=>{//将disMeasure2拖拽一定距离
  517. let disMeasure1 = fixPoint.disMeasure1,
  518. disMeasure2 = fixPoint.disMeasure2
  519. startMeasurePoints = startMeasurePoints || disMeasure2.points //开始拖拽时的点
  520. disMeasure2.points = startMeasurePoints.map(e=>new THREE.Vector3().addVectors(e,dragVec))
  521. let basePointProj = disMeasure2.guideLinePoints[1]
  522. let foot1_P1 = disMeasure2.guideLinePoints[disMeasure2.guideLinePoints.length-1]
  523. disMeasure2.guideLinePoints = [fixPoint.basePoint.clone(), basePointProj, //修改虚线
  524. basePointProj, disMeasure2.points[0].clone(),
  525. disMeasure2.points[1].clone(), foot1_P1]
  526. disMeasure2.updateGuideLines()
  527. disMeasure2.update({ifUpdateMarkers:true})
  528. viewer.dispatchEvent('content_changed')
  529. fixPoint.bus.emit('measureChange',[
  530. {line: disMeasure1.points.map(e=>e.clone()), dis: disMeasure1.points[0].distanceTo(disMeasure1.points[1])},
  531. {line: disMeasure2.points.map(e=>e.clone()), dis: disMeasure2.points[0].distanceTo(disMeasure2.points[1])}
  532. ])
  533. }
  534. let updateMeasureForPoint = (fixPoint, {onlyBasePoint,updateBaseLine}={})=>{
  535. if(!fixPoint.disMeasure1)return
  536. let ps = fixPoint.disMeasure2.guideLinePoints
  537. let dragVec = ps.length == 6 && new THREE.Vector3().subVectors(ps[3],ps[2])
  538. let info = getMeasurePointsInfo(fixPoint)
  539. if(!info)return
  540. if(!onlyBasePoint){
  541. fixPoint.disMeasure1.points = info.disMeasure1.points
  542. fixPoint.disMeasure1.update({ifUpdateMarkers:true})
  543. }
  544. fixPoint.disMeasure1.guideLinePoints = info.disMeasure1.guideLinePoints
  545. fixPoint.disMeasure1.updateGuideLines()
  546. fixPoint.disMeasure2.points = info.disMeasure2.points
  547. fixPoint.disMeasure2.update({ifUpdateMarkers:true})
  548. fixPoint.disMeasure2.guideLinePoints = info.disMeasure2.guideLinePoints
  549. fixPoint.disMeasure2.updateGuideLines()
  550. if(dragVec){//基准点的那条垂线如果移动过
  551. if(updateBaseLine){//移动基准线的话dragVec也改变方向了
  552. let baseLine = viewer.scene.measurements.find(e=>e.isBaseLine && e.points.length == 2)
  553. let dragDir = dragVec.cross(baseLine.lineDir).z < 0 ? 1 : -1//相对于基准线向外or向内
  554. ps = fixPoint.disMeasure2.guideLinePoints
  555. let newVec = new THREE.Vector3().subVectors(ps[ps.length-2],ps[ps.length-1]).normalize()
  556. let dis = dragVec.length() * dragDir
  557. newVec.multiplyScalar(dis)
  558. dragVec = newVec
  559. }
  560. dragDisMeasure2(fixPoint, dragVec)//恢复之前拖拽的距离
  561. }
  562. }
  563. let removeMeasureForPoint = (fixPoint)=>{
  564. viewer.scene.removeMeasurement(fixPoint.disMeasure1);
  565. viewer.scene.removeMeasurement(fixPoint.disMeasure2);
  566. fixPoint.disMeasure1 = null
  567. fixPoint.disMeasure2 = null
  568. fixPoint.basePoint = null
  569. }
  570. var sdk = {
  571. temp: {}, //记录
  572. debug: isDebug,
  573. scene: {
  574. getScreenByPoint(pos, canShelter) {
  575. //通过真实坐标获取DOM坐标
  576. let pos3d = new THREE.Vector3().copy(pos);
  577. if (canShelter) {
  578. if (viewer.ifPointBlockedByIntersect(pos3d)) {
  579. //console.log('shelter')
  580. return {
  581. trueSide: false
  582. };
  583. }
  584. }
  585. var viewport = viewer.mainViewport;
  586. var camera = viewport.camera;
  587. var dom = viewer.renderArea;
  588. //Potree.Log('getScreenByPoint scene' , pos3d.toArray(), {font:{toFixed:2,fontSize:10}})
  589. return Potree.Utils.getPos2d(pos3d, viewport, dom );
  590. },
  591. getPointByScreen(pos2d) {
  592. //获取当前画面鼠标所在位置的三维点(必须是点云点)
  593. let position,
  594. /* datasetId,
  595. dataset_location, */
  596. intersect;
  597. let Handler = viewer.inputHandler;
  598. let needReGet =
  599. !Potree.settings.depTexLocBindDataset &&
  600. Potree.settings.useDepthTex &&
  601. Handler.intersect &&
  602. !Handler.intersect.pointcloud; //如果开启了depTexLocBindDataset,热点就可能使用深度图了,属于该漫游点。全景得到的位置更均匀
  603. if ((pos2d && pos2d.inDrag) || needReGet) {
  604. //不使用当前鼠标所在位置的intersect,单独算
  605. if (!pos2d) {
  606. // needReGet
  607. intersect = Handler.getIntersect({viewport:Handler.hoverViewport, onlyGetIntersect:true, usePointcloud: true}) //数据集多的时候卡顿
  608. intersect = Handler.getIntersect(
  609. Handler.hoverViewport,
  610. true,
  611. null,
  612. null,
  613. true); //数据集多的时候卡顿
  614. } else {
  615. pos2d.clientX = pos2d.x;
  616. pos2d.clientY = pos2d.y;
  617. pos2d.onlyGetIntersect = true;
  618. pos2d.whichPointcloud = !Potree.settings.depTexLocBindDataset;
  619. pos2d.usePointcloud = true // 深度图不准
  620. intersect = Handler.onMouseMove(pos2d);
  621. }
  622. } else {
  623. intersect = Handler.intersect;
  624. }
  625. if (intersect && intersect.location) {
  626. position = intersect.location.clone();
  627. /* datasetId = intersect.pointcloud.dataset_id;
  628. dataset_location = Potree.Utils.datasetPosTransform({
  629. toDataset: true,
  630. pointcloud: intersect.pointcloud,
  631. position,
  632. }); */
  633. } else
  634. return null;
  635. //console.log('getPointByScreen',position )
  636. return {
  637. position,
  638. /* datasetId,
  639. dataset_location */
  640. };
  641. }, //全景模式一直获取会很卡
  642. getPose2() {
  643. const camera = viewer.scene.getActiveCamera();
  644. const target = viewer.scene.view.getPivot();
  645. const position = viewer.scene.view.position;
  646. return {
  647. position,
  648. target
  649. };
  650. },
  651. currentCamera() {
  652. return viewer.scene.getActiveCamera().position.clone();
  653. },
  654. // 切换模式 1 点云 0 全景图
  655. changeMode(v) {
  656. //Potree.settings.displayMode = Potree.settings.displayMode == 'showPointCloud' ? 'showPanos' : 'showPointCloud'
  657. Potree.settings.displayMode = v == 0 ? "showPanos" : "showPointCloud";
  658. },
  659. getCurrentMode() {
  660. return Potree.settings.displayMode == "showPanos" ? 0 : 1;
  661. },
  662. comeToTag(tag) {
  663. let dontLookUp = page == "geoRegistration"; //防止相机在地面以下
  664. return viewer.focusOnObject({
  665. position: new THREE.Vector3().copy(tag)
  666. },
  667. "tag",
  668. null, {
  669. dontLookUp,
  670. maxDis: Potree.config.panoFieldRadius,
  671. checkIntersect: true /*, sameFloor:true */,
  672. }).promise;
  673. },
  674. comeToMeasure(measure) {
  675. let result = viewer.focusOnObject(measure.object, "measure", 1200);
  676. return result.msg ? result.msg : result.promise;
  677. //返回值 1 deferred 表示即将位移 2 'posNoChange' 表示已在最佳位置 3 'tooFar' 表示距离最佳位置太远
  678. //后两种都代表停在原位
  679. },
  680. comeTo(o = {}) {
  681. //飞到某个点 暂时没写全景模式
  682. let deferred = $.Deferred();
  683. viewer.scene.view.setView(
  684. $.extend({}, o, {
  685. duration: o.dur,
  686. callback: () => {
  687. o.callback && o.callback();
  688. deferred.resolve(true);
  689. },
  690. }));
  691. return deferred.promise();
  692. },
  693. /**
  694. * 开始测量
  695. */
  696. startMeasure(type, unit, color) {
  697. const bus = mitt();
  698. let info = getMeasureType(type, unit);
  699. //info.bus = bus
  700. info.color = color
  701. let measure = viewer.measuringTool.startInsertion( info,
  702. () => {
  703. //done:
  704. bus.emit("end", ret); //完成
  705. },
  706. () => {
  707. //cancel
  708. bus.emit("quit", ret); //删除
  709. });
  710. Potree.Log("startMeasure: " + measure.id, {
  711. font: {
  712. color: "#00c7b2"
  713. },
  714. });
  715. viewer.setPointStandardMat(true);
  716. const ret = {
  717. bus,
  718. type,
  719. object: measure,
  720. ...getMeasureFunction(measure, bus),
  721. };
  722. measure.addEventListener("intersectNoPointcloud", () => {
  723. bus.emit("invalidPoint");
  724. });
  725. measure.addEventListener("firstClick", () => {
  726. bus.emit("firstClickMarker");
  727. });
  728. return ret;
  729. },
  730. quitMeasure() {
  731. viewer.setPointStandardMat(false);
  732. },
  733. /**
  734. * 绘画测量点
  735. */
  736. drawMeasure(
  737. type,
  738. unit,
  739. points,
  740. datasetId,
  741. dataset_points,
  742. points_datasets,
  743. sid, color) {
  744. const bus = mitt();
  745. /* if(!viewer.scene.measurements.find(e=>e.isBaseLine)){
  746. type = 'BASE_LINE'
  747. }
  748. */
  749. let info = getMeasureType(type, unit);
  750. info.points = points;
  751. //info.datasetId = datasetId;
  752. info.dataset_points = dataset_points;
  753. info.points_datasets = points_datasets;
  754. info.sid = sid;
  755. info.bus = bus;
  756. info.color = color
  757. let measure = viewer.measuringTool.createMeasureFromData(info);
  758. Potree.Log("drawMeasure由数据新建: " + measure.id, {
  759. font: {
  760. color: "#00c7b2"
  761. },
  762. });
  763. //console.log(info)
  764. /* if(measure.isBaseLine && viewer.mainViewport.camera.type != 'OrthographicCamera'){
  765. Potree.Utils.updateVisible(measure,'enterOrthoView',false)//基准线仅在正交视图可见
  766. } */
  767. const ret = {
  768. // 退出测量模式,清除之前操作
  769. object: measure,
  770. bus,
  771. ...getMeasureFunction(measure, bus),
  772. };
  773. viewer.dispatchEvent({type:'camera_changed', viewport:viewer.mainViewport, changeInfo:{}})//update sprite
  774. return ret;
  775. },
  776. /*
  777. // 创建固定点对象,measure是否是测量模式,
  778. //graph 如果是形状则有形状路径点,如果不是形状则传入pos当前固定点的位置
  779. sdk.scene.createFixPoint({ measure: boolean,
  780. graph: Array<{x,y,z}>, pos: {xyz} })
  781. */
  782. createFixPoint({measure, graph, pos, basePoint }, lines){//创建固定点或多线段
  783. console.log('createFixPoint',measure, graph, pos, basePoint, lines)
  784. let ifDrawVerMeasure = measure//是否绘制垂线
  785. let shape, measureFun, mainPoint = new THREE.Vector3(), bus = mitt();
  786. basePoint && (mainPoint.basePoint = new THREE.Vector3().copy(basePoint))
  787. mainPoint.bus = bus
  788. mainPoint.index11 = Math.random()
  789. let disMeasure2points = lines && lines[1].points.map(e=>new THREE.Vector3().copy(e))
  790. const baseLineChanged = ()=>{
  791. updateMeasureForPoint(mainPoint,{updateBaseLine:true})
  792. }
  793. const setDisplay = (show)=>{
  794. if(graph){
  795. Potree.Utils.updateVisible(shape, "forceByUser", show);
  796. }
  797. if(ifDrawVerMeasure){
  798. Potree.Utils.updateVisible(mainPoint.disMeasure1, "forceByUser", show);
  799. Potree.Utils.updateVisible(mainPoint.disMeasure2, "forceByUser", show);
  800. }
  801. viewer.dispatchEvent('content_changed')
  802. }
  803. if(graph){ //多线段形状
  804. let info = {
  805. measureType : 'MulDistance_shape', color : pointMeasureColor
  806. }
  807. let updateMeasure = ()=>{
  808. if(!shape.isNew){//更新中心点和垂线
  809. mainPoint.copy(shape.getCenter())
  810. updateMeasureForPoint(mainPoint)
  811. }
  812. }
  813. if(graph.length == 0){//开始绘制
  814. shape = viewer.measuringTool.startInsertion( info,
  815. () => {
  816. bus.emit("end", ret); //完成
  817. shape.dispatchEvent('cancelSelect')
  818. ifDrawVerMeasure && (createMeasureForPoint(mainPoint) , updateMeasure())
  819. },
  820. () => {
  821. bus.emit("quit", ret); //删除
  822. });
  823. }else{//已经得到全部点
  824. info.points = graph;
  825. info.sid = Math.random()//sid;
  826. info.bus = bus;
  827. shape = viewer.measuringTool.createMeasureFromData(info);
  828. ifDrawVerMeasure && (createMeasureForPoint(mainPoint, disMeasure2points) , updateMeasure())
  829. }
  830. ifDrawVerMeasure && bus.on("graphChange",updateMeasure)
  831. measureFun = getMeasureFunction(shape, bus, true)
  832. shape.mainPoint = mainPoint
  833. //和普通MulDistance不同点:选中才能拖拽 非选中时不展示marker (clickSelected);选中后marker是非选中状态, 但是颜色一样
  834. //https://lanhuapp.com/web/#/item/project/stage?tid=de3e5e3e-a489-4b19-862a-7c87ce113467&pid=fa4ff928-d61e-438a-b8ee-f848048b7f52
  835. }else{//固定点
  836. mainPoint.copy(pos)
  837. mainPoint.isFixPoint = true
  838. mainPoint.pos2d = Potree.Utils.getPos2d(mainPoint, viewer.mainViewport, viewer.renderArea )
  839. ifDrawVerMeasure && createMeasureForPoint(mainPoint, disMeasure2points)
  840. viewer.fixPoints.push(mainPoint)
  841. ifDrawVerMeasure && setTimeout(()=>{
  842. mainPoint.bus.emit('measureChange',[
  843. {line: mainPoint.disMeasure1.points.map(e=>e.clone()), dis: mainPoint.disMeasure1.points[0].distanceTo(mainPoint.disMeasure1.points[1])},
  844. {line: mainPoint.disMeasure2.points.map(e=>e.clone()), dis: mainPoint.disMeasure2.points[0].distanceTo(mainPoint.disMeasure2.points[1])}
  845. ])
  846. },10)
  847. }
  848. ifDrawVerMeasure && viewer.addEventListener('baseLineChanged',baseLineChanged)
  849. const ret = {
  850. bus,
  851. destroy : ()=>{
  852. console.log('destroy' )
  853. ret.quitMeasure()
  854. if(graph){
  855. measureFun.clear()
  856. }else{
  857. let index = viewer.fixPoints.indexOf(mainPoint)
  858. index > -1 && viewer.fixPoints.splice(index,1)
  859. }
  860. },
  861. quitMeasure(){//退出测量模式,删除测量线. 基准线被删时
  862. console.log('quitMeasure' )
  863. if(ifDrawVerMeasure){
  864. ifDrawVerMeasure = false
  865. removeMeasureForPoint(mainPoint)
  866. viewer.removeEventListener('baseLineChanged',baseLineChanged)
  867. }
  868. },
  869. changePos(pos){//固定点修改
  870. console.log('changePos',pos)
  871. mainPoint.copy(pos)
  872. if(ifDrawVerMeasure){
  873. updateMeasureForPoint(mainPoint)
  874. }
  875. },
  876. changeBase(pos){//基准点修改
  877. console.log('changeBase',pos)
  878. if(ifDrawVerMeasure){
  879. mainPoint.basePoint.copy(pos)
  880. updateMeasureForPoint(mainPoint,{onlyBasePoint:true})
  881. }
  882. },
  883. graphDrawComplete: measureFun && measureFun.end,
  884. show:()=>{
  885. setDisplay(true)
  886. },
  887. hide:()=>{
  888. setDisplay(false)
  889. },
  890. selected(state, ignoreShape){
  891. //console.error(mainPoint.index11, 'selected', state)
  892. if(graph){
  893. ignoreShape || measureFun.selected(state)
  894. }
  895. if(ifDrawVerMeasure && mainPoint.disMeasure1){
  896. if(state){
  897. mainPoint.disMeasure1.focus({dontMoveCamera:true, dontEmit:true})
  898. mainPoint.disMeasure2.focus({dontMoveCamera:true, dontEmit:true})
  899. }else{
  900. mainPoint.disMeasure1.dispatchEvent('cancelSelect')
  901. mainPoint.disMeasure2.dispatchEvent('cancelSelect')
  902. }
  903. }
  904. }
  905. };
  906. mainPoint.ret = ret
  907. return ret
  908. },
  909. // 开启放大镜
  910. openMagnifier() {
  911. //console.error('开启放大镜')
  912. viewer.magnifier.dispatchEvent({
  913. type: "setEnable",
  914. value: true
  915. });
  916. },
  917. // 关闭放大镜
  918. closeMagnifier() {
  919. //console.error('关闭放大镜')
  920. viewer.magnifier.dispatchEvent({
  921. type: "setEnable",
  922. value: false
  923. });
  924. },
  925. changePointDensity(levelType) {
  926. //点云密度:低中高
  927. Potree.settings.UserPointDensity = levelType;
  928. return {
  929. percent: Potree.config.pointDensity[levelType].maxLevelPercent,
  930. }; //回调需要更改密度百分比滑动条
  931. },
  932. changeDensityPercent(percent) {
  933. //点云密度百分比(细节) percent : 0-1
  934. //console.log('changeDensityPercent ', percent) //有出现过首次加载大于1的情况???
  935. Potree.settings.UserDensityPercent = percent;
  936. viewer.setPointLevels();
  937. },
  938. // 设置far
  939. changeViewRange(num) {
  940. Potree.settings.cameraFar = num;
  941. },
  942. // 设置色彩模式 0 彩色 1 海拔 2 半透明(透明色)
  943. changeColorMode: function (mode) {
  944. const modes = ["rgba", "elevation", "color"];
  945. mode = modes[mode];
  946. //console.log('设置色彩模式 ', mode)
  947. let otherChange = {};
  948. switch (mode) {
  949. case "rgba": //每个点的颜色
  950. otherChange.opacity = 1;
  951. otherChange.size = 0.4 / 4;
  952. break;
  953. case "elevation":
  954. otherChange.opacity = 0.3;
  955. otherChange.size = 0.4 / 4;
  956. break;
  957. case "color": //透明色
  958. //otherChange.color = ''
  959. otherChange.opacity = 0.3;
  960. otherChange.size = 0.4 / 4;
  961. break;
  962. }
  963. viewer.scene.pointclouds.forEach((e) => {
  964. e.material.activeAttributeName = mode;
  965. });
  966. sdk.scene.changePointSize(otherChange.size);
  967. sdk.scene.changePointOpacity(otherChange.opacity);
  968. delete otherChange.color;
  969. return otherChange;
  970. },
  971. // 设置点大小
  972. changePointSize(num) {
  973. viewer.scene.pointclouds.forEach((e) => {
  974. e.changePointSize(num);
  975. });
  976. },
  977. // 设置点透明度
  978. changePointOpacity: function (num) {
  979. //num:0-1 navvis用的是亮度
  980. viewer.scene.pointclouds.forEach((e) => {
  981. e.changePointOpacity(num);
  982. });
  983. },
  984. // 设置点形状 传入参数 1 矩形 2 圆形
  985. changePointShape(shape) {
  986. viewer.scene.pointclouds.forEach((e) => {
  987. e.material.shape =
  988. Potree.PointShape[shape == 1 ? "SQUARE" : "CIRCLE"]; // and PARABOLOID
  989. });
  990. },
  991. // 设置是否强化边缘
  992. changePointEdge(isStrong) {
  993. //console.log('强化边缘', isStrong)
  994. viewer.setEDLEnabled(isStrong);
  995. },
  996. // 设置漫游点位显示
  997. changePanoPoint(show) {
  998. Potree.settings.ifShowMarker = !!show;
  999. },
  1000. getDownloadInfo() {
  1001. //获取直接下载点云的参数给后台
  1002. return viewer.modules.Clip.downloadNoCrop();
  1003. },
  1004. /* getDataSets() {
  1005. //获取所有数据集对象
  1006. let datasets = CloneJson(Potree.datasetData);
  1007. datasets.forEach((e) => {
  1008. var pointcloud = viewer.scene.pointclouds.find( (p) => p.dataset_id == e.id);
  1009. e.changeDisplay = function (show) {
  1010. Potree.Utils.updateVisible(pointcloud, "datasetSelection", !!show);
  1011. pointcloud.panos.forEach((pano) => {
  1012. //数据集隐藏时漫游点也隐藏 //还是不隐藏了,仅隐藏点云
  1013. Potree.Utils.updateVisible(pano, "pointcloudVisi", show, 0);
  1014. });
  1015. if (
  1016. viewer.modules.SiteModel.editing ||
  1017. viewer.modules.Alignment.editing) {
  1018. viewer.updateFpVisiDatasets();
  1019. }
  1020. };
  1021. e.changeColor = function (color) {
  1022. pointcloud.material.color = color;
  1023. };
  1024. e.getColor = function () {
  1025. return pointcloud.material.color;
  1026. };
  1027. e.focus = function () {
  1028. viewer.modules.Alignment.SplitScreen.focusOnPointCloud(pointcloud);
  1029. };
  1030. e.flyTo = function () {
  1031. return viewer.flyToDataset({
  1032. pointcloud
  1033. }) || false;
  1034. };
  1035. e.getAttachPloygon = function () {
  1036. //计算完后才会有
  1037. return (
  1038. pointcloud.belongToEntity && pointcloud.belongToEntity.polygon);
  1039. };
  1040. });
  1041. return datasets;
  1042. }, */
  1043. screenshot: (width, height, bgOpacity=1) => {
  1044. //截图
  1045. let meterPerPixel,
  1046. isScreenshoting = true;
  1047. var {
  1048. getImagePromise,
  1049. finishPromise
  1050. } = viewer.startScreenshot({
  1051. type: "default",
  1052. hideMarkers:true, bgOpacity
  1053. //hideMeasures:true,
  1054. },
  1055. width,
  1056. height);
  1057. finishPromise.done(() => {
  1058. isScreenshoting = false;
  1059. });
  1060. if(viewer.mainViewport.camera.type == 'OrthographicCamera'){
  1061. meterPerPixel = 1 / viewer.mainViewport.camera.zoom
  1062. }
  1063. return {finishPromise, meterPerPixel};
  1064. },
  1065. canTurnToPanoMode(pos) {
  1066. /* if(viewer.hasNoPanoDataset){
  1067. return
  1068. } */
  1069. pos = pos ? new THREE.Vector3().copy(pos) : viewer.images360.position;
  1070. let pano = viewer.images360.findNearestPano(pos);
  1071. if (
  1072. pano &&
  1073. pano.position.distanceTo(pos) < Potree.config.panoFieldRadius) {
  1074. return true;
  1075. }
  1076. //poschange后会调用这个,如果返回false会变为点云模式,且不会自动变回原先的模式
  1077. },
  1078. trackScenePos(){// 单击场景某个位置 返回当前三维坐标, 调用时场景不能漫游与选择直到获取完成
  1079. let deferred = $.Deferred();
  1080. let quit = ()=>{ //取消获取
  1081. viewer.removeEventListener('global_click',gotIntersect)
  1082. Potree.settings.unableNavigate = false
  1083. Potree.settings.unableUseDepTexPick = false
  1084. viewer.controls.setEnable(true)
  1085. }
  1086. let gotIntersect = (e)=>{
  1087. if(e.intersect && e.intersect.location){
  1088. console.log('quit', e.intersect.location)
  1089. quit()
  1090. deferred.resolve(e.intersect.location)
  1091. }
  1092. }
  1093. viewer.addEventListener('global_click',gotIntersect)
  1094. Potree.settings.unableNavigate = true
  1095. Potree.settings.unableUseDepTexPick = true
  1096. viewer.controls.setEnable(false)
  1097. viewer.scene.measurements.forEach(e=>e.dispatchEvent('cancelSelect')) //避免stopContinue
  1098. return {
  1099. promise: deferred.promise() , //获取的promise, 获取到了返回三维坐标,没获取到返回null
  1100. quit
  1101. }
  1102. },
  1103. getSceneCropSetting(){
  1104. let boxData = viewer.modules.Clip.getBoxData()
  1105. return {
  1106. top : {value:boxData.scaleZ*100, minTop:0, maxTop:10},
  1107. scale : {value: boxData.scaleXY*100},
  1108. rotate : {value: THREE.Math.radToDeg(boxData.rotAngle)},
  1109. //rotByUser : {value:boxData.rotByUser}
  1110. }
  1111. },
  1112. //设置裁剪值
  1113. setSceneCropSetting({top,scale,rotate }){
  1114. viewer.modules.Clip.boxData = {
  1115. scaleZ: top.value/100,
  1116. scaleXY: scale.value/100,
  1117. rotAngle: THREE.Math.degToRad(rotate.value),
  1118. //rotByUser
  1119. }
  1120. viewer.modules.Clip.setBoxPose()
  1121. },
  1122. enterCropSetting(){
  1123. let Clip = viewer.modules.Clip
  1124. Clip.enter()
  1125. return {
  1126. quit(){
  1127. Clip.leave()
  1128. },
  1129. enterSetScale(){
  1130. Clip.box.frameHorizon.visible = true
  1131. },
  1132. leaveSetScale(){
  1133. Clip.box.frameHorizon.visible = false
  1134. },
  1135. enterSetTop(){
  1136. Clip.box.frameVertical.visible = true
  1137. },
  1138. leaveSetTop(){
  1139. Clip.box.frameVertical.visible = false
  1140. },
  1141. enterSetRotate(){
  1142. Clip.box.frameHorizon.visible = true
  1143. Clip.box.frameVertical.visible = true
  1144. },
  1145. leaveSetRotate(){
  1146. Clip.box.frameHorizon.visible = false
  1147. Clip.box.frameVertical.visible = false
  1148. },
  1149. }
  1150. },
  1151. ...parameter.sceneBus,
  1152. },
  1153. transformPoint(point, datasetId, dataset_location) {
  1154. /* //获取由dataset_location转出的position
  1155. var r = datasetId != void 0
  1156. ? Potree.Utils.datasetPosTransform({
  1157. fromDataset: true,
  1158. datasetId,
  1159. position: dataset_location,
  1160. })
  1161. : point;
  1162. return r; */
  1163. return point
  1164. },
  1165. // 坐标转换
  1166. coordTransform: (originType, pos, targetType, datasetId) => {
  1167. // pos 坐标的类型, 当类型为SCREEN时为 { x, y } 其余为 {x, y, z}
  1168. if (pos.z == void 0)
  1169. pos.z = 0; //否则datasetPosTransform NAN 地理注册
  1170. let needMeshLocal;
  1171. if (originType == targetType)
  1172. return pos;
  1173. if (
  1174. originType == CoordType.SCENE_SCREEN ||
  1175. originType == CoordType.MAP_SCREEN) {
  1176. let tool = originType == CoordType.SCENE_SCREEN ? sdk.scene : sdk.map;
  1177. let result = tool.getPointByScreen(pos) || {}; //{ position, datasetId, dataset_location }
  1178. pos = result.position;
  1179. if (!pos)
  1180. return;
  1181. datasetId = result.datasetId;
  1182. originType = CoordType.LOCAL;
  1183. }
  1184. let pointcloud;
  1185. if (datasetId != void 0) {
  1186. pointcloud = viewer.scene.pointclouds.find(
  1187. (p) => p.dataset_id == datasetId);
  1188. }
  1189. if (originType == CoordType.MESH_LOCAL) {
  1190. pos = Potree.Utils.datasetPosTransform({
  1191. fromDataset: true,
  1192. pointcloud,
  1193. position: pos,
  1194. });
  1195. originType = CoordType.LOCAL;
  1196. }
  1197. if (targetType == CoordType.MESH_LOCAL) {
  1198. needMeshLocal = true;
  1199. targetType = CoordType.LOCAL; //先转化为求CoordType.LOCAL
  1200. }
  1201. if (originType == targetType) {
  1202. //for控制点,获取点云未移动前的坐标值。暂且这么写。
  1203. if (needMeshLocal) {
  1204. //var invMatrix = new THREE.Matrix4().getInverse(viewer.scene.pointclouds[0].transformMatrix)
  1205. pos = Potree.Utils.datasetPosTransform({
  1206. toDataset: true,
  1207. pointcloud,
  1208. position: pos,
  1209. });
  1210. }
  1211. return pos;
  1212. }
  1213. //先转成lonlat(高德)
  1214. switch (originType) {
  1215. //EPSG: 4550大地坐标
  1216. case CoordType.EPSE:
  1217. pos = viewer.transform.lonlatTo4550.inverse(pos);
  1218. break;
  1219. //Wgs84 经纬度
  1220. case CoordType.WGS84: //84转高德
  1221. //pos = wgs84ToAMap(pos)
  1222. break;
  1223. // 本地坐标
  1224. case CoordType.LOCAL:
  1225. pos = viewer.transform.lonlatToLocal.inverse(pos);
  1226. }
  1227. // 需要转换成什么类型的坐标
  1228. switch (targetType) {
  1229. case CoordType.SCENE_SCREEN: // 场景屏幕坐标
  1230. pos = sdk.scene.getScreenByPoint(pos);
  1231. break;
  1232. case CoordType.MAP_SCREEN: // 地图屏幕坐标
  1233. pos = sdk.map.getScreenByPoint(pos);
  1234. break;
  1235. //EPSG: 4550大地坐标
  1236. case CoordType.EPSE:
  1237. pos = viewer.transform.lonlatTo4550.forward(pos);
  1238. break;
  1239. //Wgs84 经纬度
  1240. case CoordType.WGS84:
  1241. //pos = aMapToWgs84(pos)
  1242. break;
  1243. //本地坐标
  1244. case CoordType.LOCAL:
  1245. pos = viewer.transform.lonlatToLocal.forward(pos);
  1246. }
  1247. if (needMeshLocal) {
  1248. pos = Potree.Utils.datasetPosTransform({
  1249. toDataset: true,
  1250. pointcloud,
  1251. position: pos,
  1252. });
  1253. }
  1254. return pos;
  1255. },
  1256. enterMeasurement() {
  1257. //进入测量模块
  1258. viewer.setLimitFar(false);
  1259. },
  1260. leaveMeasurement() {
  1261. //退出测量模块
  1262. viewer.setLimitFar(true);
  1263. },
  1264. loadModel(info) {
  1265. info.moveWithPointcloud = true;
  1266. viewer.loadModel(info);
  1267. },
  1268. enterTopView(){
  1269. viewer.navCubeViewer.dispatchEvent('enterTopView')
  1270. },
  1271. leaveTopView(){
  1272. viewer.navCubeViewer.dispatchEvent('leaveTopView')
  1273. },
  1274. reshoot(data){//补拍漫游点,后台没给位姿信息,位置是用户在场景里点选
  1275. console.log('reshot',data)
  1276. const height = 1
  1277. const upVec = new THREE.Vector3(0,0,height)
  1278. let id = getPanoId()
  1279. let info = {
  1280. "uuid": id,
  1281. id,
  1282. "pose": {
  1283. "rotation": { "x": 0, "y": 0, "z": 0, 'w':1 },
  1284. //"translation": new THREE.Vector3().addVectors(data.position, upVec)
  1285. "translation": data.position
  1286. },
  1287. "puck": new THREE.Vector3().subVectors(data.position, upVec),
  1288. /* "group": 1,
  1289. "subgroup": 0,
  1290. "visibles": [],
  1291. "id": 0*/
  1292. imageSrc: data.image
  1293. }
  1294. //var pano = new Panorama(info, viewer.images360);
  1295. viewer.images360.addPano(info)
  1296. Potree.Common.intervalTool.isWaiting('addPanosCallback', ()=>{
  1297. viewer.images360.loadDone()
  1298. },500)
  1299. },
  1300. delReshoot({image}){
  1301. let pano = viewer.images360.panos.find(e=>e.panoData.imageSrc == image)
  1302. if(pano) {
  1303. viewer.images360.deletePano(pano)
  1304. }
  1305. },
  1306. getCurrentPano(){
  1307. let image = viewer.images360.currentPano?.panoData.imageSrc
  1308. return {image}
  1309. }
  1310. ,
  1311. destroy(){//重新创建viewer,删了旧的
  1312. viewer.setDisplay(false)
  1313. }
  1314. };
  1315. Potree.sdk = sdk;
  1316. return sdk;
  1317. };
  1318. export default enter;
  1319. /*
  1320. 热点poi加载到的数据中,pos是错误的,只使用dataset_location
  1321. 关于webgl context lost报错:
  1322. 已知有一iphoneX在创建shadowMap后才报错。
  1323. 所以报错的话很可能是代码中的某一句,去除后就会正常。
  1324. =======
  1325. 如果遇到点云只显示一部分,很可能是裁剪范围出错
  1326. */