itowns
Version:
A JS/WebGL framework for 3D geospatial data visualization
226 lines (181 loc) • 8.54 kB
HTML
<html>
<head>
<title>Itowns - 3D Tiles loader</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<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;
}
#featureInfoText {
font-size: small;
}
#description .marg {
margin: 10px;
}
</style>
<script src="https://cdnjs.cloudflare.com/ajax/libs/dat-gui/0.7.6/dat.gui.min.js"></script>
</head>
<body>
<div id="viewerDiv"></div>
<div id="description">Specify the URL of a tileset to load:
<input type="text" id="url" />
<button onclick="readURL()">Load</button>
<div class="marg">
<button onClick="loadLyon()">Load Lyon 1 (Mesh)</button>
<button onClick="loadSete()">Load Sete (Point Cloud)</button>
<button onClick="loadLille()">Load Lille (Mesh)</button>
<div id="share"></div>
</div>
<hr />
<p id="featureInfoText" class="marg"><em>Display feature information by clicking on it</em></p>
<p><b>Feature Information:</b></p>
<div id="featureInfo" class="marg"></div>
</div>
<script src="js/GUI/GuiTools.js"></script>
<script src="../dist/itowns.js"></script>
<script src="js/GUI/LoadingScreen.js"></script>
<script src="../dist/debug.js"></script>
<script type="importmap">
{
"imports": {
"three": "https://cdn.jsdelivr.net/npm/three@0.170.0/build/three.module.js",
"three/addons/": "https://cdn.jsdelivr.net/npm/three@0.170.0/examples/jsm/"
}
}
</script>
<script type="module">
import {
AmbientLight,
PMREMGenerator,
} from 'three';
import { MeshoptDecoder } from 'three/addons/libs/meshopt_decoder.module.js';
import { RoomEnvironment } from 'three/addons/environments/RoomEnvironment.js';
import {
zoomToLayer,
fillHTMLWithPickingInfo,
} from './jsm/OGC3DTilesHelper.js';
const {
TMSSource, WMTSSource, OGC3DTilesSource,
ColorLayer, ElevationLayer, OGC3DTilesLayer, PNTS_SIZE_MODE,
GlobeView, Coordinates, Fetcher,
} = itowns;
window.layer = null; // 3D Tiles layer
const uri = new URL(location);
window.gui = new dat.GUI();
// ---- Create a GlobeView ----
// Define camera initial position
const placement = {
coord: new Coordinates('EPSG:4326', 2.351323, 48.856712),
range: 12500000,
};
// `viewerDiv` will contain iTowns' rendering area (`<canvas>`)
const viewerDiv = document.getElementById('viewerDiv');
// Create a GlobeView
const view = new GlobeView(viewerDiv, placement, {
controls: {
minDistance: 100,
}
});
// Enable various compression support for 3D Tiles tileset:
// - `KHR_draco_mesh_compression` mesh compression extension
// - `KHR_texture_basisu` texture compression extension
// - `EXT_meshopt_compression` data compression extension
itowns.enableDracoLoader('./libs/draco/');
itowns.enableKtx2Loader('./lib/basis/', view.renderer);
itowns.enableMeshoptDecoder(MeshoptDecoder);
// Add ambient light to globally illuminates all objects
const light = new AmbientLight(0x404040, 40);
view.scene.add(light);
// Set the environment map for all physical materials in the scene.
// Otherwise, mesh with only diffuse colors will appear black.
const environment = new RoomEnvironment();
const pmremGenerator = new PMREMGenerator(view.renderer);
view.scene.environment = pmremGenerator.fromScene(environment).texture;
pmremGenerator.dispose();
// Setup loading screen
setupLoadingScreen(viewerDiv, view);
// ---- Add a basemap ----
// Add one imagery layer to the scene. This layer's properties are
// defined in a json file, but it cou ld be defined as a plain js
// object. See `Layer` documentation for more info.
Fetcher.json('./layers/JSONLayers/OPENSM.json').then((config) => {
const colorLayer = new ColorLayer('Ortho', {
...config,
source: new TMSSource(config.source),
});
view.addLayer(colorLayer);
});
// ---- Add 3D terrain ----
// Add two elevation layers: world terrain and a more precise terrain for france
// These will deform iTowns globe geometry to represent terrain elevation.
function addElevationLayerFromConfig(config) {
config.source = new itowns.WMTSSource(config.source);
var elevationLayer = new itowns.ElevationLayer(config.id, config);
view.addLayer(elevationLayer);
}
itowns.Fetcher.json('./layers/JSONLayers/IGN_MNT_HIGHRES.json').then(addElevationLayerFromConfig);
itowns.Fetcher.json('./layers/JSONLayers/WORLD_DTM.json').then(addElevationLayerFromConfig);
// ---------- 3D Tiles loading
function readURL() {
const url = document.getElementById('url').value;
if (url) {
setUrl(url);
}
}
function setUrl(url) {
if (!url) return;
const input_url = document.getElementById('url');
if (!input_url) return;
uri.searchParams.set('copc', url);
history.replaceState(null, null, `?${uri.searchParams.toString()}`);
input_url.value = url;
load(url);
}
function load(url) {
const source = new OGC3DTilesSource({ url });
if (window.layer) {
gui.removeFolder('Layer 3DTiles');
view.removeLayer('3DTiles');
view.notifyChange();
window.layer.delete();
}
window.layer = new OGC3DTilesLayer('3DTiles', {
source,
pntsSizeMode: PNTS_SIZE_MODE.ATTENUATED,
});
// Add an event for picking the 3D Tiles layer and displaying
// information about the picked feature in an html div
const pickingArgs = {
htmlDiv: document.getElementById('featureInfo'),
view,
layer: window.layer,
};
// Add the layer to our view
view.addLayer(window.layer).then((layer) => {
zoomToLayer(view, layer);
window.addEventListener('click',
(event) => fillHTMLWithPickingInfo(event, pickingArgs), false);
});
window.layer.whenReady
.then(() => debug.createOGC3DTilesDebugUI(gui, view, window.layer));
}
function loadLyon() {
setUrl("https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/refs/heads/master/3DTiles/lyon1-4978/tileset.json");
}
function loadSete() {
setUrl("https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/pointclouds/pnts-sete-2021-0756_6256/tileset.json");
}
function loadLille() {
setUrl("https://webimaging.lillemetropole.fr/externe/maillage/2020_mel_5cm/tileset.json");
}
window.readURL = readURL;
window.loadLyon = loadLyon;
window.loadSete = loadSete;
window.loadLille = loadLille;
</script>
</body>
</html>