From 1979c2a160f2ad306582c60f9ad6be67dfc353ab Mon Sep 17 00:00:00 2001 From: John Rattz Date: Mon, 25 Oct 2021 19:19:56 -0400 Subject: [PATCH] Voxel visualizer: Buttons now working. --- .../dc_fractional_coverage_classifier.py | 2 +- data_cube_utilities/dc_utilities.py | 2 +- data_cube_utilities/dc_water_classifier.py | 2 +- .../voxel_visualizer/template.html | 194 +++--------------- .../voxel_visualizer/voxel_visualizer.py | 40 ++-- dea_tools/dea_tools/datahandling.py | 3 +- 6 files changed, 51 insertions(+), 192 deletions(-) diff --git a/data_cube_utilities/dc_fractional_coverage_classifier.py b/data_cube_utilities/dc_fractional_coverage_classifier.py index 6b28a51e..0df968cc 100644 --- a/data_cube_utilities/dc_fractional_coverage_classifier.py +++ b/data_cube_utilities/dc_fractional_coverage_classifier.py @@ -11,7 +11,7 @@ import argparse import os import collections -import gdal +from osgeo import gdal from datetime import datetime # Author: KMF diff --git a/data_cube_utilities/dc_utilities.py b/data_cube_utilities/dc_utilities.py index 6056ea09..c36257da 100644 --- a/data_cube_utilities/dc_utilities.py +++ b/data_cube_utilities/dc_utilities.py @@ -19,7 +19,7 @@ # License for the specific language governing permissions and limitations # under the License. -import gdal +from osgeo import gdal import numpy as np import xarray as xr import os diff --git a/data_cube_utilities/dc_water_classifier.py b/data_cube_utilities/dc_water_classifier.py index 59defd47..6274e856 100644 --- a/data_cube_utilities/dc_water_classifier.py +++ b/data_cube_utilities/dc_water_classifier.py @@ -33,7 +33,7 @@ # Command line tool imports import argparse import collections -import gdal +from osgeo import gdal from datetime import datetime diff --git a/data_cube_utilities/voxel_visualizer/template.html b/data_cube_utilities/voxel_visualizer/template.html index 8240ec10..d84a28fa 100644 --- a/data_cube_utilities/voxel_visualizer/template.html +++ b/data_cube_utilities/voxel_visualizer/template.html @@ -91,23 +91,15 @@
-
+
- -
-
- -
@@ -260,7 +252,6 @@ const x_dims = data_NJ_array.shape[1]; const y_dims = data_NJ_array.shape[2]; - console.log('Finding Center Point'); // Find Centerpoint let xs = []; let ys = []; @@ -334,6 +325,8 @@ var controls = new OrbitControls(camera, renderer.domElement); controls.damping = 0.2; controls.addEventListener('change', render); + /* end keyboard controls */ + /* button controls */ /** hider button **/ let button_controls_hider = document.getElementById('button_controls_hider'); @@ -350,127 +343,16 @@ button_controls_hider.innerHTML = 'Hide Camera Controls'; } }, false); + /** end hider button **/ + /** button click handlers **/ - /*** zoom handlers ***/ - function getFov() { - return Math.floor( - (2 * - Math.atan(camera.getFilmHeight() / 2 / - camera.getFocalLength()) * - 180) / - Math.PI - ); - } - - // function clickZoom(zoomType) { - // window.parent.postMessage({ - // 'message': '' + camera.getFov() - // },'*'); - // if (value >= 20 && zoomType === "zoomIn") { - // return value - 5; - // } else if (value <= 75 && zoomType === "zoomOut") { - // return value + 5; - // } else { - // return value; - // } - // } - - function clickZoom(zoomType) { - // const diff = (zoomType == 'zoomIn' ? 10 : -10); - const diff = (zoomType == 'zoomIn' ? 10 : -10); - - // window.parent.postMessage({ - // 'message': '' + controls.target - // },'*'); - // [tgt_x, tgt_y, tgt_z, ...rest] = controls.target; - // this.center; - window.parent.postMessage({ - // 'message': ' ' + tgt_x + ' ' + tgt_y + ' ' + tgt_z - 'message': ' ' + controls.position - },'*'); - - // let old_x = camera.position.x; - // let new_x; - // if (Math.abs(old_x) >= diff) { - // let x_diff = (old_x < 0) ? -diff: diff; - // new_x = old_x - x_diff; - // } else {new_x = old_x;} - // let old_y = camera.position.y; - // let new_y; - // if (Math.abs(old_y) >= diff) { - // let y_diff = (old_y < 0) ? -diff: diff; - // new_y = old_y - y_diff; - // } else {new_y = old_y;} - // let old_z = camera.position.z; - // let new_z; - // if (Math.abs(old_z) >= diff) { - // let z_diff = (old_z < 0) ? -diff: diff; - // new_z = old_z - z_diff; - // } else {new_z = old_z;} - // window.parent.postMessage({ - // 'message': '' + old_x + ',' + old_y + ',' + old_z - // },'*'); - // window.parent.postMessage({ - // 'message': '' + new_x + ',' + new_y + ',' + new_z - // },'*'); - // camera.position.set(new_x, new_y, new_z); - - // camera.updateProjectionMatrix(); - } - - function zoomInFunction() { - // const fov = getFov(); - // clickZoom("zoomIn"); - cameraMove('forward'); - camera.updateProjectionMatrix(); - } - - function zoomOutFunction() { - // const fov = getFov(); - // clickZoom("zoomOut"); - cameraMove('backward'); - camera.updateProjectionMatrix(); - } - - // function () { - // window.parent.postMessage({ - // 'message': controls.target.distanceTo(controls.object.position) - // }, '*'); - // // camera_pos = camera.position.clone(); - // // camera - // // camera.position.zoom; - // // x_pos = camera.position.x; - // var zoom = controls.target.distanceTo(controls.object.position) - // zoom - // } - let zoom_in_button = document.getElementById('zoom_in_button'); - zoom_in_button.addEventListener('click', zoomInFunction, false); - let zoom_out_button = document.getElementById('zoom_out_button'); - zoom_out_button.addEventListener('click', zoomOutFunction, false); - /*** movement handlers ***/ function cameraMove(moveDir) { controls.enabled = false; - camera.getWorldDirection(cameraLookDir); - - // const diff = (direction == 'left' ? 10 : -10); - const mag = 5; - // [x,y,z] = camera.getWorldDirection(); - - // let lookDirection = camera.LookDirection; - // let lookDirection = camera.getWorldDirection(controls.target); - // let position = camera.position; - // lookDirection = lookDirection.normalize(); - // position = position + mag * lookDirection; - // camera.Position = position; - - // var lookVector = new THREE.Vector3( 0, 0, - 1 ); - // camera.getWorldDirection(lookVector); + const mag = 10; if (moveDir == 'forward') - // camera.position.addScaledVector(cameraLookDir, mag); camera.translateZ(-mag); else if (moveDir == 'backward') - // camera.position.addScaledVector(cameraLookDir, -mag); camera.translateZ(mag); else if (moveDir == 'left') camera.translateX(-mag); @@ -481,44 +363,22 @@ else if (moveDir == 'down') camera.translateY(-mag); - // let smth = camera.position.addScaledVector(cameraLookDir, mag); - // camera.position.set(smth); - - // window.parent.postMessage({ - // // 'message': '' + lookVector - // 'message': '' + smth - // },'*'); - // let old_x = camera.position.x; - // let new_x; - // if (Math.abs(old_x) >= diff) { - // let x_diff = (old_x < 0) ? -diff: diff; - // new_x = old_x - x_diff; - // } else {new_x = old_x;} - // let old_y = camera.position.y; - // let new_y; - // if (Math.abs(old_y) >= diff) { - // let y_diff = (old_y < 0) ? -diff: diff; - // new_y = old_y - y_diff; - // } else {new_y = old_y;} - // let old_z = camera.position.z; - // let new_z; - // if (Math.abs(old_z) >= diff) { - // let z_diff = (old_z < 0) ? -diff: diff; - // new_z = old_z - z_diff; - // } else {new_z = old_z;} - // window.parent.postMessage({ - // 'message': '' + old_x + ',' + old_y + ',' + old_z - // },'*'); - // window.parent.postMessage({ - // 'message': '' + new_x + ',' + new_y + ',' + new_z - // },'*'); - // camera.position.set(new_x, new_y, new_z); - // camera.position.set(position); - // controls.update(); camera.lookAt(controls.target); + camera.updateProjectionMatrix(); controls.enabled = true; } + function zoomInFunction() { + cameraMove('forward'); + } + let zoom_in_button = document.getElementById('zoom_in_button'); + zoom_in_button.addEventListener('click', zoomInFunction, false); + function zoomOutFunction() { + cameraMove('backward'); + } + let zoom_out_button = document.getElementById('zoom_out_button'); + zoom_out_button.addEventListener('click', zoomOutFunction, false); + function leftFunction() { cameraMove('left'); } @@ -542,10 +402,8 @@ } let down_button = document.getElementById('down_button'); down_button.addEventListener('click', downFunction, false); - - // function rotateLeft() { camera.rotation.x += Math.PI / 8; } - // let rotate_left_button = document.getElementById('rotate_left_button'); - // rotate_left_button.addEventListener('click', rotateLeft, false); + /** end button click handlers **/ + /* end button controls */ /////////////////////////////////////////////////// @@ -755,11 +613,9 @@ var layer = new THREE.Points(geometry, generate_point_cloud_material()); layer.sizeAttenuation = true; layer.sortPoints = true; - // layer.material.transparent = true; - // layer.material.opacity = voxel_opacity; - // layer.material.vertexColors = true; - // layer.material.size = voxel_size; - layers[z] = layer; + layer.material.transparent = true; + layer.material.opacity = voxel_opacity; + layer.material.vertexColors = true; } add_layers_to_scene(); set_voxels_size(); diff --git a/data_cube_utilities/voxel_visualizer/voxel_visualizer.py b/data_cube_utilities/voxel_visualizer/voxel_visualizer.py index 0a40b732..28b83aa4 100644 --- a/data_cube_utilities/voxel_visualizer/voxel_visualizer.py +++ b/data_cube_utilities/voxel_visualizer/voxel_visualizer.py @@ -18,6 +18,23 @@ def voxel_visualize(da: xr.DataArray, **kwargs): """ Show a 3D visualization of a boolean xarray `xr`. + It creates an `iframe` DOM element in the cell's output in Jupyter. + + The camera can be controlled with either: + 1. The mouse and arrow keys OR + 2. Buttons on the right side (hideable) + + There is a slider on the left side with 2 modes - Range and Select. + * Range: This mode shows layers (time slices) after the selected time + (shown as text above the slider) at opacity `voxel_opacity`. + Layers before the selected time are shown in a lower opacity + (more translucent). + * Select: This mode shows only the selected layer at opacity `voxel_opacity`. + Layers other than the selected time are shown in a lower opacity + (more translucent). + + The visualization is created with Three.js. + Parameters ---------- da: xr.DataArray @@ -128,27 +145,14 @@ def _launch_server_if_not_running(): filled_template_sngl_lne_esc_fmt = \ " + ".join(filled_template_sngl_lne_esc_split_fmt) - #
- # overflow:hidden; width:100%; height:100%; - # - # style='display:block;' - # width=600, height=350 vox_vis_server_port = os.environ['VOXEL_VISUALIZER_PORT'] iframe = HTML(f""" -
- - - - - - +