enter.js 58 KB

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