UNPKG

potree

Version:

WebGL point cloud viewer - WORK IN PROGRESS

418 lines (342 loc) 11 kB
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <meta name="description" content=""> <meta name="author" content=""> <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no"> <title>lasmap</title> <link rel="stylesheet" href="http://openlayers.org/en/v3.11.2/css/ol.css" type="text/css"> </head> <body> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.4/jquery.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/proj4js/2.3.12/proj4.js"></script> <script src="http://openlayers.org/en/v3.11.2/build/ol.js"></script> <div id="potree_map" style="position: absolute; left: 0px; top: 0px; width: 100%; height: 100%"> <div id="potree_map_content" class="map" style="position: absolute; left: 0px; top: 0px; width: 100%; height: 100%"></div> </div> <script> var gExtent = null; var sourcesLayer = null; var sourcesLabelLayer = null; var dragBoxLayer = null; var sceneProjection = null; var map = null; var olCenter = null; var mapProjectionName = "EPSG:3857"; var mapProjection = proj4.defs(mapProjectionName); var toMap = null; var toScene = null; // from http://stackoverflow.com/questions/901115/how-can-i-get-query-string-values-in-javascript function getParameterByName(name) { name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]"); var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"), results = regex.exec(location.search); return results === null ? "" : decodeURIComponent(results[1].replace(/\+/g, " ")); } var source = getParameterByName("sources"); <!-- INCLUDE SOURCE --> var sourceurl = source.substring(0, source.lastIndexOf("/") + 1) + "sources"; function init(){ gExtent = new ol.geom.LineString([[0,0], [0,0]]); // EXTENT LAYER var feature = new ol.Feature(gExtent); var featureVector = new ol.source.Vector({ features: [feature] }); var visibleBoundsLayer = new ol.layer.Vector({ source: featureVector, style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 255, 255, 0.2)' }), stroke: new ol.style.Stroke({ color: '#0000ff', width: 2 }), image: new ol.style.Circle({ radius: 3, fill: new ol.style.Fill({ color: '#0000ff' }) }) }) }); // SOURCES EXTENT LAYER sourcesLayer = new ol.layer.Vector({ source: new ol.source.Vector({}), style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(0, 0, 150, 0.1)' }), stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 150, 1)', width: 1 }) }) }); // SOURCES LABEL LAYER sourcesLabelLayer = new ol.layer.Vector({ source: new ol.source.Vector({ }), style: new ol.style.Style({ fill: new ol.style.Fill({ color: 'rgba(255, 0, 0, 0.1)' }), stroke: new ol.style.Stroke({ color: 'rgba(255, 0, 0, 1)', width: 2 }) }), minResolution: 0.01, maxResolution: 20 }); var mousePositionControl = new ol.control.MousePosition({ coordinateFormat: ol.coordinate.createStringXY(4), projection: sceneProjection, undefinedHTML: '&nbsp;' }); var DownloadSelectionControl = function(opt_options) { var options = opt_options || {}; // TOGGLE TILES var btToggleTiles = document.createElement('button'); btToggleTiles.innerHTML = 'T'; btToggleTiles.addEventListener('click', function(){ var visible = sourcesLayer.getVisible(); sourcesLayer.setVisible(!visible); sourcesLabelLayer.setVisible(!visible); }, false); btToggleTiles.style.float = "left"; btToggleTiles.title = "show / hide tiles"; // DOWNLOAD SELECTED TILES var link = document.createElement("a"); link.href = "#"; link.download = "list.txt"; link.style.float = "left"; var button = document.createElement('button'); button.innerHTML = 'D'; link.appendChild(button); var this_ = this; var handleDownload = function(e) { var features = selectedFeatures.getArray(); var url = [location.protocol, '//', location.host, location.pathname].join(''); if(features.length === 0){ alert("No tiles were selected. Select area with ctrl + left mouse button!"); e.preventDefault(); e.stopImmediatePropagation(); return false; }else if(features.length === 1){ var feature = features[0]; if(feature.source){ var sourceurl = new URL(document.location.href + "/../" + source + '/../source/' + feature.source.name); link.href = sourceurl.href; link.download = feature.source.name; } }else{ var content = ""; for(var i = 0; i < features.length; i++){ var feature = features[i]; if(feature.source){ var sourceurl = new URL(document.location.href + "/../" + source + '/../source/' + feature.source.name); content += sourceurl.href + "\n"; } } var uri = "data:application/octet-stream;base64,"+btoa(content); link.href = uri; link.download = "list_of_files.txt"; } }; button.addEventListener('click', handleDownload, false); // assemble container var element = document.createElement('div'); element.className = 'ol-unselectable ol-control'; element.appendChild(link); element.appendChild(btToggleTiles); element.style.bottom = "0.5em"; element.style.left = "0.5em"; element.title = "Download file or list of selected tiles. Select tile with left mouse button or area using ctrl + left mouse."; ol.control.Control.call(this, { element: element, target: options.target }); }; ol.inherits(DownloadSelectionControl, ol.control.Control); map = new ol.Map({ controls: ol.control.defaults({ attributionOptions: ({ collapsible: false }) }).extend([ new DownloadSelectionControl(), mousePositionControl ]), layers: [ new ol.layer.Tile({source: new ol.source.OSM()}), sourcesLayer, sourcesLabelLayer, visibleBoundsLayer, ], target: 'potree_map_content', view: new ol.View({ center: olCenter, zoom: 9 }) }); // DRAGBOX / SELECTION dragBoxLayer = new ol.layer.Vector({ source: new ol.source.Vector({}), style: new ol.style.Style({ stroke: new ol.style.Stroke({ color: 'rgba(0, 0, 255, 1)', width: 2 }) }) }); map.addLayer(dragBoxLayer); var select = new ol.interaction.Select(); map.addInteraction(select); var selectedFeatures = select.getFeatures(); var dragBox = new ol.interaction.DragBox({ condition: ol.events.condition.platformModifierKeyOnly }); map.addInteraction(dragBox); dragBox.on('boxend', function(e) { // features that intersect the box are added to the collection of // selected features, and their names are displayed in the "info" // div var extent = dragBox.getGeometry().getExtent(); sourcesLayer.getSource().forEachFeatureIntersectingExtent(extent, function(feature) { selectedFeatures.push(feature); }); }); // clear selection when drawing a new box and when clicking on the map dragBox.on('boxstart', function(e) { selectedFeatures.clear(); }); map.on('click', function() { selectedFeatures.clear(); }); }; function setSceneProjection(proj){ sceneProjection = proj; toMap = proj4(sceneProjection, mapProjection); toScene = proj4(mapProjection, sceneProjection); }; function load(url){ var createLabelStyle = function(text){ var style = new ol.style.Style({ image: new ol.style.Circle({ fill: new ol.style.Fill({ color: 'rgba(100,50,200,0.5)' }), stroke: new ol.style.Stroke({ color: 'rgba(120,30,100,0.8)', width: 3 }) }), text: new ol.style.Text({ font: '12px helvetica,sans-serif', text: text, fill: new ol.style.Fill({ color: '#000' }), stroke: new ol.style.Stroke({ color: '#fff', width: 2 }) }) }); return style; } $.getJSON(url, function(data){ var sources = data.sources; setSceneProjection(data.projection); var extent = { min: [Infinity, Infinity], max: [-Infinity, -Infinity] }; for(var i = 0; i < sources.length; i++){ var source = sources[i]; var name = source.name; var points = source.points; var bounds = source.bounds; extent.min[0] = Math.min(extent.min[0], bounds.min[0]); extent.min[1] = Math.min(extent.min[1], bounds.min[1]); extent.max[0] = Math.max(extent.max[0], bounds.max[0]); extent.max[1] = Math.max(extent.max[1], bounds.max[1]); var mapBounds = { min: toMap.forward( [bounds.min[0], bounds.min[1]] ), max: toMap.forward( [bounds.max[0], bounds.max[1]] ) } var mapCenter = [ (mapBounds.min[0] + mapBounds.max[0]) / 2, (mapBounds.min[1] + mapBounds.max[1]) / 2, ]; var p1 = toMap.forward( [bounds.min[0], bounds.min[1]] ); var p2 = toMap.forward( [bounds.max[0], bounds.min[1]] ); var p3 = toMap.forward( [bounds.max[0], bounds.max[1]] ); var p4 = toMap.forward( [bounds.min[0], bounds.max[1]] ); var boxes = []; //var feature = new ol.Feature({ // 'geometry': new ol.geom.LineString([p1, p2, p3, p4, p1]) //}); var feature = new ol.Feature({ 'geometry': new ol.geom.Polygon([[p1, p2, p3, p4, p1]]) }); feature.source = source; sourcesLayer.getSource().addFeature(feature); feature = new ol.Feature({ geometry: new ol.geom.Point(mapCenter), name: name }); feature.setStyle(createLabelStyle(name)); sourcesLabelLayer.getSource().addFeature(feature); } sceneExtent = extent; var mapExtent = getMapExtent(); var mapCenter = getMapCenter(); var view = map.getView(); view.setCenter(mapCenter); gExtent.setCoordinates([ mapExtent.bottomLeft, mapExtent.bottomRight, mapExtent.topRight, mapExtent.topLeft, mapExtent.bottomLeft ]); view.fit(gExtent, [300, 300], { constrainResolution: false }); }); }; function getMapExtent(){ var e = sceneExtent; var bottomLeft = toMap.forward([e.min[0], e.min[1]]); var bottomRight = toMap.forward([e.max[0], e.min[1]]); var topRight = toMap.forward([e.max[0], e.max[1]]); var topLeft = toMap.forward([e.min[0], e.max[1]]); var mapExtent = { bottomLeft: bottomLeft, bottomRight: bottomRight, topRight: topRight, topLeft: topLeft }; return mapExtent; }; this.getMapCenter = function(){ var mapExtent = getMapExtent(); var mapCenter = [ (mapExtent.bottomLeft[0] + mapExtent.topRight[0]) / 2, (mapExtent.bottomLeft[1] + mapExtent.topRight[1]) / 2 ]; return mapCenter; }; function update(){ requestAnimationFrame(update); }; init(); load(source); update(); </script> </body> </html>