3D Model
The example shows you how to render a 3D model to the map.
Demo
Plain HTML
You can find the live Demo on CodeSandbox here.
1<!DOCTYPE html>2<html lang="en">3<head>4<meta name="viewport" content="initial-scale=1.0" />5<meta charset="UTF-8" />6<title>Basic Map</title>7<link8href="https://maps-gl.nextbillion.io/maps/v2/api/css"9rel="stylesheet"10/>11<style>12* {13margin: 0;14padding: 0;15}16#map {17width: 100vw;18height: 100vh;19}20</style>21</head>22<body>23<div id="map"></div>242526<script src="https://maps-gl.nextbillion.io/maps/v2/api/js"></script>27<script>28// You need to replace the apiKey with yours29nextbillion.setApiKey("your-api-key");30var nbmap = new nextbillion.maps.Map({31container: document.getElementById("map"),32style: "https://api.nextbillion.io/maps/streets/style.json",33zoom: 20,34pitch: 52,35center: { lat: 34.08572, lng: -118.324569 }36});3738// parameters to ensure the model is georeferenced correctly on the map39var modelOrigin = [-118.324424, 34.08572];40var modelAltitude = 0;41var modelRotate = [Math.PI / 2, 0, 0];4243var modelAsMercatorCoordinate = nextbillion.maps.MercatorCoordinate.fromLngLat(44modelOrigin,45modelAltitude46);4748// transformation parameters to position, rotate and scale the 3D model onto the map49var modelTransform = {50translateX: modelAsMercatorCoordinate.x,51translateY: modelAsMercatorCoordinate.y,52translateZ: modelAsMercatorCoordinate.z,53rotateX: modelRotate[0],54rotateY: modelRotate[1],55rotateZ: modelRotate[2],56/* Since our 3D model is in real world meters, a scale transform needs to be57* applied since the CustomLayerInterface expects units in MercatorCoordinates.58*/59scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()60};6162var THREE = window.THREE;6364// configuration of the custom layer for a 3D model per the CustomLayerInterface65var customLayer = {66id: "3d-model",67type: "custom",68renderingMode: "3d",69onAdd: function (map, gl) {70this.camera = new THREE.Camera();71this.scene = new THREE.Scene();7273// create two three.js lights to illuminate the model74var directionalLight = new THREE.DirectionalLight(0xffffff);75directionalLight.position.set(0, -70, 100).normalize();76this.scene.add(directionalLight);7778var directionalLight2 = new THREE.DirectionalLight(0xffffff);79directionalLight2.position.set(0, 70, 100).normalize();80this.scene.add(directionalLight2);8182// use the three.js GLTF loader to add the 3D model to the three.js scene83var loader = new THREE.GLTFLoader();84loader.load(85"https://static.nextbillion.io/docs-next/3d-model-demo.gltf",86function (gltf) {87this.scene.add(gltf.scene);88}.bind(this)89);90this.map = map;9192// use the MapLibre GL JS map canvas for three.js93this.renderer = new THREE.WebGLRenderer({94canvas: map.getCanvas(),95context: gl,96antialias: true97});9899this.renderer.autoClear = false;100},101render: function (gl, matrix) {102var rotationX = new THREE.Matrix4().makeRotationAxis(103new THREE.Vector3(1, 0, 0),104modelTransform.rotateX105);106var rotationY = new THREE.Matrix4().makeRotationAxis(107new THREE.Vector3(0, 1, 0),108modelTransform.rotateY109);110var rotationZ = new THREE.Matrix4().makeRotationAxis(111new THREE.Vector3(0, 0, 1),112modelTransform.rotateZ113);114115var m = new THREE.Matrix4().fromArray(matrix);116var l = new THREE.Matrix4()117.makeTranslation(118modelTransform.translateX,119modelTransform.translateY,120modelTransform.translateZ121)122.scale(123new THREE.Vector3(124modelTransform.scale,125-modelTransform.scale,126modelTransform.scale127)128)129.multiply(rotationX)130.multiply(rotationY)131.multiply(rotationZ);132133this.camera.projectionMatrix = m.multiply(l);134this.renderer.state.reset();135this.renderer.render(this.scene, this.camera);136this.map.triggerRepaint();137}138};139140nbmap.on("style.load", function () {141nbmap.map.addLayer(customLayer);142});143</script>144</body>145</html>146