UNPKG

itowns

Version:

A JS/WebGL framework for 3D geospatial data visualization

261 lines (223 loc) 10.3 kB
<!DOCTYPE html> <html> <head> <title>Point Cloud Viewer</title> <style type="text/css"> #info { color: black; position: absolute; top: 0; left: 0; margin-left: 15px; padding: 0.3rem; background-color: white; border: 2px solid black; border-radius: 5px; } .centered { margin-left: auto; margin-right: auto; max-width: 25rem; border: 2px solid black; padding: 1rem; background: rgba(128, 168, 197, 1); border-radius: 5px; display: none; } #viewerDiv { display: none; } input { margin-top: 1rem; font-size: 1rem; } #url { width: calc(100% - 1rem); } #submit { margin-left: 25%; margin-right: 25%; width: 50%; } /* lopocs result display */ table { margin-top: 3rem; width: 100%; border-collapse: collapse; } th, td { padding: 0.3rem; text-align: center; } tr:nth-child(even) { background-color: #c6cfd5; } tr:nth-child(odd) { background-color: #9fc0d5; } #result { display: none; } @media (max-width: 600px) { #info, .dg { display: none; } } </style> <meta charset="UTF-8"> <link rel="stylesheet" type="text/css" href="css/example.css"> <link rel="stylesheet" type="text/css" href="css/LoadingScreen.css"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <div id="viewerDiv"> <div id="info"></div> </div> <div class="centered"> <div id="lopocs"> </div> <div id="itowns"> </div> <h2>Point cloud absolute URL: </h2> <h4>(file.js from PotreeConverter or Lopocs url)</h4> <input id="url" type="url" value="https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/eglise_saint_blaise_arles/eglise_saint_blaise_arles.js"> <input id="submit" type="submit" value="Connect"> <div id="result"> <h3>Available pointclouds:</h3> <table id="dropdown"></table> </div> <!-- POINTCLOUD TABLE SELECTION --> <script type="text/javascript"> function createResultRow(serverUrl, table) { var tr = document.createElement('tr'); var td = document.createElement('td'); td.textContent = table; var td2 = document.createElement('td'); var i = document.createElement('input'); i.value = 'Display'; i.type = 'submit'; function onDisplayClicked() { showPointcloud(serverUrl, undefined, table, false); } i.addEventListener('click', onDisplayClicked); td2.appendChild(i); tr.appendChild(td); tr.appendChild(td2); return tr; } function buildLopocsResultTable(serverUrl, metadata) { document.getElementById('result').style.display = 'block'; var dd = document.getElementById('dropdown'); // clean table while (dd.firstChild) { dd.removeChild(dd.firstChild); } var i; for (i = 0; i < metadata.length; i++) { dd.appendChild(createResultRow(serverUrl, metadata[i].table)); } } function onConnectClicked() { var url = document.getElementById('url').value; // assume that "url ends with .js" == potreeconverter // no .endsWith() in ES5... if (url.indexOf('.js') === (url.length - 3)) { var lastSlashIndex = url.lastIndexOf('/'); var filename = url.substr(lastSlashIndex + 1); showPointcloud(url.substr(0, lastSlashIndex), filename, undefined, true); } else { itowns.Fetcher.json(url + '/infos/sources').then(function(meta) { buildLopocsResultTable(url, meta); }); } } </script> <script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script> <script src="../dist/itowns.js"></script> <script src="js/GUI/LoadingScreen.js"></script> <script src="../dist/debug.js"></script> <script type="text/javascript"> var searchParams = new URL(window.location.href).searchParams; function showPointcloud(serverUrl, fileName, lopocsTable) { var pointcloud; var oldPostUpdate; var viewerDiv; var debugGui; var view; var controls; viewerDiv = document.getElementById('viewerDiv'); viewerDiv.style.display = 'block'; itowns.THREE.Object3D.DefaultUp.set(0, 0, 1); debugGui = new dat.GUI({ width: 400 }); // TODO: do we really need to disable logarithmicDepthBuffer ? view = new itowns.View('EPSG:3946', viewerDiv); setupLoadingScreen(viewerDiv, view); view.mainLoop.gfxEngine.renderer.setClearColor(0xcccccc); // Configure Point Cloud layer pointcloud = new itowns.GeometryLayer('eglise_saint_blaise_arles', new itowns.THREE.Group()); pointcloud.file = fileName || 'infos/sources'; pointcloud.protocol = 'potreeconverter'; pointcloud.url = serverUrl; pointcloud.table = lopocsTable; if (searchParams.get('material') === 'three') { pointcloud.material = new itowns.THREE.PointsMaterial({ color: 0xff8888, sizeAttenuation: false, size: 1, vertexColors: itowns.THREE.VertexColors }); } // point selection on double-click function dblClickHandler(event) { var pick = view.pickObjectsAt(event, 5, pointcloud); for (const p of pick) { console.info('Selected point #' + p.index + ' in position (' + p.object.position.x + ', ' + p.object.position.y + ', ' + p.object.position.z + ') in Points ' + p.object.layer.id); } } view.mainLoop.gfxEngine.renderer.domElement.addEventListener('dblclick', dblClickHandler); function placeCamera(position, lookAt) { view.camera.camera3D.position.set(position.x, position.y, position.z); view.camera.camera3D.lookAt(lookAt); // create controls controls = new itowns.FirstPersonControls(view, { focusOnClick: true }); debugGui.add(controls.options, 'moveSpeed', 1, 100).name('Movement speed'); view.notifyChange(view.camera.camera3D); } // add pointcloud to scene function onLayerReady() { var ratio; var position; var lookAt = new itowns.THREE.Vector3(); var size = new itowns.THREE.Vector3(); pointcloud.root.bbox.getSize(size); pointcloud.root.bbox.getCenter(lookAt); debug.PointCloudDebug.initTools(view, pointcloud, debugGui); view.camera.camera3D.far = 2.0 * size.length(); ratio = size.x / size.z; position = pointcloud.root.bbox.min.clone().add( size.multiply({ x: 0, y: 0, z: ratio * 0.5 })); lookAt.z = pointcloud.root.bbox.min.z; placeCamera(position, lookAt); controls.moveSpeed = size.length() / 3; // update stats window oldPostUpdate = pointcloud.postUpdate; pointcloud.postUpdate = function postUpdate() { var info = document.getElementById('info'); oldPostUpdate.apply(pointcloud, arguments); info.textContent = 'Nb points: ' + pointcloud.displayedCount.toLocaleString(); }; } window.view = view; view.addLayer(pointcloud).then(onLayerReady); } if (searchParams.get('selector')) { document.getElementsByClassName('centered')[0].style.display = 'block'; document.getElementById('submit').addEventListener('click', onConnectClicked); } else { onConnectClicked(); } </script> </body> </html>