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 <link
8 href="https://maps-gl.nextbillion.io/maps/v2/api/css"
9 rel="stylesheet"
10 />
11 <style>
12 * {
13 margin: 0;
14 padding: 0;
15 }
16 #map {
17 width: 100vw;
18 height: 100vh;
19 }
20 </style>
21 </head>
22 <body>
23 <div id="map"></div>
24 <script src="https://unpkg.com/[email protected]/build/three.min.js"></script>
25 <script src="https://unpkg.com/[email protected]/examples/js/loaders/GLTFLoader.js"></script>
26 <script src="https://maps-gl.nextbillion.io/maps/v2/api/js"></script>
27 <script>
28 // You need to replace the apiKey with yours
29 nextbillion.setApiKey("your-api-key");
30 var nbmap = new nextbillion.maps.Map({
31 container: document.getElementById("map"),
32 style: "https://api.nextbillion.io/maps/streets/style.json",
33 zoom: 20,
34 pitch: 52,
35 center: { lat: 34.08572, lng: -118.324569 }
36 });
37
38 // parameters to ensure the model is georeferenced correctly on the map
39 var modelOrigin = [-118.324424, 34.08572];
40 var modelAltitude = 0;
41 var modelRotate = [Math.PI / 2, 0, 0];
42
43 var modelAsMercatorCoordinate = nextbillion.maps.MercatorCoordinate.fromLngLat(
44 modelOrigin,
45 modelAltitude
46 );
47
48 // transformation parameters to position, rotate and scale the 3D model onto the map
49 var modelTransform = {
50 translateX: modelAsMercatorCoordinate.x,
51 translateY: modelAsMercatorCoordinate.y,
52 translateZ: modelAsMercatorCoordinate.z,
53 rotateX: modelRotate[0],
54 rotateY: modelRotate[1],
55 rotateZ: modelRotate[2],
56 /* Since our 3D model is in real world meters, a scale transform needs to be
57 * applied since the CustomLayerInterface expects units in MercatorCoordinates.
58 */
59 scale: modelAsMercatorCoordinate.meterInMercatorCoordinateUnits()
60 };
61
62 var THREE = window.THREE;
63
64 // configuration of the custom layer for a 3D model per the CustomLayerInterface
65 var customLayer = {
66 id: "3d-model",
67 type: "custom",
68 renderingMode: "3d",
69 onAdd: function (map, gl) {
70 this.camera = new THREE.Camera();
71 this.scene = new THREE.Scene();
72
73 // create two three.js lights to illuminate the model
74 var directionalLight = new THREE.DirectionalLight(0xffffff);
75 directionalLight.position.set(0, -70, 100).normalize();
76 this.scene.add(directionalLight);
77
78 var directionalLight2 = new THREE.DirectionalLight(0xffffff);
79 directionalLight2.position.set(0, 70, 100).normalize();
80 this.scene.add(directionalLight2);
81
82 // use the three.js GLTF loader to add the 3D model to the three.js scene
83 var loader = new THREE.GLTFLoader();
84 loader.load(
85 "https://static.nextbillion.io/docs-next/3d-model-demo.gltf",
86 function (gltf) {
87 this.scene.add(gltf.scene);
88 }.bind(this)
89 );
90 this.map = map;
91
92 // use the MapLibre GL JS map canvas for three.js
93 this.renderer = new THREE.WebGLRenderer({
94 canvas: map.getCanvas(),
95 context: gl,
96 antialias: true
97 });
98
99 this.renderer.autoClear = false;
100 },
101 render: function (gl, matrix) {
102 var rotationX = new THREE.Matrix4().makeRotationAxis(
103 new THREE.Vector3(1, 0, 0),
104 modelTransform.rotateX
105 );
106 var rotationY = new THREE.Matrix4().makeRotationAxis(
107 new THREE.Vector3(0, 1, 0),
108 modelTransform.rotateY
109 );
110 var rotationZ = new THREE.Matrix4().makeRotationAxis(
111 new THREE.Vector3(0, 0, 1),
112 modelTransform.rotateZ
113 );
114
115 var m = new THREE.Matrix4().fromArray(matrix);
116 var l = new THREE.Matrix4()
117 .makeTranslation(
118 modelTransform.translateX,
119 modelTransform.translateY,
120 modelTransform.translateZ
121 )
122 .scale(
123 new THREE.Vector3(
124 modelTransform.scale,
125 -modelTransform.scale,
126 modelTransform.scale
127 )
128 )
129 .multiply(rotationX)
130 .multiply(rotationY)
131 .multiply(rotationZ);
132
133 this.camera.projectionMatrix = m.multiply(l);
134 this.renderer.state.reset();
135 this.renderer.render(this.scene, this.camera);
136 this.map.triggerRepaint();
137 }
138 };
139
140 nbmap.on("style.load", function () {
141 nbmap.map.addLayer(customLayer);
142 });
143 </script>
144 </body>
145</html>
146
Shape & Symbol
Directions(Simple)