Add a 3D model
Use a custom style layer with three.js to add a 3D model to the map.
Note
If you want to test this example, edit it in JSFiddle or CodePen and replace the "YOUR-OWN-API-KEY" and "YOUR-OWN-VPM-ID" placeholders with your actual api key and vpm id.<!DOCTYPE html><html><head><meta charset="utf-8" /><title>Add a 3D model</title><meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" /><script src="https://unpkg.com/unl-map-js@0.1.5/lib/unl-map-js.js"></script><link href="https://unpkg.com/unl-map-js@0.1.5/lib/unl-map-js.css" rel="stylesheet" /><linkhref="https://unpkg.com/maplibre-gl@2.1.9/dist/maplibre-gl.css"rel="stylesheet"/><style> body { margin: 0; padding: 0; } #map { position: absolute; top: 0; bottom: 0; width: 100%; }</style></head><body><script src="https://unpkg.com/three@0.106.2/build/three.min.js"></script><script src="https://unpkg.com/three@0.106.2/examples/js/loaders/GLTFLoader.js"></script><div id="map"></div><script>var map = (window.map = new UnlSdk.Map({container: "map",zoom: 18,center: [148.9819, -35.3981],pitch: 60,antialias: true, // create the gl context with MSAA antialiasing, so custom layers are antialiasedapiKey: "YOUR-OWN-API-KEY",vpmId: "YOUR-OWN-VPM-ID",})); // parameters to ensure the model is georeferenced correctly on the mapvar modelOrigin = [148.9819, -35.39847];var modelAltitude = 0;var modelRotate = [Math.PI / 2, 0, 0]; var modelAsMercatorCoordinate = UnlSdk.MercatorCoordinate.fromLngLat(modelOrigin,modelAltitude); // transformation parameters to position, rotate and scale the 3D model onto the mapvar modelTransform = {translateX: modelAsMercatorCoordinate.x,translateY: modelAsMercatorCoordinate.y,translateZ: modelAsMercatorCoordinate.z,rotateX: modelRotate[0],rotateY: modelRotate[1],rotateZ: modelRotate[2],/* Since our 3D model is in real world meters, a scale transform needs to be* applied since the CustomLayerInterface expects units in MercatorCoordinates.*/scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits(),}; var THREE = window.THREE; // configuration of the custom layer for a 3D model per the CustomLayerInterfacevar customLayer = {id: "3d-model",type: "custom",renderingMode: "3d",onAdd: function (map, gl) {this.camera = new THREE.Camera();this.scene = new THREE.Scene(); // create two three.js lights to illuminate the modelvar directionalLight = new THREE.DirectionalLight(0xffffff);directionalLight.position.set(0, -70, 100).normalize();this.scene.add(directionalLight); var directionalLight2 = new THREE.DirectionalLight(0xffffff);directionalLight2.position.set(0, 70, 100).normalize();this.scene.add(directionalLight2); // use the three.js GLTF loader to add the 3D model to the three.js scenevar loader = new THREE.GLTFLoader();loader.load("https://u-n-l.github.io/unl-map-js-docs/assets/34M_17/34M_17.gltf",function (gltf) {this.scene.add(gltf.scene);}.bind(this));this.map = map; // use the Unl Map Js map canvas for three.jsthis.renderer = new THREE.WebGLRenderer({canvas: map.getCanvas(),context: gl,antialias: true,}); this.renderer.autoClear = false;},render: function (gl, matrix) {var rotationX = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(1, 0, 0),modelTransform.rotateX);var rotationY = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 1, 0),modelTransform.rotateY);var rotationZ = new THREE.Matrix4().makeRotationAxis(new THREE.Vector3(0, 0, 1),modelTransform.rotateZ); var m = new THREE.Matrix4().fromArray(matrix);var l = new THREE.Matrix4().makeTranslation(modelTransform.translateX,modelTransform.translateY,modelTransform.translateZ).scale(new THREE.Vector3(modelTransform.scale,-modelTransform.scale,modelTransform.scale)).multiply(rotationX).multiply(rotationY).multiply(rotationZ); this.camera.projectionMatrix = m.multiply(l);this.renderer.state.reset();this.renderer.render(this.scene, this.camera);this.map.triggerRepaint();},}; map.on("style.load", function () {map.addLayer(customLayer);});</script> </body></html>