@dvt3d/maplibre-three-plugin 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,272 @@
1
+ # maplibre-three-plugin
2
+
3
+ `maplibre-three-plugin` is a bridge plugin that cleverly connects [MapLibre GL JS](https://maplibre.org/maplibre-gl-js/docs/) with [Three.js](https://threejs.org/), enabling developers to implement 3D rendering and animation on maps.
4
+
5
+ ## Install
6
+
7
+ ```shell
8
+ npm install @dvgis/maplibre-three-plugin
9
+ ----------------------------------------
10
+ yarn add @dvgis/maplibre-three-plugin
11
+ ```
12
+
13
+ ## Quickly Start
14
+
15
+ `maplibre-three-plugin` depends on three, please make sure three is installed before using it.
16
+
17
+ ```html
18
+ <div id="map-container" ></div>
19
+ ```
20
+
21
+ ```javascript
22
+
23
+ import maplibregl from 'maplibre-gl'
24
+ import * as THREE from 'three'
25
+ import { GLTFLoader } from 'three/addons'
26
+ import * as MTP from '@dvt3d/maplibre-three-plugin'
27
+
28
+ const map = new maplibregl.Map({
29
+ container: 'map-container', // container id
30
+ style: 'https://api.maptiler.com/maps/basic-v2/style.json?key=get_access_key',
31
+ zoom: 18,
32
+ center: [148.9819, -35.3981],
33
+ pitch: 60,
34
+ canvasContextAttributes: { antialias: true },
35
+ maxPitch: 85,
36
+ })
37
+
38
+ //init three scene
39
+ const mapScene = new MTP.MapScene(map)
40
+
41
+ //add light
42
+ mapScene.addLight(new THREE.AmbientLight())
43
+
44
+ // add model
45
+ const glTFLoader = new GLTFLoader()
46
+
47
+ glTFLoader.load('./assets/34M_17/34M_17.gltf', (gltf) => {
48
+ let rtcGroup = MTP.Creator.createRTCGroup([148.9819, -35.39847])
49
+ rtcGroup.add(gltf.scene)
50
+ mapScene.addObject(rtcGroup)
51
+ })
52
+ ```
53
+
54
+ ## Examples
55
+ | ![pic](./examples/index.png) | ![pic](./examples/point.png) | ![pic](./examples/point-collection.png) | ![pic](./examples/billboard.png) |
56
+ |:--------------------------------------------------------------------------------:|:--------------------------------------------------------------------------------:|:------------------------------------------------------------------------------------------------:|:----------------------------------------------------------------------------------:|
57
+ | [model](https://dvt3d.github.io/maplibre-three-plugin/examples/index.html) | [point](https://dvt3d.github.io/maplibre-three-plugin/examples/point.html) | [point-collection](https://dvt3d.github.io/maplibre-three-plugin/examples/point-collection.html) | [billboard](https://dvt3d.github.io/maplibre-three-plugin/examples/billboard.html) |
58
+ | ![pic](./examples/div-icon.png) | ![pic](./examples/3d-tiles.png) | ![pic](./examples/3d-tiles-osgb.png) | ![pic](./examples/sun-light.png) |
59
+ | [div-icon](https://dvt3d.github.io/maplibre-three-plugin/examples/div-icon.html) | [3d-tiles](https://dvt3d.github.io/maplibre-three-plugin/examples/3d-tiles.html) | [3d-tiles-osgb](https://dvt3d.github.io/maplibre-three-plugin/examples/3d-tiles-osgb.html) | [sun-light](https://dvt3d.github.io/maplibre-three-plugin/examples/sun-light.html) |
60
+
61
+
62
+ ## Docs
63
+
64
+ ### MapScene
65
+
66
+ #### examples
67
+
68
+ ```js
69
+ const mapScene = new MapScene(map)
70
+ ```
71
+
72
+ #### creation
73
+ - constructor(map,[options])
74
+ - params
75
+ - `{Map} map ` : map instance
76
+ - `{Object} options ` : config
77
+ ```js
78
+ // config
79
+ Object({
80
+ scene: null, //THREE.Scene,if not passed in, the default scene will be used
81
+ camera: null, //THREE.Camera, if not passed in, the default camera will be used
82
+ renderer: null, //THREE.WebGLRenderer if not passed in, the default renderer will be used
83
+ preserveDrawingBuffer: false,
84
+ renderLoop: (ins) =>{} //Frame animation rendering function, if not passed in, the default function will be used,the params is an instance for MapScene
85
+ })
86
+ ```
87
+
88
+ #### event hooks
89
+
90
+ - `preRest` : A hook that calls `renderer.resetState` before each animation frame
91
+ - `postRest`: A hook that calls `renderer.resetState` after each animation frame
92
+ - `preRender`: A hook that calls `renderer.render` before each animation frame
93
+ - `postRender`: A hook that calls `renderer.render` after each animation frame
94
+
95
+ #### properties
96
+
97
+ - `{maplibregl.Map} map ` : `readonly`
98
+ - `{HTMLCanvasElement} canvas ` : `readonly`
99
+ - `{THREE.Camera} camera `: `readonly`
100
+ - `{THREE.Sence} scene` : `readonly`
101
+ - `{THREE.Group} lights`: `readonly`
102
+ - `{THREE.Group} world` : `readonly`
103
+ - `{THREE.WebGLRenderer} renderer` : `readonly`
104
+
105
+ #### methods
106
+
107
+ - **_addLight(light)_**
108
+
109
+ Add light to the scene, support custom light objects, but the custom light objects need to support the `delegate` property, and the `delegate` type is `THREE.Object3D`
110
+ - params
111
+ - `{THREE.Object3D | Sun | CustomLight } light `
112
+ - returns
113
+ - `this`
114
+
115
+ - **_removeLight(light)_**
116
+
117
+ Remove light from the scene
118
+
119
+ - params
120
+ - `{THREE.Object3D | Sun | CustomLight } light `
121
+ - returns
122
+ - `this`
123
+
124
+ - **_addObject(object)_**
125
+
126
+ Add an object to world,support custom object, but the custom object need to support the `delegate` property, and the `delegate` type is `THREE.Object3D`
127
+
128
+ - params
129
+ - `{THREE.Object3D | CustomObject} object `
130
+ - returns
131
+ - `this`
132
+ - **_removeObject(object)_**
133
+
134
+ Remove an object from world
135
+
136
+ - params
137
+ - `{THREE.Object3D | CustomObject} object `
138
+ - returns
139
+ - `this`
140
+
141
+ - **_flyTo(target,[completed],[duration])_**
142
+
143
+ Fly the map to the provided target over a period of time, the completion callback will be triggered when the flight is complete, the target needs to contain the `position` property
144
+
145
+ - params
146
+ - `{THREE.Object3D | CustomObject} target `
147
+ - `{Function} completed `:
148
+ - `{Number} duration `:
149
+ - returns
150
+ - `this`
151
+
152
+ - **_zoomTo(target,[completed])_**
153
+
154
+ Zoom the map to the provided target
155
+
156
+ - params
157
+ - `{Ojbect} target `
158
+ - `{Function} completed `:
159
+ - returns
160
+ - `this`
161
+
162
+ - **_on(type,callback)_**
163
+ - params
164
+ - `{String} type `
165
+ - `{Function} callback `:
166
+ - returns
167
+ - `this`
168
+
169
+ - **_off(type,callback)_**
170
+ - params
171
+ - `{String} type `
172
+ - `{Function} callback `:
173
+ - returns
174
+ - `this`
175
+
176
+ ### SceneTransform
177
+
178
+ #### examples
179
+
180
+ ```js
181
+ const scale = new SceneTransform.projectedUnitsPerMeter(24)
182
+ ```
183
+
184
+ #### static methods
185
+
186
+ - **_projectedMercatorUnitsPerMeter()_**
187
+ - params
188
+ - returns
189
+ - `{Number} value`
190
+
191
+ - **_projectedUnitsPerMeter(lat)_**
192
+ - params
193
+ - `{Number} lat `
194
+ - returns
195
+ - `{Number} value`
196
+
197
+ - **_lngLatToVector3(lng, [lat], [alt] )_**
198
+ - params
199
+ - `{Array | Number} lng `
200
+ - `{ Number} lat `
201
+ - `{ Number} alt `
202
+ - returns
203
+ - `{THREE.Vector3} v`
204
+
205
+ - **_vector3ToLngLat(v)_**
206
+ - params
207
+ - `{THREE.Vector3} v`
208
+ - returns
209
+ - `{Array} value`
210
+
211
+ ### Sun
212
+
213
+ #### examples
214
+
215
+ ```js
216
+ const sun= new Sun()
217
+ ```
218
+
219
+ #### creation
220
+ - constructor()
221
+ - params
222
+
223
+
224
+ #### properties
225
+
226
+ - `{THREE.Group} delegate ` : `readonly`
227
+ - `{Boolean} castShadow `
228
+ - `{Date || String} currentTime `
229
+ - `{THREE.DirectionalLight} sunLight` : `readonly`
230
+ - `{THREE.HemisphereLight} hemiLight`: `readonly`
231
+
232
+ #### methods
233
+
234
+ - **_update(frameState)_**
235
+ - params
236
+ - `{Object} frameState`:
237
+ - returns
238
+ - `this`
239
+
240
+ ### Creator
241
+
242
+ #### examples
243
+
244
+ ```js
245
+ const rtcGroup = Creator.createRTCGroup([-1000,0,0])
246
+ ```
247
+
248
+ #### static methods
249
+
250
+ - **_createRTCGroup(center, [rotation], [scale])_**
251
+ - params
252
+ - `{Array} center`
253
+ - `{Array} rotation`: default value is [0,0,0]
254
+ - `{Array} scale`: scale corresponding to the current latitude
255
+ - returns
256
+ - `{THREE.Group} rtc`
257
+
258
+ - **_createMercatorRTCGroup(center, [rotation], [scale])_**
259
+ - params
260
+ - `{Array} center`
261
+ - `{Array} rotation`: default value is [0,0,0]
262
+ - `{Array} scale`: scale corresponding to the current latitude
263
+ - returns
264
+ - `{THREE.Group} rtc`
265
+
266
+ - **_createShadowGround(center, [width], [height])_**
267
+ - params
268
+ - `{THREE.Vector3} center`
269
+ - `{Number} width`: default value is 100
270
+ - `{Number} height` : default value is 100
271
+ - returns
272
+ - `{Object} rtc`
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ import{Group as it,PerspectiveCamera as vt,Scene as Et,WebGLRenderer as It,EventDispatcher as Pt,Box3 as Dt,Vector3 as Ct}from"three";var P=63710088e-1,D=2*Math.PI*P,m=Math.PI/180,Bt=180/Math.PI,C=1024e3/D,K=512;var j=class{static clamp(t,e,a){return Math.min(a,Math.max(e,t))}static makePerspectiveMatrix(t,e,a,r){let s=1/Math.tan(t/2),n=1/(a-r);return[s/e,0,0,0,0,s,0,0,0,0,(r+a)*n,-1,0,0,2*r*a*n,0]}static mercatorXFromLng(t){return(180+t)/360}static mercatorYFromLat(t){return(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+t*Math.PI/360)))/360}static getViewInfo(t,e,a){let r=t.fov*m,s=t.pitch*m;if(Array.isArray(e)&&(e={lng:e[0],lat:e[1],alt:e[2]||0}),typeof e=="string"){let _=e.split(",");e={lng:_[0],lat:_[1],alt:_[2]||0}}let o=Math.max(a.x,a.y,a.z)/(2*Math.tan(r/2))*Math.cos(s)+e.alt,u=Math.abs(Math.cos(s)*t.cameraToCenterDistance),l=D*Math.abs(Math.cos(e.lat*m)),d=u/o*l,f=Math.round(Math.log2(d/t.tileSize));return{center:[e.lng,e.lat],cameraHeight:o,zoom:f}}static getHeightByZoom(t,e,a,r){let s=Math.abs(Math.cos(r*m)*t.cameraToCenterDistance),n=D*Math.abs(Math.cos(a*m)),o=Math.pow(2,e)*t.tileSize;return s*n/o}static getZoomByHeight(t,e,a,r){let s=Math.abs(Math.cos(r*m)*t.cameraToCenterDistance),n=D*Math.abs(Math.cos(a*m)),o=s/e*n;return Math.round(Math.log2(o/t.tileSize))}},T=j;import{Matrix4 as x,Vector3 as Rt}from"three";var Q=new x,$=new x,tt=85.051129,G=class{constructor(t,e,a){this._map=t,this._world=e,this._camera=a,this._translateCenter=new x().makeTranslation(1024e3/2,-1024e3/2,0),this._worldSizeRatio=K/1024e3,this._map.on("move",this.syncCamera.bind(this)),this._map.on("resize",this.syncCamera.bind(this))}syncCamera(){let t=this._map.transform;this._camera.aspect=t.width/t.height;let e=t.centerOffset||new Rt,a=t.fov*m,r=t.pitch*m,s=t.bearing*m;Q.elements=T.makePerspectiveMatrix(a,this._camera.aspect,t.height/50,t.farZ),this._camera.projectionMatrix=Q,this._camera.projectionMatrix.elements[8]=-e.x*2/t.width,this._camera.projectionMatrix.elements[9]=e.y*2/t.height,$.makeTranslation(0,0,t.cameraToCenterDistance);let n=new x().premultiply($).premultiply(new x().makeRotationX(r)).premultiply(new x().makeRotationZ(-s));t.elevation&&(n.elements[14]=t.cameraToCenterDistance*Math.cos(r)),this._camera.matrixWorld.copy(n);let o=t.scale*this._worldSizeRatio,u=new x().makeScale(o,o,o),l=t.x,d=t.y;if(!l||!d){let g=t.center,w=T.clamp(g.lat,-tt,tt);l=T.mercatorXFromLng(g.lng)*t.worldSize,d=T.mercatorYFromLat(w)*t.worldSize}let f=new x().makeTranslation(-l,d,0),_=new x().makeRotationZ(Math.PI);this._world.matrix=new x().premultiply(_).premultiply(this._translateCenter).premultiply(u).premultiply(f)}},et=G;var k=class{constructor(t,e){this._id=t,this._mapScene=e,this._cameraSync=new et(this._mapScene.map,this._mapScene.world,this._mapScene.camera)}get id(){return this._id}get type(){return"custom"}get renderingMode(){return"3d"}onAdd(t,e){this._cameraSync.syncCamera()}render(){this._mapScene.render()}},rt=k;import{Vector3 as Tt}from"three";var J=class{static projectedMercatorUnitsPerMeter(){return Math.abs(1024e3/D)}static projectedUnitsPerMeter(t){return Math.abs(1024e3/Math.cos(m*t)/D)}static lngLatToVector3(t,e,a=0){let r=[0,0,0];return Array.isArray(t)?(r=[-P*m*t[0]*C,-P*Math.log(Math.tan(Math.PI*.25+.5*m*t[1]))*C],t[2]?r.push(t[2]*this.projectedUnitsPerMeter(t[1])):r.push(0)):(r=[-P*m*t*C,-P*Math.log(Math.tan(Math.PI*.25+.5*m*e))*C],a?r.push(a*this.projectedUnitsPerMeter(e)):r.push(0)),new Tt(r[0],r[1],r[2])}static vector3ToLngLat(t){let e=[0,0,0];return t&&(e[0]=-t.x/(P*m*C),e[1]=2*(Math.atan(Math.exp(t.y/(C*-P)))-Math.PI/4)/m,e[2]=t.z/this.projectedUnitsPerMeter(e[1])),e}},M=J;var At={scene:null,camera:null,renderer:null,renderLoop:null,preserveDrawingBuffer:!1},F=class{constructor(t,e={}){if(!t)throw"missing map";this._map=t,this._options={...At,...e},this._canvas=t.getCanvas(),this._scene=this._options.scene||new Et,this._camera=this._options.camera||new vt(this._map.transform.fov,this._map.transform.width/this._map.transform.height,.1,1e21),this._camera.matrixAutoUpdate=!1,this._renderer=this._options.renderer||new It({alpha:!0,antialias:!0,preserveDrawingBuffer:this._options.preserveDrawingBuffer,canvas:this._canvas,context:this._canvas.getContext("webgl2")}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(this._canvas.clientWidth,this._canvas.clientHeight),this._renderer.autoClear=!1,this._lights=new it,this._lights.name="lights",this._scene.add(this._lights),this._world=new it,this._world.name="world",this._world.userData={isWorld:!0,name:"world"},this._world.position.set(1024e3/2,1024e3/2,0),this._world.matrixAutoUpdate=!1,this._scene.add(this._world),this._map.on("style.load",this._onStyleLoad.bind(this)),this._event=new Pt}get map(){return this._map}get canvas(){return this._canvas}get camera(){return this._camera}get scene(){return this._scene}get lights(){return this._lights}get world(){return this._world}get renderer(){return this._renderer}_onStyleLoad(){this._map.addLayer(new rt("map_scene_layer",this))}render(){if(this._options.renderLoop)this._options.renderLoop(this);else{let t={center:this._map.getCenter(),scene:this._scene,camera:this._camera,renderer:this._renderer};this._event.dispatchEvent({type:"preRest",frameState:t}),this.renderer.resetState(),this._event.dispatchEvent({type:"postRest",frameState:t}),this._event.dispatchEvent({type:"preRender",frameState:t}),this.renderer.render(this._scene,this._camera),this._event.dispatchEvent({type:"postRender",frameState:t})}return this}addLight(t){return this._lights.add(t.delegate||t),this}removeLight(t){return this._lights.remove(t.delegate||t),this}addObject(t){return this._world.add(t.delegate||t),this}removeObject(t){return this._world.remove(t),t.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&(Array.isArray(e.material)?e.material.forEach(a=>a.dispose()):e.material.dispose()),e.texture&&e.texture.dispose()}),this}getViewPosition(){let t=this._map.transform,e=t.center;return{position:[e.lng,e.lat,T.getHeightByZoom(t,t.zoom,e.lat,t.pitch)],heading:t.bearing,pitch:t.pitch}}flyTo(t,e=null,a=3){if(t&&t.position){e&&this._map.once("moveend",e);let r=t.size;r||(r=new Ct,new Dt().setFromObject(t.delegate||t,!0).getSize(r));let s=T.getViewInfo(this._map.transform,M.vector3ToLngLat(t.position),r);this._map.flyTo({center:s.center,zoom:s.zoom,duration:a*1e3})}return this}zoomTo(t,e){return this.flyTo(t,e,0)}flyToPosition(t,e=[0,0,0],a=null,r=3){return a&&this._map.once("moveend",a),this._map.flyTo({center:[t[0],t[1]],zoom:T.getZoomByHeight(this._map.transform,t[2],t[1],e[1]||0),bearing:e[0],pitch:e[1],duration:r*1e3}),this}zoomToPosition(t,e=[0,0,0],a=null,r=3){return this.flyToPosition(t,e,a,0)}on(t,e){return this._event.addEventListener(t,e),this}off(t,e){return this._event.removeEventListener(t,e),this}},at=F;import{Group as Wt,DirectionalLight as jt,HemisphereLight as Gt,Color as yt}from"three";var Z=Math.PI,h=Math.sin,c=Math.cos,B=Math.tan,st=Math.asin,b=Math.atan2,nt=Math.acos,p=Z/180,N=1e3*60*60*24,ot=2440588,ht=2451545;function zt(i){return i.valueOf()/N-.5+ot}function U(i){return new Date((i+.5-ot)*N)}function W(i){return zt(i)-ht}var H=p*23.4397;function ct(i,t){return b(h(i)*c(H)-B(t)*h(H),c(i))}function X(i,t){return st(h(t)*c(H)+c(t)*h(H)*h(i))}function lt(i,t,e){return b(h(i),c(i)*h(t)-B(e)*c(t))}function ut(i,t,e){return st(h(t)*h(e)+c(t)*c(e)*c(i))}function mt(i,t){return p*(280.16+360.9856235*i)-t}function bt(i){return i<0&&(i=0),2967e-7/Math.tan(i+.00312536/(i+.08901179))}function dt(i){return p*(357.5291+.98560028*i)}function pt(i){let t=p*(1.9148*h(i)+.02*h(2*i)+3e-4*h(3*i)),e=p*102.9372;return i+t+e+Z}function ft(i){let t=dt(i),e=pt(t);return{dec:X(e,0),ra:ct(e,0)}}var y={};y.getPosition=function(i,t,e){let a=p*-e,r=p*t,s=W(i),n=ft(s),o=mt(s,a)-n.ra;return{azimuth:lt(o,r,n.dec),altitude:ut(o,r,n.dec)}};var V=y.times=[[-.833,"sunrise","sunset"],[-.3,"sunriseEnd","sunsetStart"],[-6,"dawn","dusk"],[-12,"nauticalDawn","nauticalDusk"],[-18,"nightEnd","night"],[6,"goldenHourEnd","goldenHour"]];y.addTime=function(i,t,e){V.push([i,t,e])};var _t=9e-4;function Ut(i,t){return Math.round(i-_t-t/(2*Z))}function gt(i,t,e){return _t+(i+t)/(2*Z)+e}function Mt(i,t,e){return ht+i+.0053*h(t)-.0069*h(2*e)}function Ot(i,t,e){return nt((h(i)-h(t)*h(e))/(c(t)*c(e)))}function Ht(i){return-2.076*Math.sqrt(i)/60}function Zt(i,t,e,a,r,s,n){let o=Ot(i,e,a),u=gt(o,t,r);return Mt(u,s,n)}y.getTimes=function(i,t,e,a){a=a||0;let r=p*-e,s=p*t,n=Ht(a),o=W(i),u=Ut(o,r),l=gt(0,r,u),d=dt(l),f=pt(d),_=X(f,0),g=Mt(l,d,f),w,A,S,L,R,z,E={solarNoon:U(g),nadir:U(g-.5)};for(w=0,A=V.length;w<A;w+=1)S=V[w],L=(S[0]+n)*p,R=Zt(L,r,s,_,u,d,f),z=g-(R-g),E[S[1]]=U(z),E[S[2]]=U(R);return E};function wt(i){let t=p*(218.316+13.176396*i),e=p*(134.963+13.064993*i),a=p*(93.272+13.22935*i),r=t+p*6.289*h(e),s=p*5.128*h(a),n=385001-20905*c(e);return{ra:ct(r,s),dec:X(r,s),dist:n}}y.getMoonPosition=function(i,t,e){let a=p*-e,r=p*t,s=W(i),n=wt(s),o=mt(s,a)-n.ra,u=ut(o,r,n.dec),l=b(h(o),B(r)*c(n.dec)-h(n.dec)*c(o));return u=u+bt(u),{azimuth:lt(o,r,n.dec),altitude:u,distance:n.dist,parallacticAngle:l}};y.getMoonIllumination=function(i){let t=W(i||new Date),e=ft(t),a=wt(t),r=149598e3,s=nt(h(e.dec)*h(a.dec)+c(e.dec)*c(a.dec)*c(e.ra-a.ra)),n=b(r*h(s),a.dist-r*c(s)),o=b(c(e.dec)*h(e.ra-a.ra),h(e.dec)*c(a.dec)-c(e.dec)*h(a.dec)*c(e.ra-a.ra));return{fraction:(1+c(n))/2,phase:.5+.5*n*(o<0?-1:1)/Math.PI,angle:o}};function O(i,t){return new Date(i.valueOf()+t*N/24)}y.getMoonTimes=function(i,t,e,a){let r=new Date(i);a?r.setUTCHours(0,0,0,0):r.setHours(0,0,0,0);let s=.133*p,n=y.getMoonPosition(r,t,e).altitude-s,o,u,l,d,f,_,g,w,A,S,L,R,z;for(let I=1;I<=24&&(o=y.getMoonPosition(O(r,I),t,e).altitude-s,u=y.getMoonPosition(O(r,I+1),t,e).altitude-s,f=(n+u)/2-o,_=(u-n)/2,g=-_/(2*f),w=(f*g+_)*g+o,A=_*_-4*f*o,S=0,A>=0&&(z=Math.sqrt(A)/(Math.abs(f)*2),L=g-z,R=g+z,Math.abs(L)<=1&&S++,Math.abs(R)<=1&&S++,L<-1&&(L=R)),S===1?n<0?l=I+L:d=I+L:S===2&&(l=I+(w<0?R:L),d=I+(w<0?L:R)),!(l&&d));I+=2)n=u;let E={};return l&&(E.rise=O(r,l)),d&&(E.set=O(r,d)),!l&&!d&&(E[w>0?"alwaysUp":"alwaysDown"]=!0),E};var Lt=y;var Y=class{constructor(){this._delegate=new Wt,this._delegate.name="Sun",this._sunLight=new jt(16777215,1),this._hemiLight=new Gt(new yt(16777215),new yt(16777215),.6),this._hemiLight.color.setHSL(.661,.96,.12),this._hemiLight.groundColor.setHSL(.11,.96,.14),this._hemiLight.position.set(0,0,50),this._delegate.add(this._sunLight),this._delegate.add(this._hemiLight),this._currentTime=null}get delegate(){return this._delegate}set castShadow(t){this._sunLight.castShadow=t}get castShadow(){return this._sunLight.castShadow}set currentTime(t){this._currentTime=t}get currentTime(){return this._currentTime}get sunLight(){return this._sunLight}get hemiLight(){return this._hemiLight}setShadow(t={}){return this._sunLight.shadow.radius=t.radius||2,this._sunLight.shadow.mapSize.width=t.mapSize?t.mapSize[0]:8192,this._sunLight.shadow.mapSize.height=t.mapSize?t.mapSize[1]:8192,this._sunLight.shadow.camera.top=this._sunLight.shadow.camera.right=t.topRight||1e3,this._sunLight.shadow.camera.bottom=this._sunLight.shadow.camera.left=t.bottomLeft||-1e3,this._sunLight.shadow.camera.near=t.near||1,this._sunLight.shadow.camera.far=t.far||1e8,this._sunLight.shadow.camera.visible=!0,this}update(t){let a=new Date(this._currentTime||new Date().getTime()),r=t.center,s=Lt.getPosition(a,r.lat,r.lng),n=s.altitude,o=Math.PI+s.azimuth,u=1024e3/2,l=Math.sin(n),d=Math.cos(n),f=Math.cos(o)*d,_=Math.sin(o)*d;this._sunLight.position.set(_,f,l),this._sunLight.position.multiplyScalar(u),this._sunLight.intensity=Math.max(l,0),this._hemiLight.intensity=Math.max(l*1,.1),this._sunLight.updateMatrixWorld()}},St=Y;import{Group as kt,Mesh as Jt,PlaneGeometry as Ft,ShadowMaterial as Vt}from"three";var q=class{static createRTCGroup(t,e,a){let r=new kt;if(r.name="rtc",r.position.copy(M.lngLatToVector3(t)),e?(r.rotateX(e[0]||0),r.rotateY(e[1]||0),r.rotateZ(e[2]||0)):(r.rotateX(Math.PI/2),r.rotateY(Math.PI)),a)r.scale.set(a[0]||1,a[1]||1,a[2]||1);else{let s=1;Array.isArray(t)?s=M.projectedUnitsPerMeter(t[1]):typeof t=="string"&&(s=M.projectedUnitsPerMeter(t.split(",")[1])),r.scale.set(s,s,s)}return r}static createMercatorRTCGroup(t,e,a){let r=this.createRTCGroup(t,e,a);if(!a){let s=1,n=M.projectedMercatorUnitsPerMeter();Array.isArray(t)?s=M.projectedUnitsPerMeter(t[1]):typeof t=="string"&&(s=M.projectedUnitsPerMeter(t.split(",")[1])),r.scale.set(n,n,s)}return r}static createShadowGround(t,e=100,a=100){let r=new Ft(e,a),s=new Vt({opacity:.5,transparent:!0}),n=new Jt(r,s);return n.position.copy(M.lngLatToVector3(t)),n.receiveShadow=!0,n.name="shadow-ground",n}},xt=q;export{xt as Creator,at as MapScene,M as SceneTransform,St as Sun};
@@ -0,0 +1 @@
1
+ (()=>{var Dt=Object.create;var rt=Object.defineProperty;var Ct=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var zt=Object.getPrototypeOf,bt=Object.prototype.hasOwnProperty;var Ut=(i,t)=>()=>(t||i((t={exports:{}}).exports,t),t.exports);var Ht=(i,t,e,s)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of At(t))!bt.call(i,r)&&r!==e&&rt(i,r,{get:()=>t[r],enumerable:!(s=Ct(t,r))||s.enumerable});return i};var Z=(i,t,e)=>(e=i!=null?Dt(zt(i)):{},Ht(t||!i||!i.__esModule?rt(e,"default",{value:i,enumerable:!0}):e,i));var O=Ut((Vt,it)=>{it.exports=THREE});var g=Z(O(),1);var C=63710088e-1,A=2*Math.PI*C,m=Math.PI/180,Bt=180/Math.PI,b=1024e3/A,st=512;var V=class{static clamp(t,e,s){return Math.min(s,Math.max(e,t))}static makePerspectiveMatrix(t,e,s,r){let a=1/Math.tan(t/2),n=1/(s-r);return[a/e,0,0,0,0,a,0,0,0,0,(r+s)*n,-1,0,0,2*r*s*n,0]}static mercatorXFromLng(t){return(180+t)/360}static mercatorYFromLat(t){return(180-180/Math.PI*Math.log(Math.tan(Math.PI/4+t*Math.PI/360)))/360}static getViewInfo(t,e,s){let r=t.fov*m,a=t.pitch*m;if(Array.isArray(e)&&(e={lng:e[0],lat:e[1],alt:e[2]||0}),typeof e=="string"){let _=e.split(",");e={lng:_[0],lat:_[1],alt:_[2]||0}}let o=Math.max(s.x,s.y,s.z)/(2*Math.tan(r/2))*Math.cos(a)+e.alt,u=Math.abs(Math.cos(a)*t.cameraToCenterDistance),l=A*Math.abs(Math.cos(e.lat*m)),d=u/o*l,f=Math.round(Math.log2(d/t.tileSize));return{center:[e.lng,e.lat],cameraHeight:o,zoom:f}}static getHeightByZoom(t,e,s,r){let a=Math.abs(Math.cos(r*m)*t.cameraToCenterDistance),n=A*Math.abs(Math.cos(s*m)),o=Math.pow(2,e)*t.tileSize;return a*n/o}static getZoomByHeight(t,e,s,r){let a=Math.abs(Math.cos(r*m)*t.cameraToCenterDistance),n=A*Math.abs(Math.cos(s*m)),o=a/e*n;return Math.round(Math.log2(o/t.tileSize))}},E=V;var w=Z(O(),1),at=new w.Matrix4,nt=new w.Matrix4,ot=85.051129,B=class{constructor(t,e,s){this._map=t,this._world=e,this._camera=s,this._translateCenter=new w.Matrix4().makeTranslation(1024e3/2,-1024e3/2,0),this._worldSizeRatio=st/1024e3,this._map.on("move",this.syncCamera.bind(this)),this._map.on("resize",this.syncCamera.bind(this))}syncCamera(){let t=this._map.transform;this._camera.aspect=t.width/t.height;let e=t.centerOffset||new w.Vector3,s=t.fov*m,r=t.pitch*m,a=t.bearing*m;at.elements=E.makePerspectiveMatrix(s,this._camera.aspect,t.height/50,t.farZ),this._camera.projectionMatrix=at,this._camera.projectionMatrix.elements[8]=-e.x*2/t.width,this._camera.projectionMatrix.elements[9]=e.y*2/t.height,nt.makeTranslation(0,0,t.cameraToCenterDistance);let n=new w.Matrix4().premultiply(nt).premultiply(new w.Matrix4().makeRotationX(r)).premultiply(new w.Matrix4().makeRotationZ(-a));t.elevation&&(n.elements[14]=t.cameraToCenterDistance*Math.cos(r)),this._camera.matrixWorld.copy(n);let o=t.scale*this._worldSizeRatio,u=new w.Matrix4().makeScale(o,o,o),l=t.x,d=t.y;if(!l||!d){let M=t.center,y=E.clamp(M.lat,-ot,ot);l=E.mercatorXFromLng(M.lng)*t.worldSize,d=E.mercatorYFromLat(y)*t.worldSize}let f=new w.Matrix4().makeTranslation(-l,d,0),_=new w.Matrix4().makeRotationZ(Math.PI);this._world.matrix=new w.Matrix4().premultiply(_).premultiply(this._translateCenter).premultiply(u).premultiply(f)}},ht=B;var N=class{constructor(t,e){this._id=t,this._mapScene=e,this._cameraSync=new ht(this._mapScene.map,this._mapScene.world,this._mapScene.camera)}get id(){return this._id}get type(){return"custom"}get renderingMode(){return"3d"}onAdd(t,e){this._cameraSync.syncCamera()}render(){this._mapScene.render()}},ct=N;var lt=Z(O(),1);var X=class{static projectedMercatorUnitsPerMeter(){return Math.abs(1024e3/A)}static projectedUnitsPerMeter(t){return Math.abs(1024e3/Math.cos(m*t)/A)}static lngLatToVector3(t,e,s=0){let r=[0,0,0];return Array.isArray(t)?(r=[-C*m*t[0]*b,-C*Math.log(Math.tan(Math.PI*.25+.5*m*t[1]))*b],t[2]?r.push(t[2]*this.projectedUnitsPerMeter(t[1])):r.push(0)):(r=[-C*m*t*b,-C*Math.log(Math.tan(Math.PI*.25+.5*m*e))*b],s?r.push(s*this.projectedUnitsPerMeter(e)):r.push(0)),new lt.Vector3(r[0],r[1],r[2])}static vector3ToLngLat(t){let e=[0,0,0];return t&&(e[0]=-t.x/(C*m*b),e[1]=2*(Math.atan(Math.exp(t.y/(b*-C)))-Math.PI/4)/m,e[2]=t.z/this.projectedUnitsPerMeter(e[1])),e}},L=X;var Ot={scene:null,camera:null,renderer:null,renderLoop:null,preserveDrawingBuffer:!1},Y=class{constructor(t,e={}){if(!t)throw"missing map";this._map=t,this._options={...Ot,...e},this._canvas=t.getCanvas(),this._scene=this._options.scene||new g.Scene,this._camera=this._options.camera||new g.PerspectiveCamera(this._map.transform.fov,this._map.transform.width/this._map.transform.height,.1,1e21),this._camera.matrixAutoUpdate=!1,this._renderer=this._options.renderer||new g.WebGLRenderer({alpha:!0,antialias:!0,preserveDrawingBuffer:this._options.preserveDrawingBuffer,canvas:this._canvas,context:this._canvas.getContext("webgl2")}),this._renderer.setPixelRatio(window.devicePixelRatio),this._renderer.setSize(this._canvas.clientWidth,this._canvas.clientHeight),this._renderer.autoClear=!1,this._lights=new g.Group,this._lights.name="lights",this._scene.add(this._lights),this._world=new g.Group,this._world.name="world",this._world.userData={isWorld:!0,name:"world"},this._world.position.set(1024e3/2,1024e3/2,0),this._world.matrixAutoUpdate=!1,this._scene.add(this._world),this._map.on("style.load",this._onStyleLoad.bind(this)),this._event=new g.EventDispatcher}get map(){return this._map}get canvas(){return this._canvas}get camera(){return this._camera}get scene(){return this._scene}get lights(){return this._lights}get world(){return this._world}get renderer(){return this._renderer}_onStyleLoad(){this._map.addLayer(new ct("map_scene_layer",this))}render(){if(this._options.renderLoop)this._options.renderLoop(this);else{let t={center:this._map.getCenter(),scene:this._scene,camera:this._camera,renderer:this._renderer};this._event.dispatchEvent({type:"preRest",frameState:t}),this.renderer.resetState(),this._event.dispatchEvent({type:"postRest",frameState:t}),this._event.dispatchEvent({type:"preRender",frameState:t}),this.renderer.render(this._scene,this._camera),this._event.dispatchEvent({type:"postRender",frameState:t})}return this}addLight(t){return this._lights.add(t.delegate||t),this}removeLight(t){return this._lights.remove(t.delegate||t),this}addObject(t){return this._world.add(t.delegate||t),this}removeObject(t){return this._world.remove(t),t.traverse(e=>{e.geometry&&e.geometry.dispose(),e.material&&(Array.isArray(e.material)?e.material.forEach(s=>s.dispose()):e.material.dispose()),e.texture&&e.texture.dispose()}),this}getViewPosition(){let t=this._map.transform,e=t.center;return{position:[e.lng,e.lat,E.getHeightByZoom(t,t.zoom,e.lat,t.pitch)],heading:t.bearing,pitch:t.pitch}}flyTo(t,e=null,s=3){if(t&&t.position){e&&this._map.once("moveend",e);let r=t.size;r||(r=new g.Vector3,new g.Box3().setFromObject(t.delegate||t,!0).getSize(r));let a=E.getViewInfo(this._map.transform,L.vector3ToLngLat(t.position),r);this._map.flyTo({center:a.center,zoom:a.zoom,duration:s*1e3})}return this}zoomTo(t,e){return this.flyTo(t,e,0)}flyToPosition(t,e=[0,0,0],s=null,r=3){return s&&this._map.once("moveend",s),this._map.flyTo({center:[t[0],t[1]],zoom:E.getZoomByHeight(this._map.transform,t[2],t[1],e[1]||0),bearing:e[0],pitch:e[1],duration:r*1e3}),this}zoomToPosition(t,e=[0,0,0],s=null,r=3){return this.flyToPosition(t,e,s,0)}on(t,e){return this._event.addEventListener(t,e),this}off(t,e){return this._event.removeEventListener(t,e),this}},ut=Y;var I=Z(O(),1);var J=Math.PI,h=Math.sin,c=Math.cos,K=Math.tan,mt=Math.asin,W=Math.atan2,dt=Math.acos,p=J/180,Q=1e3*60*60*24,pt=2440588,ft=2451545;function Zt(i){return i.valueOf()/Q-.5+pt}function j(i){return new Date((i+.5-pt)*Q)}function F(i){return Zt(i)-ft}var k=p*23.4397;function _t(i,t){return W(h(i)*c(k)-K(t)*h(k),c(i))}function $(i,t){return mt(h(t)*c(k)+c(t)*h(k)*h(i))}function gt(i,t,e){return W(h(i),c(i)*h(t)-K(e)*c(t))}function Mt(i,t,e){return mt(h(t)*h(e)+c(t)*c(e)*c(i))}function wt(i,t){return p*(280.16+360.9856235*i)-t}function Wt(i){return i<0&&(i=0),2967e-7/Math.tan(i+.00312536/(i+.08901179))}function Lt(i){return p*(357.5291+.98560028*i)}function yt(i){let t=p*(1.9148*h(i)+.02*h(2*i)+3e-4*h(3*i)),e=p*102.9372;return i+t+e+J}function St(i){let t=Lt(i),e=yt(t);return{dec:$(e,0),ra:_t(e,0)}}var x={};x.getPosition=function(i,t,e){let s=p*-e,r=p*t,a=F(i),n=St(a),o=wt(a,s)-n.ra;return{azimuth:gt(o,r,n.dec),altitude:Mt(o,r,n.dec)}};var q=x.times=[[-.833,"sunrise","sunset"],[-.3,"sunriseEnd","sunsetStart"],[-6,"dawn","dusk"],[-12,"nauticalDawn","nauticalDusk"],[-18,"nightEnd","night"],[6,"goldenHourEnd","goldenHour"]];x.addTime=function(i,t,e){q.push([i,t,e])};var xt=9e-4;function jt(i,t){return Math.round(i-xt-t/(2*J))}function Rt(i,t,e){return xt+(i+t)/(2*J)+e}function Tt(i,t,e){return ft+i+.0053*h(t)-.0069*h(2*e)}function Gt(i,t,e){return dt((h(i)-h(t)*h(e))/(c(t)*c(e)))}function kt(i){return-2.076*Math.sqrt(i)/60}function Jt(i,t,e,s,r,a,n){let o=Gt(i,e,s),u=Rt(o,t,r);return Tt(u,a,n)}x.getTimes=function(i,t,e,s){s=s||0;let r=p*-e,a=p*t,n=kt(s),o=F(i),u=jt(o,r),l=Rt(0,r,u),d=Lt(l),f=yt(d),_=$(f,0),M=Tt(l,d,f),y,U,R,S,T,H,P={solarNoon:j(M),nadir:j(M-.5)};for(y=0,U=q.length;y<U;y+=1)R=q[y],S=(R[0]+n)*p,T=Jt(S,r,a,_,u,d,f),H=M-(T-M),P[R[1]]=j(H),P[R[2]]=j(T);return P};function Et(i){let t=p*(218.316+13.176396*i),e=p*(134.963+13.064993*i),s=p*(93.272+13.22935*i),r=t+p*6.289*h(e),a=p*5.128*h(s),n=385001-20905*c(e);return{ra:_t(r,a),dec:$(r,a),dist:n}}x.getMoonPosition=function(i,t,e){let s=p*-e,r=p*t,a=F(i),n=Et(a),o=wt(a,s)-n.ra,u=Mt(o,r,n.dec),l=W(h(o),K(r)*c(n.dec)-h(n.dec)*c(o));return u=u+Wt(u),{azimuth:gt(o,r,n.dec),altitude:u,distance:n.dist,parallacticAngle:l}};x.getMoonIllumination=function(i){let t=F(i||new Date),e=St(t),s=Et(t),r=149598e3,a=dt(h(e.dec)*h(s.dec)+c(e.dec)*c(s.dec)*c(e.ra-s.ra)),n=W(r*h(a),s.dist-r*c(a)),o=W(c(e.dec)*h(e.ra-s.ra),h(e.dec)*c(s.dec)-c(e.dec)*h(s.dec)*c(e.ra-s.ra));return{fraction:(1+c(n))/2,phase:.5+.5*n*(o<0?-1:1)/Math.PI,angle:o}};function G(i,t){return new Date(i.valueOf()+t*Q/24)}x.getMoonTimes=function(i,t,e,s){let r=new Date(i);s?r.setUTCHours(0,0,0,0):r.setHours(0,0,0,0);let a=.133*p,n=x.getMoonPosition(r,t,e).altitude-a,o,u,l,d,f,_,M,y,U,R,S,T,H;for(let D=1;D<=24&&(o=x.getMoonPosition(G(r,D),t,e).altitude-a,u=x.getMoonPosition(G(r,D+1),t,e).altitude-a,f=(n+u)/2-o,_=(u-n)/2,M=-_/(2*f),y=(f*M+_)*M+o,U=_*_-4*f*o,R=0,U>=0&&(H=Math.sqrt(U)/(Math.abs(f)*2),S=M-H,T=M+H,Math.abs(S)<=1&&R++,Math.abs(T)<=1&&R++,S<-1&&(S=T)),R===1?n<0?l=D+S:d=D+S:R===2&&(l=D+(y<0?T:S),d=D+(y<0?S:T)),!(l&&d));D+=2)n=u;let P={};return l&&(P.rise=G(r,l)),d&&(P.set=G(r,d)),!l&&!d&&(P[y>0?"alwaysUp":"alwaysDown"]=!0),P};var vt=x;var tt=class{constructor(){this._delegate=new I.Group,this._delegate.name="Sun",this._sunLight=new I.DirectionalLight(16777215,1),this._hemiLight=new I.HemisphereLight(new I.Color(16777215),new I.Color(16777215),.6),this._hemiLight.color.setHSL(.661,.96,.12),this._hemiLight.groundColor.setHSL(.11,.96,.14),this._hemiLight.position.set(0,0,50),this._delegate.add(this._sunLight),this._delegate.add(this._hemiLight),this._currentTime=null}get delegate(){return this._delegate}set castShadow(t){this._sunLight.castShadow=t}get castShadow(){return this._sunLight.castShadow}set currentTime(t){this._currentTime=t}get currentTime(){return this._currentTime}get sunLight(){return this._sunLight}get hemiLight(){return this._hemiLight}setShadow(t={}){return this._sunLight.shadow.radius=t.radius||2,this._sunLight.shadow.mapSize.width=t.mapSize?t.mapSize[0]:8192,this._sunLight.shadow.mapSize.height=t.mapSize?t.mapSize[1]:8192,this._sunLight.shadow.camera.top=this._sunLight.shadow.camera.right=t.topRight||1e3,this._sunLight.shadow.camera.bottom=this._sunLight.shadow.camera.left=t.bottomLeft||-1e3,this._sunLight.shadow.camera.near=t.near||1,this._sunLight.shadow.camera.far=t.far||1e8,this._sunLight.shadow.camera.visible=!0,this}update(t){let s=new Date(this._currentTime||new Date().getTime()),r=t.center,a=vt.getPosition(s,r.lat,r.lng),n=a.altitude,o=Math.PI+a.azimuth,u=1024e3/2,l=Math.sin(n),d=Math.cos(n),f=Math.cos(o)*d,_=Math.sin(o)*d;this._sunLight.position.set(_,f,l),this._sunLight.position.multiplyScalar(u),this._sunLight.intensity=Math.max(l,0),this._hemiLight.intensity=Math.max(l*1,.1),this._sunLight.updateMatrixWorld()}},It=tt;var z=Z(O(),1);var et=class{static createRTCGroup(t,e,s){let r=new z.Group;if(r.name="rtc",r.position.copy(L.lngLatToVector3(t)),e?(r.rotateX(e[0]||0),r.rotateY(e[1]||0),r.rotateZ(e[2]||0)):(r.rotateX(Math.PI/2),r.rotateY(Math.PI)),s)r.scale.set(s[0]||1,s[1]||1,s[2]||1);else{let a=1;Array.isArray(t)?a=L.projectedUnitsPerMeter(t[1]):typeof t=="string"&&(a=L.projectedUnitsPerMeter(t.split(",")[1])),r.scale.set(a,a,a)}return r}static createMercatorRTCGroup(t,e,s){let r=this.createRTCGroup(t,e,s);if(!s){let a=1,n=L.projectedMercatorUnitsPerMeter();Array.isArray(t)?a=L.projectedUnitsPerMeter(t[1]):typeof t=="string"&&(a=L.projectedUnitsPerMeter(t.split(",")[1])),r.scale.set(n,n,a)}return r}static createShadowGround(t,e=100,s=100){let r=new z.PlaneGeometry(e,s),a=new z.ShadowMaterial({opacity:.5,transparent:!0}),n=new z.Mesh(r,a);return n.position.copy(L.lngLatToVector3(t)),n.receiveShadow=!0,n.name="shadow-ground",n}},Pt=et;})();
package/package.json ADDED
@@ -0,0 +1,51 @@
1
+ {
2
+ "name": "@dvt3d/maplibre-three-plugin",
3
+ "version": "1.0.0",
4
+ "main": "dist/index.js",
5
+ "repository": "https://github.com/dvt3d/maplibre-three-plugin.git",
6
+ "author": "cavencj <cavencj@gmail.com>",
7
+ "license": "MIT",
8
+ "type": "module",
9
+ "scripts": {
10
+ "dev": "rimraf dist && gulp dev",
11
+ "build": "rimraf dist && gulp build",
12
+ "build:node": "rimraf dist && gulp buildNode",
13
+ "build:iife": "rimraf dist && gulp buildIIFE",
14
+ "build:release": "rimraf dist && gulp buildRelease",
15
+ "prepublishOnly": "yarn run build:release",
16
+ "lint": "eslint --fix src"
17
+ },
18
+ "devDependencies": {
19
+ "@babel/core": "^7.21.4",
20
+ "@babel/eslint-parser": "^7.21.8",
21
+ "@babel/plugin-proposal-class-properties": "^7.18.6",
22
+ "@babel/plugin-transform-runtime": "^7.21.4",
23
+ "@babel/preset-env": "^7.21.5",
24
+ "chalk": "^5.2.0",
25
+ "esbuild": "^0.20.2",
26
+ "esbuild-plugin-globals": "^0.2.0",
27
+ "esbuild-plugin-inline-image": "^0.0.9",
28
+ "esbuild-sass-plugin": "^3.1.0",
29
+ "eslint": "^8.40.0",
30
+ "eslint-config-prettier": "^8.8.0",
31
+ "eslint-plugin-import": "^2.27.5",
32
+ "eslint-plugin-node": "^11.1.0",
33
+ "eslint-plugin-prettier": "^4.2.1",
34
+ "eslint-plugin-promise": "^6.1.1",
35
+ "express": "^4.18.2",
36
+ "fs-extra": "^11.1.1",
37
+ "gulp": "^4.0.2",
38
+ "gulp-clean": "^0.4.0",
39
+ "portfinder": "^1.0.32",
40
+ "prettier": "^2.8.8",
41
+ "rimraf": "^5.0.0",
42
+ "sass": "^1.62.1",
43
+ "shelljs": "^0.8.5"
44
+ },
45
+ "peerDependencies": {
46
+ "three": "^0.178.0"
47
+ },
48
+ "files": [
49
+ "dist"
50
+ ]
51
+ }