Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PointCloudData reprojection into view CRS ('a la volee') #2272

Open
wants to merge 17 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion config/threeExamples.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export default {
'./utils/WorkerPool.js',
'./capabilities/WebGL.js',
'./libs/ktx-parse.module.js',
'./libs/zstddec.module.js'
'./libs/zstddec.module.js',
'./math/OBB.js',
],
};
144 changes: 144 additions & 0 deletions examples/copc_3d_loader.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
<html>
<head>
<title>Itowns - COPC 3D loader</title>

<meta charset="UTF-8">
<link rel="stylesheet" type="text/css" href="css/example.css">
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">

<style type="text/css">
#description {
z-index: 2;
left: 10px;
}
</style>

<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
</head>
<body>
<div id="description">Specify the URL of a COPC file to load:
<input type="text" id="copc_url" />
<button onclick="readCopcURL()">Load</button>
<button onclick="loadLidarHD()">Load LiDAR HD dataset</button>
<div id="share"></div>
</div>
<div id="viewerDiv">
</div>

<script src="../dist/itowns.js"></script>
<script src="js/GUI/LoadingScreen.js"></script>
<script src="../dist/debug.js"></script>
<script type="text/javascript">
var debugGui = new dat.GUI();
var viewerDiv = document.getElementById('viewerDiv');

var view = new itowns.GlobeView(viewerDiv);

// Add one imagery layer to the scene and the miniView
// This layer is defined in a json file but it could be defined as a plain js
// object. See Layer* for more info.
itowns.Fetcher.json('./layers/JSONLayers/Ortho.json').then(function _(config) {
config.source = new itowns.WMTSSource(config.source);
var layer = new itowns.ColorLayer('Ortho', config);
view.addLayer(layer);
});
// Add two elevation layers.
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
config.source = new itowns.WMTSSource(config.source);
var layer = new itowns.ElevationLayer(config.id, config);
view.addLayer(layer);
}
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);

var layer;

function onLayerReady() {
var lookAt = new itowns.THREE.Vector3();
layer.root.bbox.getCenter(lookAt);
var coordLookAt = new itowns.Coordinates(view.referenceCrs).setFromVector3(lookAt);

var size = new itowns.THREE.Vector3();
layer.root.bbox.getSize(size);

view.controls.lookAtCoordinate({
coord: coordLookAt,
range: 2 * size.length(),
}, false);
}

function readCopcURL() {
const urlParams = new URL(location.href).searchParams
var url = document.getElementById('copc_url').value || urlParams.get('copc');

if (url) {
const options = {};
urlParams.keys().forEach(key => {
if (key !== 'copc') {
if (key.includes('.')) {
params = key.split('.');
let object = options;
params.forEach((subKey, index) => {
if (!object[subKey]) { object[subKey] = {}; }
if (index === params.length - 1) {
object[subKey] = parseFloat(urlParams.get(key));
}
object = object[subKey];
})
} else {
options[key] = parseFloat(urlParams.get(key));
}

}
});
loadCopc(url, options);

document.getElementById('share').innerHTML = '<a href="' +
location.href.replace(location.search, '?copc=' + url) +
'" target="_blank">Link to share this view</a>';
document.getElementById('copc_url').value = url;
}
}

function loadCopc(url, options) {
const source = new itowns.CopcSource({ url });

if (layer) {
debugGui.removeFolder(layer.debugUI);
view.removeLayer('COPC');
view.notifyChange();
layer.delete();
}

const config = {
source,
crs: view.referenceCrs,
sseThreshold: 2,
pointBudget: 3000000,
...options,
}

layer = new itowns.CopcLayer('COPC', config);

itowns.View.prototype.addLayer.call(view, layer).then(onLayerReady);

layer.whenReady
.then(() => debug.PointCloudDebug.initTools(view, layer, debugGui));
}

function loadLidarHD() {
// const url ="https://storage.sbg.cloud.ovh.net/v1/AUTH_63234f509d6048bca3c9fd7928720ca1/ppk-lidar/ML/LHD_FXX_0746_6509_PTS_C_LAMB93_IGN69.copc.laz"
const url ="https://dl-lidar.ign.fr/ppk-lidar/ML/LHD_FXX_0746_6509_PTS_C_LAMB93_IGN69.copc.laz" //fixed with proxy
const options = {
material: {mode: 2},
opacity: 0.5,
}
loadCopc(url, options);
}

