Skip to content

Instantly share code, notes, and snippets.

@bertt
Created March 13, 2026 09:31
Show Gist options
  • Select an option

  • Save bertt/326d6fcfebf9e51b044bc3069c1a21cd to your computer and use it in GitHub Desktop.

Select an option

Save bertt/326d6fcfebf9e51b044bc3069c1a21cd to your computer and use it in GitHub Desktop.
3D Visualisation of Sibbe in Giro3D
import "./style.css";
import CoordinateSystem from "@giro3d/giro3d/core/geographic/CoordinateSystem.js";
import Extent from "@giro3d/giro3d/core/geographic/Extent.js";
import Instance from "@giro3d/giro3d/core/Instance.js";
import ColorLayer from "@giro3d/giro3d/core/layer/ColorLayer.js";
import ElevationLayer from "@giro3d/giro3d/core/layer/ElevationLayer.js";
import Map, { defaultMapSubdivisionStrategy } from "@giro3d/giro3d/entities/Map.js";
import Tiles3D from "@giro3d/giro3d/entities/Tiles3D.js";
import MapboxTerrainFormat from "@giro3d/giro3d/formats/MapboxTerrainFormat.js";
import Inspector from "@giro3d/giro3d/gui/Inspector.js";
import TiledImageSource from "@giro3d/giro3d/sources/TiledImageSource.js";
import WmtsSource from "@giro3d/giro3d/sources/WmtsSource.js";
import XYZ from "ol/source/XYZ.js";
import TileGrid from "ol/tilegrid/TileGrid.js";
import { DirectionalLight, Vector3 } from "three";
import { MapControls } from "three/examples/jsm/controls/MapControls.js";
const EPSG_28992_DEF =
"+proj=sterea +lat_0=52.15616055555555 +lon_0=5.38763888888889 +k=0.9999079 +x_0=155000 +y_0=463000 +ellps=bessel +towgs84=565.2369,50.0087,465.658,-0.406857330322,-0.350732676542,1.870347383606,-4.0812 +units=m +no_defs +type=crs";
const CRS = CoordinateSystem.register("EPSG:28992", EPSG_28992_DEF);
const extent = new Extent(
CRS,
180000,
198000,
313000,
323000
);
const instance = new Instance({
target: "view",
crs: CRS,
backgroundColor: 0xf3f6fb,
});
const map = new Map({
extent,
subdivisionThreshold: 1.2,
subdivisionStrategy: defaultMapSubdivisionStrategy,
terrain: {
segments: 16,
},
});
const resolutions = Array.from({ length: 12 }, (_, z) => 3440.64 / 2 ** z);
const rdNewQuadExtent = [
-285401.92,
22598.08,
595401.92,
903401.92,
];
const tileGrid = new TileGrid({
extent: rdNewQuadExtent,
origin: [-285401.92, 903401.92],
resolutions,
tileSize: 256,
});
const sibbeCenter = new Vector3(186592, 317893, 90);
function addSceneLighting() {
const sun = new DirectionalLight("#ffffff", 1.4);
sun.position.set(1, 0, 1).normalize();
sun.updateMatrixWorld(true);
instance.scene.add(sun);
}
async function addLayers() {
const elevationLayer = new ElevationLayer({
name: "ahn5-terrain",
extent,
resolutionFactor: 0.25,
source: new TiledImageSource({
noDataValue: -10000,
format: new MapboxTerrainFormat(),
extent,
source: new XYZ({
projection: "EPSG:28992",
tileGrid,
crossOrigin: "anonymous",
url: "./tiles/{z}/{x}/{y}.png",
}),
}),
});
await map.addLayer(elevationLayer);
const wmtsSource = await WmtsSource.fromCapabilities(
"https://service.pdok.nl/brt/achtergrondkaart/wmts/v2_0?SERVICE=WMTS&REQUEST=GetCapabilities",
{
layer: "standaard",
matrixSet: "EPSG:28992",
imageFormat: "image/png",
},
);
const pdokLayer = new ColorLayer({
name: "pdok-achtergrondkaart",
extent,
preloadImages: false,
source: wmtsSource,
});
await map.addLayer(pdokLayer);
const buildingsTileset = new Tiles3D({
name: "buildings-3dtiles",
url: "./buildings/tileset.json",
errorTarget: 2,
});
await instance.add(buildingsTileset);
}
async function initialize() {
addSceneLighting();
const controls = new MapControls(instance.view.camera, instance.domElement);
controls.enablePan = true;
controls.enableZoom = true;
controls.enableRotate = true;
instance.view.camera.position.set(
sibbeCenter.x - 1000,
sibbeCenter.y - 2000,
sibbeCenter.z + 540,
);
controls.target.copy(sibbeCenter);
controls.update();
instance.view.setControls(controls);
await instance.add(map);
await addLayers();
const inspector = Inspector.attach("inspector", instance, {
title: "Giro3D Inspector",
width: 420,
});
inspector.gui.open();
}
void initialize().catch(console.error);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment