start.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332
  1. import * as THREE from "../libs/three.js/build/three.module.js";
  2. import {settings, config} from './settings'
  3. import math from './utils/math'
  4. import browser from './utils/browser'
  5. import './extensions/three.shim.js'
  6. import {Utils} from "../src/utils.js"
  7. var start = function(dom, mapDom, number, fileServer, webSite){ //t-Zvd3w0m
  8. /* {
  9. let obj = JSON.parse(localStorage.getItem('setting'))
  10. for(let i in obj){
  11. console.log(i + ': ' + obj[i])
  12. }
  13. }
  14. */
  15. Potree.settings.number = number || 't-o5YMR13'// 't-iksBApb'// 写在viewer前
  16. Potree.fileServer = fileServer
  17. webSite && (Potree.settings.webSite = webSite)
  18. let viewer = new Potree.Viewer(dom , mapDom);
  19. let Alignment = viewer.modules.Alignment
  20. //let pointDensity = config.pointDensity.middle
  21. viewer.setEDLEnabled(false);
  22. viewer.setFOV(config.view.fov);
  23. //viewer.setPointBudget(pointDensity.pointBudget);
  24. viewer.loadSettingsFromURL();
  25. if(!Potree.settings.isOfficial){
  26. viewer.loadGUI(() => {
  27. viewer.setLanguage('en');
  28. //$("#menu_appearance").next().show();
  29. $("#menu_tools").next().show();
  30. $("#menu_scene").next().show();
  31. //$("#siteModel").show();
  32. $("#alignment").show();
  33. viewer.toggleSidebar();
  34. });
  35. Potree.settings.sizeFitToLevel = true//当type为衰减模式时自动根据level调节大小。每长一级,大小就除以2
  36. }
  37. Potree.loadDatasetsCallback = function(data, ifReload){
  38. Potree.datasetData = data
  39. viewer.transform = null
  40. var datasetLength = data.length
  41. var loaded = 0
  42. var loadDone = function(){//点云cloud.js加载完毕后
  43. viewer.updateModelBound()
  44. let {boundSize, center} = viewer.bound
  45. Potree.Log(`中心点: ${math.toPrecision(center.toArray(),2)}, boundSize: ${math.toPrecision(boundSize.toArray(),2)} ` , null, 12)
  46. if(!ifReload){
  47. Potree.Images360Loader.load(viewer, {
  48. boundSize: boundSize.clone(),
  49. center: center.clone()
  50. }, images360 => {
  51. viewer.scene.add360Images(images360);
  52. viewer.mapViewer.addListener(images360)
  53. {//初始位置
  54. var urlFirstView = false
  55. var panoId = browser.urlHasValue('pano',true);
  56. if(panoId != void 0){
  57. var pos
  58. var pano = viewer.images360.panos.find(e=>e.id==panoId);
  59. if(pano){
  60. viewer.images360.focusPano({
  61. pano,
  62. duration:0,
  63. callback:()=>{/* Potree.settings.displayMode = 'showPanos' */}
  64. })
  65. }
  66. }
  67. }
  68. viewer.addObjectTest()
  69. viewer.emit('allLoaded')
  70. });
  71. }
  72. Potree.loadMapEntity() //加载floorplan,不一定成功
  73. if(!ifReload){
  74. viewer.scene.view.setView(//position, target
  75. center.clone().add(new THREE.Vector3(10,5,10)),
  76. center
  77. )
  78. if(!Potree.settings.isOfficial){
  79. setTimeout(//暂时延迟,等focus第一个点之后
  80. ()=>{
  81. // viewer.loadProject(Potree.scriptPath + "/data/t-iksBApb/potree.json5")
  82. },
  83. 500)
  84. }
  85. viewer.dispatchEvent({type:'loadPointCloudDone'})
  86. if(!Potree.settings.UserPointDensity){
  87. Potree.settings.UserPointDensity = 'middle'
  88. }
  89. Potree.Log('loadPointCloudDone 点云加载完毕', null, 10)
  90. }
  91. }
  92. var transformPointcloud = (pointcloud, dataset)=>{
  93. var locationLonLat = dataset.location.slice(0,2)
  94. //当只有一个dataset时,无论如何transform 点云和漫游点都能对应上。
  95. var location = viewer.transform.lonlatToLocal.forward(locationLonLat) //transform.inverse()
  96. //初始化位置
  97. pointcloud.matrixAutoUpdate = false //最好禁止updateMatrix 直接使用matrixWorld
  98. pointcloud.orientationUser = 0
  99. pointcloud.translateUser = new THREE.Vector3;
  100. viewer.sidebar && viewer.sidebar.addAlignmentButton(pointcloud)
  101. //dataset.orientation = 0
  102. Alignment.rotate(pointcloud, null, dataset.orientation)
  103. Alignment.translate(pointcloud, new THREE.Vector3(location[0], location[1], dataset.location[2]))
  104. pointcloud.updateMatrixWorld()
  105. Potree.Log(`点云${pointcloud.dataset_id}旋转值:${pointcloud.orientationUser}, 位置${math.toPrecision(pointcloud.translateUser.toArray(),3)}, 经纬度 ${locationLonLat}, spacing ${pointcloud.material.spacing}`, null, 17 )
  106. //-------------------
  107. //viewer.mapView.showSources(false);
  108. }
  109. data.forEach((dataset,index)=>{
  110. //dataset.location = [ 113.60182446595765,22.364155116865753,0]
  111. //dataset.orientation = -0.9
  112. if(!viewer.transform){//拿任意一个数据集作为基准。它的位置就会是000 (第一个数据集应该一直就是初始数据集吧?)
  113. var locationLonLat = dataset.location.slice(0,2)
  114. proj4.defs("NAVVIS:TMERC", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
  115. proj4.defs("WGS84", "+proj=longlat +ellps=WGS84 +datum=WGS84 +no_defs");
  116. //proj4.defs("pointcloud", viewer.getProjection()); //不用从cloud里拿了
  117. let transform1 = proj4("WGS84", "NAVVIS:TMERC"); //这个ok TMERC是展开的平面投影
  118. let transform2 = proj4("+proj=tmerc +lat_0=0 +lon_0=123 +k=1 +x_0=500000 +y_0=0 +ellps=GRS80 +units=m +no_defs;");
  119. viewer.transform = {
  120. lonlatToLocal : transform1,
  121. lonlatTo4550 : transform2 // 转大地坐标EPSG:4550
  122. }
  123. // proj4(fromProjection, toProjection, coordinates)
  124. //let transform = proj4("WGS84", "pointcloud");
  125. viewer.mapViewer && viewer.mapViewer.mapLayer.maps[0].updateProjection()
  126. }
  127. if(!ifReload){
  128. var cloudPath = `https://${Potree.config.urls.prefix}/${Potree.settings.webSite}/${number}/data/${dataset.name}/webcloud/cloud.js`
  129. var timeStamp = dataset.createTime.replace(/[^0-9]/ig,''); //每重算一次后缀随createTime更新一次
  130. Potree.loadPointCloud(cloudPath, dataset.name , timeStamp, e => {
  131. let scene = viewer.scene;
  132. let pointcloud = e.pointcloud;
  133. let config = Potree.config.material
  134. let material = pointcloud.material;
  135. material.minSize = config.minSize
  136. material.maxSize = config.maxSize
  137. material.pointSizeType = config.pointSizeType //Potree.PointSizeType[config.pointSizeType]//Potree.PointSizeType.ADAPTIVE;//FIXED
  138. pointcloud.changePointSize(config.pointSize) //material.size = config.pointSize;
  139. pointcloud.changePointOpacity(1)
  140. material.shape = Potree.PointShape.SQUARE;
  141. pointcloud.color = pointcloud.material.color = dataset.color
  142. pointcloud.dataset_id = dataset.id;//供漫游点找到属于的dataset点云
  143. pointcloud.timeStamp = timeStamp
  144. pointcloud.panos = []
  145. transformPointcloud(pointcloud,dataset)
  146. scene.addPointCloud(pointcloud);
  147. loaded ++;
  148. if(loaded == datasetLength)loadDone()
  149. })
  150. }else{
  151. let pointcloud = viewer.scene.pointclouds.find(p => p.dataset_id == dataset.id)
  152. if(!pointcloud){
  153. Potree.Log('数据集id变了,自动使用第一个','#500')
  154. pointcloud = viewer.scene.pointclouds[0]
  155. }
  156. //先归零
  157. Alignment.translate(pointcloud, pointcloud.translateUser.clone().negate())
  158. Alignment.rotate(pointcloud, null, - pointcloud.orientationUser)
  159. transformPointcloud(pointcloud, dataset)
  160. }
  161. })
  162. if(ifReload){
  163. loadDone()
  164. }
  165. }
  166. Potree.loadDatasets(Potree.loadDatasetsCallback)
  167. window.testTransform = function(locationLonLat, location1, location2){
  168. proj4.defs("NAVVIS:test", "+proj=tmerc +ellps=WGS84 +lon_0=" + locationLonLat[0].toPrecision(15) + " +lat_0=" + locationLonLat[1].toPrecision(15));
  169. let transform = proj4("WGS84", "NAVVIS:test"); //这个ok navvis里也是这两种转换 见proj4Factory
  170. if(location1){//经纬度
  171. return transform.forward(location1)
  172. }else{
  173. return transform.inverse(location2)
  174. }
  175. }
  176. window.THREE = THREE
  177. window.buttonFunction = function(){
  178. /*
  179. viewer.startScreenshot({type:'measure', measurement:viewer.scene.measurements[0]})
  180. */
  181. viewer.modules.RouteGuider.routeStart = new THREE.Vector3(0,0,-1.3)
  182. viewer.modules.RouteGuider.routeEnd = new THREE.Vector3(-10,0,-1.3)
  183. }
  184. }
  185. /* var changeLog = ()=>{ //如果移动端加了test反而出不来bug的话,用这个
  186. var textarea = document.createElement('textarea');
  187. textarea.id = "consoleLog";
  188. textarea.style.width = '160px';
  189. textarea.style.height = '200px'
  190. textarea.style.position = 'fixed'
  191. textarea.style.right = 0
  192. textarea.style.bottom = '0'
  193. textarea.style['z-index'] = 9999;
  194. textarea.style.color = 'black';
  195. textarea.style.opacity = 0.9;
  196. textarea.style['font-size'] = '12px';
  197. textarea.style['backgroundColor'] = '#ffffff'
  198. document.getElementsByTagName("body")[0].appendChild(textarea);
  199. var list = ["log", "error", "warn", "debug", "info", "time", "timeEnd"]
  200. var exchange = function (o) {
  201. console["old" + o] = console[o];
  202. console[o] = function () {
  203. var args = Array.from(arguments)
  204. console["old" + o].apply(this, arguments)
  205. var t = document.getElementById("consoleLog").innerHTML;
  206. var str = ''
  207. args.forEach(a=>{
  208. str += a + ' '
  209. })
  210. document.getElementById("consoleLog").innerHTML = str + "\n\n" + t;
  211. }
  212. }
  213. for (var i = 0; i < list.length; i++) {
  214. exchange(list[i])
  215. }
  216. }
  217. changeLog() */
  218. export {start}
  219. /*
  220. 坐标转换问题:
  221. 由于控制点可以随便输入,所以本地和地理位置的转换也是可拉伸的。而navvis的转换是等比由中心展开,
  222. 所以对比两种转化方式时误差较大。
  223. 另外地理注册控制点是有参考数据集的,若参考数据集和我放置在0,0,0的数据集一致,就可直接使用,否则要转换。
  224. */