readCopcURL();
</script>
</body>
</html>
37 changes: 20 additions & 17 deletions examples/copc_simple_loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
<head>
<meta charset="UTF-8">

<title>Itowns - COPC loader</title>
<title>Itowns - COPC simple loader</title>

<link rel="stylesheet" type="text/css" href="css/example.css">
<link rel="stylesheet" type="text/css" href="css/LoadingScreen.css">
Expand Down Expand Up @@ -35,17 +35,20 @@
<script src="../dist/debug.js"></script>
<script type="text/javascript">
let layer; // COPCLayer
let view;
let control;

const uri = new URL(location);

const gui = new dat.GUI();
const crs = {
'autzen-classified': 'EPSG:2992',
sofi: 'EPSG:32611',
millsite: 'EPSG:6341',
}

const viewerDiv = document.getElementById('viewerDiv');
const view = new itowns.View('EPSG:4326', viewerDiv);
const controls = new itowns.PlanarControls(view);
view.mainLoop.gfxEngine.renderer.setClearColor(0xdddddd);
gui = new dat.GUI();

setUrl(uri.searchParams.get('copc'));
const uri = new URL(location);
setView(uri.searchParams.get('copc'));

function onLayerReady(layer) {
const camera = view.camera.camera3D;
Expand All @@ -69,7 +72,6 @@
view.notifyChange(camera);
}


function readURL() {
const url = document.getElementById('url').value;

Expand All @@ -88,20 +90,21 @@
history.replaceState(null, null, `?${uri.searchParams.toString()}`);

input_url.value = url;
load(url);
location.reload()
}

function setView(url) {
const copcId = url.split('/').pop().split('.').shift();

view = new itowns.View(crs[copcId], viewerDiv);
controls = new itowns.PlanarControls(view);
view.mainLoop.gfxEngine.renderer.setClearColor(0xdddddd);
load(url);
}

