Potree.js 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499
  1. export {config, settings} from "./settings.js";
  2. export * from "./start.js";
  3. export * from "./Actions.js";
  4. export * from "./AnimationPath.js";
  5. export * from "./Annotation.js";
  6. export * from "./defines.js";
  7. export * from "./Enum.js";
  8. export * from "./EventDispatcher.js";
  9. export * from "./Features.js";
  10. export * from "./KeyCodes.js";
  11. export * from "./LRU.js";
  12. export * from "./PointCloudEptGeometry.js";
  13. export * from "./PointCloudOctree.js";
  14. //export * from "./custom/ExtendPointCloudOctree.js";
  15. export * from "./PointCloudOctreeGeometry.js";
  16. export * from "./PointCloudTree.js";
  17. export * from "./Points.js";
  18. // export * from "./Potree_update_visibility.js";
  19. //export * from "./custom/ExtendPotree_update_visibility.js";
  20. export * from "./PotreeRenderer.js";
  21. export * from "./ProfileRequest.js";
  22. export * from "./TextSprite.js";
  23. export * from "./utils.js";
  24. export * from "./Version.js";
  25. export * from "./WorkerPool.js";
  26. export * from "./XHRFactory.js";
  27. export * from "./viewer/SaveProject.js";
  28. export * from "./viewer/LoadProject.js";
  29. export * from "./materials/ClassificationScheme.js";
  30. export * from "./materials/EyeDomeLightingMaterial.js";
  31. export * from "./materials/Gradients.js";
  32. export * from "./materials/NormalizationEDLMaterial.js";
  33. export * from "./materials/NormalizationMaterial.js";
  34. export * from "./materials/PointCloudMaterial.js";
  35. export * from "./loader/POCLoader.js";
  36. export * from "./modules/loader/2.0/OctreeLoader.js";
  37. export * from "./loader/EptLoader.js";
  38. export * from "./loader/ept/BinaryLoader.js";
  39. export * from "./loader/ept/LaszipLoader.js";
  40. export * from "./loader/ept/ZstandardLoader.js";
  41. export * from "./loader/PointAttributes.js";
  42. export * from "./loader/ShapefileLoader.js";
  43. export * from "./loader/GeoPackageLoader.js";
  44. // export * from "./objects/tool/Box3Helper.js";
  45. // export * from "./objects/tool/ClippingTool.js";
  46. // export * from "./objects/tool/ClipVolume.js";
  47. export * from "./utils/Box3Helper.js";
  48. export * from "./utils/ClippingTool.js";
  49. export * from "./utils/ClipVolume.js";
  50. export * from "./utils/GeoTIFF.js";
  51. // export * from "./objects/tool/Measure.js";
  52. // export * from "./objects/tool/MeasuringTool.js";
  53. export * from "./utils/Measure.js";
  54. export * from "./utils/MeasuringTool.js";
  55. export * from "./utils/Message.js";
  56. export * from "./utils/PointCloudSM.js";
  57. // export * from "./objects/tool/PolygonClipVolume.js";
  58. // export * from "./objects/tool/Profile.js";
  59. // export * from "./objects/tool/ProfileTool.js";
  60. // export * from "./objects/tool/ScreenBoxSelectTool.js";
  61. // export * from "./objects/tool/SpotLightHelper.js";
  62. // export * from "./objects/tool/TransformationTool.js";
  63. // export * from "./objects/tool/Volume.js";
  64. // export * from "./objects/tool/VolumeTool.js";
  65. // export * from "./objects/tool/Compass.js";
  66. export * from "./utils/PolygonClipVolume.js";
  67. export * from "./utils/Profile.js";
  68. export * from "./utils/ProfileTool.js";
  69. export * from "./utils/ScreenBoxSelectTool.js";
  70. export * from "./utils/SpotLightHelper.js";
  71. export * from "./utils/TransformationTool.js";
  72. export * from "./utils/Volume.js";
  73. export * from "./utils/VolumeTool.js";
  74. export * from "./utils/Compass.js";
  75. export * from "./viewer/viewer.js";
  76. export * from "./viewer/Scene.js";
  77. export * from "./viewer/HierarchicalSlider.js";
  78. export * from "./modules/OrientedImages/OrientedImages.js";
  79. export * from "./modules/Images360/Images360.js";
  80. export * from "./modules/CameraAnimation/CameraAnimation.js";
  81. export * from "./modules/loader/2.0/OctreeLoader.js";
  82. export {OrbitControls} from "./navigation/OrbitControls.js";
  83. export {FirstPersonControls} from "./navigation/FirstPersonControls.js";
  84. export {EarthControls} from "./navigation/EarthControls.js";
  85. export {DeviceOrientationControls} from "./navigation/DeviceOrientationControls.js";
  86. export {VRControls} from "./navigation/VRControls.js";
  87. //add:
  88. export {Alignment} from "./modules/datasetAlignment/Alignment.js";
  89. import "./extensions/OrthographicCamera.js";
  90. import "./extensions/PerspectiveCamera.js";
  91. import "./extensions/Ray.js";
  92. import {LRU} from "./LRU.js";
  93. import {OctreeLoader} from "./modules/loader/2.0/OctreeLoader.js";
  94. import {POCLoader} from "./loader/POCLoader.js";
  95. import {EptLoader} from "./loader/EptLoader.js";
  96. import {PointCloudOctree} from "./PointCloudOctree.js";
  97. //import {ExtendPointCloudOctree} from "./custom/ExtendPointCloudOctree.js";
  98. import {WorkerPool} from "./WorkerPool.js";
  99. export const workerPool = new WorkerPool();
  100. export const version = {
  101. major: 1,
  102. minor: 8,
  103. suffix: '.0'
  104. };
  105. export let lru = new LRU();
  106. console.log('Potree ' + version.major + '.' + version.minor + version.suffix);
  107. export let pointBudget = 1 * 1000 * 1000;
  108. export let framenumber = 0;
  109. export let numNodesLoading = 0;
  110. export let maxNodesLoading = 4;
  111. export const debug = {};
  112. let scriptPath = "";
  113. if (document.currentScript && document.currentScript.src) {
  114. scriptPath = new URL(document.currentScript.src + '/..').href;
  115. if (scriptPath.slice(-1) === '/') {
  116. scriptPath = scriptPath.slice(0, -1);
  117. }
  118. } else if(import.meta){
  119. scriptPath = new URL(import.meta.url + "/..").href;
  120. if (scriptPath.slice(-1) === '/') {
  121. scriptPath = scriptPath.slice(0, -1);
  122. }
  123. }else {
  124. console.error('Potree was unable to find its script path using document.currentScript. Is Potree included with a script tag? Does your browser support this function?');
  125. }
  126. let resourcePath = scriptPath + '/resources';
  127. // scriptPath: build/potree
  128. // resourcePath:build/potree/resources
  129. export {scriptPath, resourcePath};
  130. //add:
  131. export async function loadFile(path, callback, onError){
  132. if(Potree.fileServer){
  133. Potree.fileServer.get(path).then(data=>{
  134. if(data.data)data = data.data
  135. if(data.data)data = data.data //融合页面getdataset需要查找两次data
  136. callback && callback(data)
  137. }).catch(onError)
  138. }else{
  139. try{
  140. let response = await fetch(path);
  141. let text = await response.text();
  142. var data = JSON.parse(text)
  143. if(data.data) data = data.data
  144. callback && callback(data)
  145. return data
  146. }catch(e){
  147. onError && onError(e)
  148. }
  149. }
  150. //查询: http://192.168.0.26:8080/doc.html#/default/filter-%E6%BC%AB%E6%B8%B8%E7%82%B9/filterUsingGET
  151. }
  152. export async function loadDatasets(callback,sceneCode,onError){//之后直接把path写进来
  153. let path
  154. sceneCode = sceneCode || Potree.settings.number
  155. if(Potree.fileServer){
  156. path = `/laser/dataset/${sceneCode}/getDataSet`
  157. }else{
  158. //path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/datasets`
  159. //现在只能加载得了本地的了
  160. path = `${Potree.settings.urls.prefix}/laser/dataset/${sceneCode}/getDataSet`
  161. //path = `${Potree.scriptPath}/data/${sceneCode}/getDataSet.json`
  162. }
  163. return loadFile(path, callback,onError)
  164. }
  165. //目前上传平面图后如果不点击保存按钮,数据还是旧的不生效
  166. export async function loadMapEntity(datasetId, force){
  167. if(!Potree.settings.floorplanEnable && !force && Potree.fileServer )return /* 等待平面图类型定义好会加载 */
  168. let loaded = 0
  169. let needLoads = datasetId == 'all' ? viewer.scene.pointclouds.map(e=>e.dataset_id) : [datasetId]
  170. let callback = (dataset_id, floorplanType, data )=>{
  171. //要防止旧的比新的先获取到导致覆盖新的,因为两种type随时可能切换
  172. if(floorplanType != Potree.settings.floorplanType[dataset_id]) return //如果请求的floorplanType不是当前最新的floorplanType就返回
  173. var map = viewer.mapViewer.mapLayer.maps.find(e => e.name == 'floorplan_'+ dataset_id)
  174. if(map){
  175. viewer.mapViewer.mapLayer.removeMap(map)
  176. }
  177. var mapNew = viewer.mapViewer.mapLayer.addMapEntity(data.data || data, dataset_id)
  178. if(map){
  179. mapNew.visibleReasons = map.visibleReasons
  180. mapNew.unvisibleReasons = map.unvisibleReasons
  181. }
  182. loaded ++;
  183. }
  184. needLoads.forEach(dataset_id=>{
  185. let floorplanType = Potree.settings.floorplanType[dataset_id], prefix = ''
  186. if(!Potree.fileServer){
  187. prefix = Potree.settings.urls.prefix
  188. }
  189. if(!floorplanType)return
  190. var path
  191. /* if(Potree.fileServer){
  192. path = `/laser/tiledMap/${Potree.settings.number}/tiledMap/${floorplanType}/${dataset_id}`
  193. }else{
  194. path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/tiled_maps`
  195. } */
  196. path = `${prefix}/laser/tiledMap/${Potree.settings.number}/tiledMap/${floorplanType}/${dataset_id}`
  197. Potree.settings.floorplanRequests[dataset_id] = true //开始加载了
  198. return loadFile(path, callback.bind(this, dataset_id, floorplanType) )
  199. })
  200. }
  201. export async function loadPanos(datasetId, callback){
  202. var path
  203. let query = `?datasetId=${datasetId}` //`?lat=${center.lat}&lon=${center.lon}&radius=200000`
  204. if(Potree.fileServer){
  205. path = `/laser/filter/${Potree.settings.number}/query` + query
  206. }else{
  207. //path = `${Potree.settings.urls.prefix2}/indoor/${Potree.settings.number}/api/images/filter` + query
  208. //path = `${Potree.scriptPath}/data/${Potree.settings.number}/panos-${datasetId}.json`
  209. path = `${Potree.settings.urls.prefix}/laser/filter/${Potree.settings.number}/query` + query
  210. }
  211. return loadFile(path, callback)
  212. }
  213. export async function loadPanosInfo(callback){
  214. var path
  215. if(Potree.fileServer){
  216. }else{
  217. path = `${Potree.scriptPath}/data/panoEdit/vision_edit.txt`
  218. }
  219. return loadFile(path, callback)
  220. }
  221. //site_model
  222. /* {
  223. "area": 2503.30551910935,
  224. "attributes": {},
  225. "center": [
  226. 113.59568277455075,
  227. 22.366566635195288,
  228. 12.78751625
  229. ],
  230. "children": [],
  231. "geometry_hash": 1891071345,
  232. "id": 10,
  233. "name": "港湾一号",
  234. "parentId": null,
  235. "polygon": {
  236. "coordinates": [
  237. [
  238. [
  239. 113.59590810534583,
  240. 22.36679132753878
  241. ],
  242. [
  243. 113.59590810534583,
  244. 22.366807172528629
  245. ],
  246. [
  247. 113.59545610274934,
  248. 22.366807172528629
  249. ],
  250. [
  251. 113.59545610274934,
  252. 22.36679132753878
  253. ]
  254. ]
  255. ],
  256. "type": "Polygon"
  257. },
  258. "type": "BUILDING",
  259. "volume": null,
  260. "z_max": null,
  261. "z_min": null
  262. }
  263. */
  264. export function Log(value, color, fontSize){
  265. color = color || '#13f'
  266. fontSize = fontSize || 14
  267. console.warn(`%c${value}`, `color:${color};font-size:${fontSize}px`)
  268. }
  269. export function loadPointCloud(path, name, sceneCode, timeStamp, callback, onError){
  270. let loaded = function(e){
  271. e.pointcloud.name = name;
  272. e.pointcloud.sceneCode = sceneCode //对应4dkk的场景码
  273. callback(e);
  274. };
  275. let promise = new Promise( resolve => {
  276. // load pointcloud
  277. if (!path){
  278. // TODO: callback? comment? Hello? Bueller? Anyone?
  279. } else if (path.indexOf('ept.json') > 0) {
  280. EptLoader.load(path, function(geometry) {
  281. if (!geometry) {
  282. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  283. }
  284. else {
  285. let pointcloud = new PointCloudOctree(geometry);
  286. //loaded(pointcloud);
  287. resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
  288. }
  289. });
  290. } else if (path.indexOf('cloud.js') > 0) {
  291. POCLoader.load(path, timeStamp, function (geometry) {
  292. if (!geometry) {
  293. //callback({type: 'loading_failed'});
  294. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  295. onError && onError()
  296. } else {
  297. let pointcloud = new PointCloudOctree(geometry);
  298. // loaded(pointcloud);
  299. resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
  300. }
  301. });
  302. }/* else if (path.indexOf('metadata.json') > 0) { //部分浏览器(如uc)不支持NodeLoader中的1n的大数据写法
  303. Potree.OctreeLoader.load(path).then(e => {
  304. let geometry = e.geometry;
  305. if(!geometry){
  306. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  307. }else{
  308. let pointcloud = new PointCloudOctree(geometry);
  309. let aPosition = pointcloud.getAttribute("position");
  310. let material = pointcloud.material;
  311. material.elevationRange = [
  312. aPosition.range[0][2],
  313. aPosition.range[1][2],
  314. ];
  315. // loaded(pointcloud);
  316. resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
  317. }
  318. });
  319. OctreeLoader.load(path, function (geometry) {
  320. if (!geometry) {
  321. //callback({type: 'loading_failed'});
  322. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  323. } else {
  324. let pointcloud = new PointCloudOctree(geometry);
  325. // loaded(pointcloud);
  326. resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
  327. }
  328. });
  329. } */else if (path.indexOf('.vpc') > 0) {
  330. PointCloudArena4DGeometry.load(path, function (geometry) {
  331. if (!geometry) {
  332. //callback({type: 'loading_failed'});
  333. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  334. } else {
  335. let pointcloud = new PointCloudArena4D(geometry);
  336. // loaded(pointcloud);
  337. resolve({type: 'pointcloud_loaded', pointcloud: pointcloud});
  338. }
  339. });
  340. } else {
  341. //callback({'type': 'loading_failed'});
  342. console.error(new Error(`failed to load point cloud from URL: ${path}`));
  343. }
  344. });
  345. if(callback){
  346. promise.then(pointcloud => {
  347. loaded(pointcloud);
  348. });
  349. }else{
  350. return promise;
  351. }
  352. };
  353. // add selectgroup
  354. (function($){
  355. $.fn.extend({
  356. selectgroup: function(args = {}){
  357. let elGroup = $(this);
  358. let rootID = elGroup.prop("id");
  359. let groupID = `${rootID}`;
  360. let groupTitle = (args.title !== undefined) ? args.title : "";
  361. let elButtons = [];
  362. elGroup.find("option").each((index, value) => {
  363. let buttonID = $(value).prop("id");
  364. let label = $(value).html();
  365. let optionValue = $(value).prop("value");
  366. let elButton = $(`
  367. <span style="flex-grow: 1; display: inherit">
  368. <label for="${buttonID}" class="ui-button" style="width: 100%; padding: .4em .1em">${label}</label>
  369. <input type="radio" name="${groupID}" id="${buttonID}" value="${optionValue}" style="display: none"/>
  370. </span>
  371. `);
  372. let elLabel = elButton.find("label");
  373. let elInput = elButton.find("input");
  374. elInput.change( () => {
  375. elGroup.find("label").removeClass("ui-state-active");
  376. elGroup.find("label").addClass("ui-state-default");
  377. if(elInput.is(":checked")){
  378. elLabel.addClass("ui-state-active");
  379. }else{
  380. //elLabel.addClass("ui-state-default");
  381. }
  382. });
  383. elButtons.push(elButton);
  384. });
  385. let elFieldset = $(`
  386. <fieldset style="border: none; margin: 0px; padding: 0px">
  387. <legend>${groupTitle}</legend>
  388. <span style="display: flex">
  389. </span>
  390. </fieldset>
  391. `);
  392. let elButtonContainer = elFieldset.find("span");
  393. for(let elButton of elButtons){
  394. elButtonContainer.append(elButton);
  395. }
  396. elButtonContainer.find("label").each( (index, value) => {
  397. $(value).css("margin", "0px");
  398. $(value).css("border-radius", "0px");
  399. $(value).css("border", "1px solid black");
  400. $(value).css("border-left", "none");
  401. });
  402. elButtonContainer.find("label:first").each( (index, value) => {
  403. $(value).css("border-radius", "4px 0px 0px 4px");
  404. });
  405. elButtonContainer.find("label:last").each( (index, value) => {
  406. $(value).css("border-radius", "0px 4px 4px 0px");
  407. $(value).css("border-left", "none");
  408. });
  409. elGroup.empty();
  410. elGroup.append(elFieldset);
  411. }
  412. });
  413. })(jQuery);