function load(url) {
const source = new itowns.CopcSource({ url });

if (layer) {
gui.removeFolder(layer.debugUI);
view.removeLayer('COPC');
view.notifyChange();
layer.delete();
}

layer = new itowns.CopcLayer('COPC', {
source,
crs: view.referenceCrs,
Expand Down
16 changes: 11 additions & 5 deletions examples/entwine_3d_loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@
<div id="description">Specify the URL of a Entwine Point Tree to load:
<input type="text" id="ept_url" />
<button onclick="readEPTURL()">Load</button>
<p>If your dataset is not displaying at the right location,
check that it has been converted in <code>EPSG:4978</code>.</p>
<button onclick="loadGrandLyon()">Load the Grand Lyon
dataset</button>
<div id="share"></div>
</div>
<div id="viewerDiv">
Expand Down Expand Up @@ -71,7 +71,8 @@
}

function readEPTURL() {
var url = document.getElementById('ept_url').value || new URL(location.href).searchParams.get('ept');
const urlParams = new URL(location.href).searchParams
var url = document.getElementById('ept_url').value || urlParams.get('ept');

if (url) {
loadEPT(url);
Expand All @@ -95,12 +96,17 @@

eptLayer = new itowns.EntwinePointTileLayer('Entwine Point Tile', {
source: eptSource,
crs: view.referenceCrs,
});

itowns.View.prototype.addLayer.call(view, eptLayer).then(onLayerReady);

debug.PointCloudDebug.initTools(view, eptLayer, debugGui);
eptLayer.whenReady
.then(() => debug.PointCloudDebug.initTools(view, eptLayer, debugGui));
}

function loadGrandLyon() {
document.getElementById('ept_url').value = 'https://download.data.grandlyon.com/files/grandlyon/imagerie/mnt2018/lidar/ept/';
readEPTURL();
}

readEPTURL();
Expand Down
8 changes: 3 additions & 5 deletions examples/entwine_simple_loader.html
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,11 @@
<script src="js/GUI/LoadingScreen.js"></script>
<script src="../dist/debug.js"></script>
<script type="text/javascript">
itowns.proj4.defs('EPSG:3946', '+proj=lcc +lat_0=46 +lon_0=3 +lat_1=45.25 +lat_2=46.75 +x_0=1700000 +y_0=5200000 +ellps=GRS80 +towgs84=0,0,0,0,0,0,0 +units=m +no_defs +type=crs');

var debugGui = new dat.GUI();
var viewerDiv = document.getElementById('viewerDiv');
viewerDiv.style.display = 'block';
var view = new itowns.View('EPSG:3946', viewerDiv);

var view = new itowns.View('EPSG:3857', viewerDiv);
view.mainLoop.gfxEngine.renderer.setClearColor(0xcccccc);

const controls = new itowns.PlanarControls(view);
Expand All @@ -52,7 +51,7 @@
view.camera3D.far = 2.0 * size.length();

controls.groundLevel = eptLayer.root.bbox.min.z;
var position = eptLayer.root.bbox.min.clone().add(
var position = eptLayer.root.bbox.max.clone().add(
size.multiply({ x: 0, y: 0, z: size.x / size.z })
);

Expand Down Expand Up @@ -96,7 +95,6 @@

const config = {
source: eptSource,
crs: view.referenceCrs,
...options,
}
eptLayer = new itowns.EntwinePointTileLayer('Entwine Point Tile', config);
Expand Down
9 changes: 5 additions & 4 deletions examples/potree_25d_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -60,12 +60,13 @@
view.mainLoop.gfxEngine.renderer.setClearColor(0xcccccc);

// Configure Point Cloud layer
potreeLayer = new itowns.PotreeLayer('eglise_saint_blaise_arles', {
source: new itowns.PotreeSource({
const potreeSource = new itowns.PotreeSource({
file: 'eglise_saint_blaise_arles.js',
url: 'https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/eglise_saint_blaise_arles',
crs: view.referenceCrs,
}),
crs: 'EPSG:3946',
});
potreeLayer = new itowns.PotreeLayer('eglise_saint_blaise_arles', {
source: potreeSource,
});

// point selection on double-click
Expand Down
11 changes: 6 additions & 5 deletions examples/potree_3d_map.html
Original file line number Diff line number Diff line change
Expand Up @@ -61,12 +61,13 @@
view.controls.minDistance = 50;

// Configure Point Cloud layer
potreeLayer = new itowns.PotreeLayer('eglise_saint_blaise_arles', {
source: new itowns.PotreeSource({
file: 'eglise_saint_blaise_arles.js',
const potreeSource = new itowns.PotreeSource({
file: 'eglise_saint_blaise_arles.js',
url: 'https://raw.githubusercontent.com/gmaillet/dataset/master/',
crs: view.referenceCrs,
}),
crs: 'EPSG:4978',
});
potreeLayer = new itowns.PotreeLayer('eglise_saint_blaise_arles', {
source: potreeSource,
});

// add potreeLayer to scene
Expand Down
7 changes: 3 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

23 changes: 22 additions & 1 deletion src/Core/CopcNode.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ class CopcNode extends PointCloudNode {
}

/**
* Create an (A)xis (A)ligned (B)ounding (B)ox for the given node given
* Create an (A)xis (A)ligned (B)ounding (B)ox for the node given
* `this` is its parent.
* @param {CopcNode} node - The child node
*/
Expand Down Expand Up @@ -90,6 +90,27 @@ class CopcNode extends PointCloudNode {
node.bbox.max.copy(node.bbox.min).add(size);
}

/**
* Create an (O)riented (B)ounding (B)ox for the node given
* `this` is its parent.
* @param {CopcNode} childNode - The child node
*/
createChildOBB(childNode) {
const f = 2 ** (childNode.depth - this.depth);

this.obb.getSize(size).divideScalar(f);

position.copy(this).multiplyScalar(f);

translation.subVectors(childNode, position).multiply(size);

childNode.obb = this.obb.clone();
childNode.obb.halfSize.divideScalar(f);

childNode.obb.center = this.obb.center.clone().add(this.obb.halfSize.clone().multiplyScalar(-0.5)).add(translation);
childNode.obb.position = this.obb.position.clone();
}

/**
* Create a CopcNode from the provided subtree and add it as child
* of the current node.
Expand Down
Loading