@things-factory/weather 9.0.0-9.0.0-beta.59.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.
Files changed (90) hide show
  1. package/CHANGELOG.md +8 -0
  2. package/assets/images/wind.png +0 -0
  3. package/assets/images/wind2.png +0 -0
  4. package/client/bootstrap.ts +1 -0
  5. package/client/index.ts +0 -0
  6. package/client/ol-components/webgl-canvas-layer.ts +413 -0
  7. package/client/ol-components/wind-data-tile-layer.ts +485 -0
  8. package/client/ol-components/wind-rasterized-layer.ts +437 -0
  9. package/client/pages/weather-page.ts +353 -0
  10. package/client/route.ts +7 -0
  11. package/client/tsconfig.json +11 -0
  12. package/config/config.development.js +28 -0
  13. package/config/config.production.js +10 -0
  14. package/data/geo-json/countries-max-geo.json +1 -0
  15. package/dist-client/bootstrap.d.ts +1 -0
  16. package/dist-client/bootstrap.js +2 -0
  17. package/dist-client/bootstrap.js.map +1 -0
  18. package/dist-client/index.d.ts +0 -0
  19. package/dist-client/index.js +2 -0
  20. package/dist-client/index.js.map +1 -0
  21. package/dist-client/ol-components/webgl-canvas-layer.d.ts +61 -0
  22. package/dist-client/ol-components/webgl-canvas-layer.js +364 -0
  23. package/dist-client/ol-components/webgl-canvas-layer.js.map +1 -0
  24. package/dist-client/ol-components/wind-data-tile-layer.d.ts +59 -0
  25. package/dist-client/ol-components/wind-data-tile-layer.js +414 -0
  26. package/dist-client/ol-components/wind-data-tile-layer.js.map +1 -0
  27. package/dist-client/ol-components/wind-rasterized-layer.d.ts +59 -0
  28. package/dist-client/ol-components/wind-rasterized-layer.js +363 -0
  29. package/dist-client/ol-components/wind-rasterized-layer.js.map +1 -0
  30. package/dist-client/pages/weather-page.d.ts +23 -0
  31. package/dist-client/pages/weather-page.js +348 -0
  32. package/dist-client/pages/weather-page.js.map +1 -0
  33. package/dist-client/route.d.ts +1 -0
  34. package/dist-client/route.js +8 -0
  35. package/dist-client/route.js.map +1 -0
  36. package/dist-client/tsconfig.tsbuildinfo +1 -0
  37. package/dist-server/controllers/open-meteo-adapter.d.ts +4 -0
  38. package/dist-server/controllers/open-meteo-adapter.js +87 -0
  39. package/dist-server/controllers/open-meteo-adapter.js.map +1 -0
  40. package/dist-server/controllers/types.d.ts +55 -0
  41. package/dist-server/controllers/types.js +3 -0
  42. package/dist-server/controllers/types.js.map +1 -0
  43. package/dist-server/controllers/weather-controller.d.ts +12 -0
  44. package/dist-server/controllers/weather-controller.js +179 -0
  45. package/dist-server/controllers/weather-controller.js.map +1 -0
  46. package/dist-server/index.d.ts +1 -0
  47. package/dist-server/index.js +4 -0
  48. package/dist-server/index.js.map +1 -0
  49. package/dist-server/routers/geo-router.d.ts +59 -0
  50. package/dist-server/routers/geo-router.js +277 -0
  51. package/dist-server/routers/geo-router.js.map +1 -0
  52. package/dist-server/routers/weather-router.d.ts +1 -0
  53. package/dist-server/routers/weather-router.js +10 -0
  54. package/dist-server/routers/weather-router.js.map +1 -0
  55. package/dist-server/routes.d.ts +1 -0
  56. package/dist-server/routes.js +11 -0
  57. package/dist-server/routes.js.map +1 -0
  58. package/dist-server/services/chrome-renderer.d.ts +13 -0
  59. package/dist-server/services/chrome-renderer.js +162 -0
  60. package/dist-server/services/chrome-renderer.js.map +1 -0
  61. package/dist-server/services/headless-pool.d.ts +4 -0
  62. package/dist-server/services/headless-pool.js +89 -0
  63. package/dist-server/services/headless-pool.js.map +1 -0
  64. package/dist-server/tsconfig.tsbuildinfo +1 -0
  65. package/dist-server/utils/svg-utils.d.ts +35 -0
  66. package/dist-server/utils/svg-utils.js +89 -0
  67. package/dist-server/utils/svg-utils.js.map +1 -0
  68. package/dist-server/utils/tile-utils.d.ts +38 -0
  69. package/dist-server/utils/tile-utils.js +64 -0
  70. package/dist-server/utils/tile-utils.js.map +1 -0
  71. package/package.json +46 -0
  72. package/server/controllers/open-meteo-adapter.ts +96 -0
  73. package/server/controllers/types.ts +63 -0
  74. package/server/controllers/weather-controller.ts +192 -0
  75. package/server/index.ts +1 -0
  76. package/server/routers/geo-router.ts +297 -0
  77. package/server/routers/weather-router.ts +8 -0
  78. package/server/routes.ts +10 -0
  79. package/server/services/chrome-renderer.ts +206 -0
  80. package/server/services/data.json +8438 -0
  81. package/server/services/headless-pool.ts +97 -0
  82. package/server/tsconfig.json +10 -0
  83. package/server/utils/svg-utils.ts +108 -0
  84. package/server/utils/tile-utils.ts +77 -0
  85. package/things-factory.config.js +8 -0
  86. package/translations/en.json +1 -0
  87. package/translations/ja.json +1 -0
  88. package/translations/ko.json +1 -0
  89. package/translations/ms.json +1 -0
  90. package/translations/zh.json +1 -0
@@ -0,0 +1 @@
1
+ export default function bootstrap(): void;
@@ -0,0 +1,2 @@
1
+ export default function bootstrap() { }
2
+ //# sourceMappingURL=bootstrap.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bootstrap.js","sourceRoot":"","sources":["../client/bootstrap.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,UAAU,SAAS,KAAI,CAAC","sourcesContent":["export default function bootstrap() {}\n"]}
File without changes
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../client/index.ts"],"names":[],"mappings":"","sourcesContent":[""]}
@@ -0,0 +1,61 @@
1
+ import ImageLayer from 'ol/layer/Image.js';
2
+ import ImageCanvasSource from 'ol/source/ImageCanvas.js';
3
+ /**
4
+ * WebGL을 μ‚¬μš©ν•˜μ—¬ 날씨 데이터 이미지λ₯Ό 지도에 μ˜€λ²„λ ˆμ΄ν•˜λŠ” λ ˆμ΄μ–΄
5
+ * μ΄λ―Έμ§€μ˜ RGBA μ±„λ„μ—λŠ” μ˜¨λ„, μŠ΅λ„, λ°”λžŒ, κ°•μˆ˜λŸ‰ 데이터가 μΈμ½”λ”©λ˜μ–΄ 있음
6
+ */
7
+ declare class WebGLCanvasLayer extends ImageLayer<ImageCanvasSource> {
8
+ private canvas;
9
+ private gl;
10
+ private program;
11
+ private texture;
12
+ private buffer;
13
+ private imageLoaded;
14
+ private pendingRender;
15
+ private imageUrl;
16
+ private dataType;
17
+ /**
18
+ * WebGL μΊ”λ²„μŠ€ λ ˆμ΄μ–΄ μƒμ„±μž
19
+ * @param imageUrl 날씨 데이터가 μΈμ½”λ”©λœ 이미지 URL
20
+ * @param dataType μ‹œκ°ν™”ν•  데이터 μœ ν˜• (temperature, humidity, wind, precipitation)
21
+ */
22
+ constructor(imageUrl: string, dataType?: string);
23
+ /**
24
+ * 데이터 μ‹œκ°ν™” μœ ν˜• λ³€κ²½
25
+ */
26
+ updateDataType(type: string): void;
27
+ /**
28
+ * λ¦¬μ†ŒμŠ€ ν•΄μ œ
29
+ */
30
+ dispose(): void;
31
+ /**
32
+ * 이미지 URL μ—…λ°μ΄νŠΈ
33
+ */
34
+ updateImageUrl(newUrl: string): void;
35
+ /**
36
+ * WebGL μ»¨ν…μŠ€νŠΈ μ΄ˆκΈ°ν™”
37
+ */
38
+ private _initializeWebGL;
39
+ /**
40
+ * λ²„ν…μŠ€ 버퍼 μ΄ˆκΈ°ν™”
41
+ */
42
+ private _initializeBuffers;
43
+ /**
44
+ * 이미지 λ‘œλ“œ 및 ν…μŠ€μ²˜ 생성
45
+ */
46
+ private _loadImage;
47
+ /**
48
+ * ν…μŠ€μ²˜ λ Œλ”λ§
49
+ */
50
+ private _renderTexture;
51
+ /**
52
+ * 셰이더 ν”„λ‘œκ·Έλž¨ 생성
53
+ */
54
+ private _createShaderProgram;
55
+ /**
56
+ * 셰이더 컴파일
57
+ */
58
+ private _compileShader;
59
+ private _updateWebGLUniforms;
60
+ }
61
+ export default WebGLCanvasLayer;
@@ -0,0 +1,364 @@
1
+ import ImageLayer from 'ol/layer/Image.js';
2
+ import ImageCanvasSource from 'ol/source/ImageCanvas.js';
3
+ import { transformExtent } from 'ol/proj.js';
4
+ /**
5
+ * WebGL을 μ‚¬μš©ν•˜μ—¬ 날씨 데이터 이미지λ₯Ό 지도에 μ˜€λ²„λ ˆμ΄ν•˜λŠ” λ ˆμ΄μ–΄
6
+ * μ΄λ―Έμ§€μ˜ RGBA μ±„λ„μ—λŠ” μ˜¨λ„, μŠ΅λ„, λ°”λžŒ, κ°•μˆ˜λŸ‰ 데이터가 μΈμ½”λ”©λ˜μ–΄ 있음
7
+ */
8
+ class WebGLCanvasLayer extends ImageLayer {
9
+ /**
10
+ * WebGL μΊ”λ²„μŠ€ λ ˆμ΄μ–΄ μƒμ„±μž
11
+ * @param imageUrl 날씨 데이터가 μΈμ½”λ”©λœ 이미지 URL
12
+ * @param dataType μ‹œκ°ν™”ν•  데이터 μœ ν˜• (temperature, humidity, wind, precipitation)
13
+ */
14
+ constructor(imageUrl, dataType = 'temperature') {
15
+ super({
16
+ source: new ImageCanvasSource({
17
+ canvasFunction: (extent, resolution, pixelRatio, size, projection) => {
18
+ this._initializeWebGL(size, pixelRatio);
19
+ if (this.gl && this.program) {
20
+ // ν˜„μž¬ 지도 뷰의 extentλ₯Ό 지리 μ’Œν‘œ(EPSG:4326)둜 λ³€ν™˜
21
+ const worldExtent = transformExtent(extent, projection.getCode(), 'EPSG:4326');
22
+ // 이미지가 λ‘œλ“œλœ 경우 λ Œλ”λ§
23
+ if (this.imageLoaded && this.texture) {
24
+ this._updateWebGLUniforms(worldExtent, resolution, size, pixelRatio);
25
+ this._renderTexture(worldExtent, size, resolution, pixelRatio);
26
+ }
27
+ else if (!this.pendingRender) {
28
+ this.pendingRender = true;
29
+ this._loadImage(this.imageUrl, worldExtent, size, resolution, pixelRatio);
30
+ }
31
+ }
32
+ return this.canvas;
33
+ },
34
+ projection: 'EPSG:3857'
35
+ })
36
+ });
37
+ this.canvas = null;
38
+ this.gl = null;
39
+ this.program = null;
40
+ this.texture = null;
41
+ this.buffer = null;
42
+ this.imageLoaded = false;
43
+ this.pendingRender = false;
44
+ this.imageUrl = imageUrl;
45
+ this.dataType = dataType;
46
+ this.on('change:visible', () => this.changed());
47
+ }
48
+ /**
49
+ * 데이터 μ‹œκ°ν™” μœ ν˜• λ³€κ²½
50
+ */
51
+ updateDataType(type) {
52
+ this.dataType = type;
53
+ this.changed();
54
+ }
55
+ /**
56
+ * λ¦¬μ†ŒμŠ€ ν•΄μ œ
57
+ */
58
+ dispose() {
59
+ if (this.gl) {
60
+ if (this.buffer)
61
+ this.gl.deleteBuffer(this.buffer);
62
+ if (this.texture)
63
+ this.gl.deleteTexture(this.texture);
64
+ if (this.program)
65
+ this.gl.deleteProgram(this.program);
66
+ }
67
+ super.dispose();
68
+ }
69
+ /**
70
+ * 이미지 URL μ—…λ°μ΄νŠΈ
71
+ */
72
+ updateImageUrl(newUrl) {
73
+ if (this.imageUrl === newUrl)
74
+ return;
75
+ this.imageUrl = newUrl;
76
+ this.imageLoaded = false;
77
+ this.pendingRender = false;
78
+ if (this.texture && this.gl) {
79
+ this.gl.deleteTexture(this.texture);
80
+ this.texture = null;
81
+ }
82
+ this.changed();
83
+ }
84
+ /**
85
+ * WebGL μ»¨ν…μŠ€νŠΈ μ΄ˆκΈ°ν™”
86
+ */
87
+ _initializeWebGL(size, pixelRatio = 1) {
88
+ const width = Math.round(size[0] * pixelRatio);
89
+ const height = Math.round(size[1] * pixelRatio);
90
+ if (!this.canvas) {
91
+ // μΊ”λ²„μŠ€ 생성 및 WebGL μ΄ˆκΈ°ν™”
92
+ this.canvas = document.createElement('canvas');
93
+ this.canvas.width = width;
94
+ this.canvas.height = height;
95
+ this.gl = this.canvas.getContext('webgl', {
96
+ alpha: true,
97
+ antialias: false,
98
+ depth: false
99
+ });
100
+ if (!this.gl)
101
+ return;
102
+ this.program = this._createShaderProgram();
103
+ if (this.program) {
104
+ this._initializeBuffers();
105
+ }
106
+ }
107
+ else if (this.canvas.width !== width || this.canvas.height !== height) {
108
+ // μΊ”λ²„μŠ€ 크기 μ‘°μ •
109
+ this.canvas.width = width;
110
+ this.canvas.height = height;
111
+ if (this.gl)
112
+ this.gl.viewport(0, 0, width, height);
113
+ }
114
+ }
115
+ /**
116
+ * λ²„ν…μŠ€ 버퍼 μ΄ˆκΈ°ν™”
117
+ */
118
+ _initializeBuffers() {
119
+ if (!this.gl)
120
+ return;
121
+ // μ‚¬κ°ν˜• λ²„ν…μŠ€ (μœ„μΉ˜(x,y) + ν…μŠ€μ²˜ μ’Œν‘œ(s,t))
122
+ const vertices = new Float32Array([
123
+ -1,
124
+ -1,
125
+ 0,
126
+ 1, // μ’Œν•˜λ‹¨
127
+ 1,
128
+ -1,
129
+ 1,
130
+ 1, // μš°ν•˜λ‹¨
131
+ -1,
132
+ 1,
133
+ 0,
134
+ 0, // μ’Œμƒλ‹¨
135
+ 1,
136
+ 1,
137
+ 1,
138
+ 0 // μš°μƒλ‹¨
139
+ ]);
140
+ this.buffer = this.gl.createBuffer();
141
+ this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer);
142
+ this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW);
143
+ }
144
+ /**
145
+ * 이미지 λ‘œλ“œ 및 ν…μŠ€μ²˜ 생성
146
+ */
147
+ _loadImage(url, worldExtent, size, resolution, pixelRatio) {
148
+ const img = new Image();
149
+ img.crossOrigin = 'anonymous';
150
+ img.onload = () => {
151
+ if (!this.gl)
152
+ return;
153
+ try {
154
+ // ν…μŠ€μ²˜ 생성 및 μ„€μ •
155
+ this.texture = this.gl.createTexture();
156
+ this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture);
157
+ // 경도 λ°©ν–₯으둜 λž˜ν•‘ (λ‚ μ§œ λ³€κ²½μ„  처리)
158
+ // this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT)
159
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE);
160
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE);
161
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR);
162
+ this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR);
163
+ // ν…μŠ€μ²˜ 데이터 μ—…λ‘œλ“œ
164
+ this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false); // μ•ŒνŒŒκ°’ 손싀 λ°©μ§€
165
+ this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, img);
166
+ this.imageLoaded = true;
167
+ this.pendingRender = false;
168
+ // 이미지 λ‘œλ“œ ν›„ λ Œλ”λ§
169
+ this._renderTexture(worldExtent, size, resolution, pixelRatio);
170
+ this.changed();
171
+ }
172
+ catch (err) {
173
+ console.error('ν…μŠ€μ²˜ 생성 μ‹€νŒ¨:', err);
174
+ this.pendingRender = false;
175
+ }
176
+ };
177
+ img.onerror = () => {
178
+ console.error('이미지 λ‘œλ“œ μ‹€νŒ¨:', url);
179
+ this.pendingRender = false;
180
+ };
181
+ img.src = url;
182
+ }
183
+ /**
184
+ * ν…μŠ€μ²˜ λ Œλ”λ§
185
+ */
186
+ _renderTexture(worldExtent, size, resolution, pixelRatio) {
187
+ if (!this.gl || !this.program || !this.texture || !this.buffer)
188
+ return;
189
+ const gl = this.gl;
190
+ const width = Math.round(size[0] * pixelRatio);
191
+ const height = Math.round(size[1] * pixelRatio);
192
+ this._updateWebGLUniforms(worldExtent, resolution, size, pixelRatio);
193
+ // κΈ°λ³Έ WebGL μƒνƒœ μ„€μ •
194
+ gl.viewport(0, 0, width, height);
195
+ gl.clearColor(0, 0, 0, 0);
196
+ gl.enable(gl.BLEND);
197
+ gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
198
+ gl.clear(gl.COLOR_BUFFER_BIT);
199
+ // 셰이더 ν”„λ‘œκ·Έλž¨ ν™œμ„±ν™”
200
+ gl.useProgram(this.program);
201
+ // ν…μŠ€μ²˜ 바인딩
202
+ gl.activeTexture(gl.TEXTURE0);
203
+ gl.bindTexture(gl.TEXTURE_2D, this.texture);
204
+ // μœ λ‹ˆνΌ μ„€μ •
205
+ const dataTypeVal = ['temperature', 'humidity', 'wind', 'precipitation'].indexOf(this.dataType);
206
+ gl.uniform1i(gl.getUniformLocation(this.program, 'u_texture'), 0);
207
+ gl.uniform1f(gl.getUniformLocation(this.program, 'u_opacity'), 0.8 * pixelRatio);
208
+ gl.uniform1i(gl.getUniformLocation(this.program, 'u_dataType'), dataTypeVal >= 0 ? dataTypeVal : 0);
209
+ gl.uniform4fv(gl.getUniformLocation(this.program, 'u_worldExtent'), new Float32Array([worldExtent[0], worldExtent[1], worldExtent[2], worldExtent[3]]));
210
+ // 버퍼 바인딩 및 속성 μ„€μ •
211
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer);
212
+ const a_position = gl.getAttribLocation(this.program, 'a_position');
213
+ const a_texCoord = gl.getAttribLocation(this.program, 'a_texCoord');
214
+ gl.enableVertexAttribArray(a_position);
215
+ gl.enableVertexAttribArray(a_texCoord);
216
+ gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 16, 0);
217
+ gl.vertexAttribPointer(a_texCoord, 2, gl.FLOAT, false, 16, 8);
218
+ // μ‚¬κ°ν˜• λ Œλ”λ§
219
+ gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
220
+ }
221
+ /**
222
+ * 셰이더 ν”„λ‘œκ·Έλž¨ 생성
223
+ */
224
+ _createShaderProgram() {
225
+ if (!this.gl)
226
+ return null;
227
+ // λ²„ν…μŠ€ 셰이더: 지리 μ’Œν‘œμ™€ ν…μŠ€μ²˜ μ’Œν‘œ κ°„ λ³€ν™˜
228
+ const vertexShaderSource = `
229
+ precision highp float;
230
+
231
+ attribute vec4 a_position; // Rectangle coordinates
232
+ attribute vec2 a_texCoord; // Texture coordinates
233
+ varying vec2 v_texCoord;
234
+
235
+ uniform vec2 u_resolution; // Resolution (meters per pixel)
236
+ uniform vec2 u_offset; // Offset in map coordinates
237
+ uniform float u_zoomResolution; // πŸš€ This will store the resolution passed from JS
238
+
239
+ void main() {
240
+ float x = ((a_position.x - u_offset.x * u_zoomResolution) / u_resolution.x) * 2.0 - 1.0;
241
+ float y = ((a_position.y - u_offset.y * u_zoomResolution) / u_resolution.y) * 2.0 - 1.0;
242
+
243
+ gl_Position = vec4(x, y, 0.0, 1.0);
244
+ v_texCoord = a_texCoord;
245
+ }
246
+ `;
247
+ // ν”„λž˜κ·Έλ¨ΌνŠΈ 셰이더: 데이터 μ‹œκ°ν™”
248
+ const fragmentShaderSource = `
249
+ precision highp float;
250
+
251
+ uniform sampler2D u_texture;
252
+ uniform float u_opacity;
253
+ uniform int u_dataType;
254
+ varying vec2 v_texCoord;
255
+
256
+ // 색상 κ·ΈλΌλ°μ΄μ…˜ 생성
257
+ vec3 getColorForData(float value) {
258
+ // κ°’ λ²”μœ„ ν™•μž₯
259
+ value = clamp(value * 1.2, 0.0, 1.0);
260
+
261
+ if (u_dataType == 0) { // μ˜¨λ„
262
+ // νŒŒλž‘(μ €μ˜¨) -> λΉ¨κ°•(고온)
263
+ return mix(vec3(0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), value);
264
+ }
265
+ else if (u_dataType == 1) { // μŠ΅λ„
266
+ // ν•˜λŠ˜μƒ‰(건쑰) -> μ§„ν•œ νŒŒλž‘(μŠ΅ν•¨)
267
+ return mix(vec3(0.5, 0.5, 1.0), vec3(0.0, 0.0, 0.8), value);
268
+ }
269
+ else if (u_dataType == 2) { // λ°”λžŒ
270
+ // 녹색(약함) -> λ…Έλž‘(강함)
271
+ return mix(vec3(0.0, 0.5, 0.0), vec3(1.0, 1.0, 0.0), value);
272
+ }
273
+ else { // κ°•μˆ˜λŸ‰
274
+ // 투λͺ…(μ—†μŒ) -> 보라(많음)
275
+ float intensity = value * 1.5;
276
+ return vec3(0.5, 0.0, 0.5) * intensity;
277
+ }
278
+ }
279
+
280
+ void main() {
281
+ // ν…μŠ€μ²˜μ—μ„œ 데이터 κ°€μ Έμ˜€κΈ°
282
+ vec4 texColor = texture2D(u_texture, v_texCoord);
283
+
284
+ // 데이터가 μ—†λŠ” 경우 λ¬΄μ‹œ
285
+ if (texColor.a < 0.01) {
286
+ discard;
287
+ }
288
+
289
+ // 데이터 채널 선택
290
+ float value = 0.0;
291
+ if (u_dataType == 0) value = texColor.r; // μ˜¨λ„
292
+ else if (u_dataType == 1) value = texColor.g; // μŠ΅λ„
293
+ else if (u_dataType == 2) value = texColor.b; // λ°”λžŒ
294
+ else value = texColor.a; // κ°•μˆ˜λŸ‰
295
+
296
+ // 데이터 μ‹œκ°ν™”
297
+ vec3 color = getColorForData(value);
298
+ float alpha = u_dataType == 3 ? value * u_opacity : u_opacity;
299
+
300
+ gl_FragColor = vec4(color, alpha);
301
+ }
302
+ `;
303
+ // 셰이더 컴파일
304
+ const vertexShader = this._compileShader(this.gl.VERTEX_SHADER, vertexShaderSource);
305
+ const fragmentShader = this._compileShader(this.gl.FRAGMENT_SHADER, fragmentShaderSource);
306
+ if (!vertexShader || !fragmentShader)
307
+ return null;
308
+ // ν”„λ‘œκ·Έλž¨ 생성 및 링크
309
+ const program = this.gl.createProgram();
310
+ this.gl.attachShader(program, vertexShader);
311
+ this.gl.attachShader(program, fragmentShader);
312
+ this.gl.linkProgram(program);
313
+ if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {
314
+ console.error('WebGL ν”„λ‘œκ·Έλž¨ 링크 μ‹€νŒ¨:', this.gl.getProgramInfoLog(program));
315
+ return null;
316
+ }
317
+ return program;
318
+ }
319
+ /**
320
+ * 셰이더 컴파일
321
+ */
322
+ _compileShader(type, source) {
323
+ if (!this.gl)
324
+ return null;
325
+ const shader = this.gl.createShader(type);
326
+ this.gl.shaderSource(shader, source);
327
+ this.gl.compileShader(shader);
328
+ if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {
329
+ console.error('셰이더 컴파일 였λ₯˜:', this.gl.getShaderInfoLog(shader));
330
+ this.gl.deleteShader(shader);
331
+ return null;
332
+ }
333
+ return shader;
334
+ }
335
+ _updateWebGLUniforms(worldExtent, resolution, size, pixelRatio) {
336
+ if (!this.gl || !this.program)
337
+ return;
338
+ const gl = this.gl;
339
+ gl.useProgram(this.program);
340
+ const textureWidth = size[0] * pixelRatio;
341
+ const textureHeight = size[1] * pixelRatio;
342
+ // βœ… Apply resolution correctly (fixing zoom scaling issue)
343
+ const u_resolution = [
344
+ (worldExtent[2] - worldExtent[0]) / textureWidth,
345
+ (worldExtent[3] - worldExtent[1]) / textureHeight
346
+ ];
347
+ // βœ… Convert u_offset to OpenGL coordinates
348
+ const u_offset = [
349
+ (worldExtent[0] - (worldExtent[2] + worldExtent[0]) / 2) / (worldExtent[2] - worldExtent[0]),
350
+ (worldExtent[1] - (worldExtent[3] + worldExtent[1]) / 2) / (worldExtent[3] - worldExtent[1])
351
+ ];
352
+ console.log('πŸ“Œ _updateWebGLUniforms called');
353
+ console.log('🟒 resolution:', resolution);
354
+ console.log('🟒 pixelRatio:', pixelRatio);
355
+ console.log('🟒 textureWidth:', textureWidth, 'textureHeight:', textureHeight);
356
+ console.log('🟒 u_resolution:', u_resolution);
357
+ console.log('🟒 u_offset:', u_offset);
358
+ gl.uniform2fv(gl.getUniformLocation(this.program, 'u_resolution'), u_resolution);
359
+ gl.uniform2fv(gl.getUniformLocation(this.program, 'u_offset'), u_offset);
360
+ gl.uniform1f(gl.getUniformLocation(this.program, 'u_zoomResolution'), resolution); // πŸš€ Pass resolution!
361
+ }
362
+ }
363
+ export default WebGLCanvasLayer;
364
+ //# sourceMappingURL=webgl-canvas-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"webgl-canvas-layer.js","sourceRoot":"","sources":["../../client/ol-components/webgl-canvas-layer.ts"],"names":[],"mappings":"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","sourcesContent":["import ImageLayer from 'ol/layer/Image.js'\nimport ImageCanvasSource from 'ol/source/ImageCanvas.js'\nimport { transformExtent } from 'ol/proj.js'\n\n/**\n * WebGL을 μ‚¬μš©ν•˜μ—¬ 날씨 데이터 이미지λ₯Ό 지도에 μ˜€λ²„λ ˆμ΄ν•˜λŠ” λ ˆμ΄μ–΄\n * μ΄λ―Έμ§€μ˜ RGBA μ±„λ„μ—λŠ” μ˜¨λ„, μŠ΅λ„, λ°”λžŒ, κ°•μˆ˜λŸ‰ 데이터가 μΈμ½”λ”©λ˜μ–΄ 있음\n */\nclass WebGLCanvasLayer extends ImageLayer<ImageCanvasSource> {\n private canvas: HTMLCanvasElement | null = null\n private gl: WebGLRenderingContext | null = null\n private program: WebGLProgram | null = null\n private texture: WebGLTexture | null = null\n private buffer: WebGLBuffer | null = null\n private imageLoaded: boolean = false\n private pendingRender: boolean = false\n private imageUrl: string\n private dataType: string\n\n /**\n * WebGL μΊ”λ²„μŠ€ λ ˆμ΄μ–΄ μƒμ„±μž\n * @param imageUrl 날씨 데이터가 μΈμ½”λ”©λœ 이미지 URL\n * @param dataType μ‹œκ°ν™”ν•  데이터 μœ ν˜• (temperature, humidity, wind, precipitation)\n */\n constructor(imageUrl: string, dataType: string = 'temperature') {\n super({\n source: new ImageCanvasSource({\n canvasFunction: (extent, resolution, pixelRatio, size, projection) => {\n this._initializeWebGL(size, pixelRatio)\n\n if (this.gl && this.program) {\n // ν˜„μž¬ 지도 뷰의 extentλ₯Ό 지리 μ’Œν‘œ(EPSG:4326)둜 λ³€ν™˜\n const worldExtent = transformExtent(extent, projection.getCode(), 'EPSG:4326')\n\n // 이미지가 λ‘œλ“œλœ 경우 λ Œλ”λ§\n if (this.imageLoaded && this.texture) {\n this._updateWebGLUniforms(worldExtent, resolution, size, pixelRatio)\n this._renderTexture(worldExtent, size, resolution, pixelRatio)\n } else if (!this.pendingRender) {\n this.pendingRender = true\n this._loadImage(this.imageUrl, worldExtent, size, resolution, pixelRatio)\n }\n }\n\n return this.canvas!\n },\n projection: 'EPSG:3857'\n })\n })\n\n this.imageUrl = imageUrl\n this.dataType = dataType\n this.on('change:visible', () => this.changed())\n }\n\n /**\n * 데이터 μ‹œκ°ν™” μœ ν˜• λ³€κ²½\n */\n updateDataType(type: string) {\n this.dataType = type\n this.changed()\n }\n\n /**\n * λ¦¬μ†ŒμŠ€ ν•΄μ œ\n */\n dispose() {\n if (this.gl) {\n if (this.buffer) this.gl.deleteBuffer(this.buffer)\n if (this.texture) this.gl.deleteTexture(this.texture)\n if (this.program) this.gl.deleteProgram(this.program)\n }\n super.dispose()\n }\n\n /**\n * 이미지 URL μ—…λ°μ΄νŠΈ\n */\n updateImageUrl(newUrl: string) {\n if (this.imageUrl === newUrl) return\n\n this.imageUrl = newUrl\n this.imageLoaded = false\n this.pendingRender = false\n\n if (this.texture && this.gl) {\n this.gl.deleteTexture(this.texture)\n this.texture = null\n }\n\n this.changed()\n }\n\n /**\n * WebGL μ»¨ν…μŠ€νŠΈ μ΄ˆκΈ°ν™”\n */\n private _initializeWebGL(size: number[], pixelRatio: number = 1) {\n const width = Math.round(size[0] * pixelRatio)\n const height = Math.round(size[1] * pixelRatio)\n\n if (!this.canvas) {\n // μΊ”λ²„μŠ€ 생성 및 WebGL μ΄ˆκΈ°ν™”\n this.canvas = document.createElement('canvas')\n this.canvas.width = width\n this.canvas.height = height\n\n this.gl = this.canvas.getContext('webgl', {\n alpha: true,\n antialias: false,\n depth: false\n })\n\n if (!this.gl) return\n\n this.program = this._createShaderProgram()\n if (this.program) {\n this._initializeBuffers()\n }\n } else if (this.canvas.width !== width || this.canvas.height !== height) {\n // μΊ”λ²„μŠ€ 크기 μ‘°μ •\n this.canvas.width = width\n this.canvas.height = height\n if (this.gl) this.gl.viewport(0, 0, width, height)\n }\n }\n\n /**\n * λ²„ν…μŠ€ 버퍼 μ΄ˆκΈ°ν™”\n */\n private _initializeBuffers() {\n if (!this.gl) return\n\n // μ‚¬κ°ν˜• λ²„ν…μŠ€ (μœ„μΉ˜(x,y) + ν…μŠ€μ²˜ μ’Œν‘œ(s,t))\n const vertices = new Float32Array([\n -1,\n -1,\n 0,\n 1, // μ’Œν•˜λ‹¨\n 1,\n -1,\n 1,\n 1, // μš°ν•˜λ‹¨\n -1,\n 1,\n 0,\n 0, // μ’Œμƒλ‹¨\n 1,\n 1,\n 1,\n 0 // μš°μƒλ‹¨\n ])\n\n this.buffer = this.gl.createBuffer()\n this.gl.bindBuffer(this.gl.ARRAY_BUFFER, this.buffer)\n this.gl.bufferData(this.gl.ARRAY_BUFFER, vertices, this.gl.STATIC_DRAW)\n }\n\n /**\n * 이미지 λ‘œλ“œ 및 ν…μŠ€μ²˜ 생성\n */\n private _loadImage(url: string, worldExtent: number[], size: number[], resolution: number, pixelRatio: number) {\n const img = new Image()\n img.crossOrigin = 'anonymous'\n\n img.onload = () => {\n if (!this.gl) return\n\n try {\n // ν…μŠ€μ²˜ 생성 및 μ„€μ •\n this.texture = this.gl.createTexture()\n this.gl.bindTexture(this.gl.TEXTURE_2D, this.texture)\n\n // 경도 λ°©ν–₯으둜 λž˜ν•‘ (λ‚ μ§œ λ³€κ²½μ„  처리)\n // this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.REPEAT)\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_S, this.gl.CLAMP_TO_EDGE)\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_WRAP_T, this.gl.CLAMP_TO_EDGE)\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MIN_FILTER, this.gl.LINEAR)\n this.gl.texParameteri(this.gl.TEXTURE_2D, this.gl.TEXTURE_MAG_FILTER, this.gl.LINEAR)\n\n // ν…μŠ€μ²˜ 데이터 μ—…λ‘œλ“œ\n this.gl.pixelStorei(this.gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false) // μ•ŒνŒŒκ°’ 손싀 λ°©μ§€\n this.gl.texImage2D(this.gl.TEXTURE_2D, 0, this.gl.RGBA, this.gl.RGBA, this.gl.UNSIGNED_BYTE, img)\n\n this.imageLoaded = true\n this.pendingRender = false\n\n // 이미지 λ‘œλ“œ ν›„ λ Œλ”λ§\n this._renderTexture(worldExtent, size, resolution, pixelRatio)\n this.changed()\n } catch (err) {\n console.error('ν…μŠ€μ²˜ 생성 μ‹€νŒ¨:', err)\n this.pendingRender = false\n }\n }\n\n img.onerror = () => {\n console.error('이미지 λ‘œλ“œ μ‹€νŒ¨:', url)\n this.pendingRender = false\n }\n\n img.src = url\n }\n\n /**\n * ν…μŠ€μ²˜ λ Œλ”λ§\n */\n private _renderTexture(worldExtent: number[], size: number[], resolution: number, pixelRatio: number) {\n if (!this.gl || !this.program || !this.texture || !this.buffer) return\n\n const gl = this.gl\n const width = Math.round(size[0] * pixelRatio)\n const height = Math.round(size[1] * pixelRatio)\n\n this._updateWebGLUniforms(worldExtent, resolution, size, pixelRatio)\n\n // κΈ°λ³Έ WebGL μƒνƒœ μ„€μ •\n gl.viewport(0, 0, width, height)\n gl.clearColor(0, 0, 0, 0)\n gl.enable(gl.BLEND)\n gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)\n gl.clear(gl.COLOR_BUFFER_BIT)\n\n // 셰이더 ν”„λ‘œκ·Έλž¨ ν™œμ„±ν™”\n gl.useProgram(this.program)\n\n // ν…μŠ€μ²˜ 바인딩\n gl.activeTexture(gl.TEXTURE0)\n gl.bindTexture(gl.TEXTURE_2D, this.texture)\n\n // μœ λ‹ˆνΌ μ„€μ •\n const dataTypeVal = ['temperature', 'humidity', 'wind', 'precipitation'].indexOf(this.dataType)\n\n gl.uniform1i(gl.getUniformLocation(this.program, 'u_texture'), 0)\n gl.uniform1f(gl.getUniformLocation(this.program, 'u_opacity'), 0.8 * pixelRatio)\n gl.uniform1i(gl.getUniformLocation(this.program, 'u_dataType'), dataTypeVal >= 0 ? dataTypeVal : 0)\n gl.uniform4fv(\n gl.getUniformLocation(this.program, 'u_worldExtent'),\n new Float32Array([worldExtent[0], worldExtent[1], worldExtent[2], worldExtent[3]])\n )\n\n // 버퍼 바인딩 및 속성 μ„€μ •\n gl.bindBuffer(gl.ARRAY_BUFFER, this.buffer)\n\n const a_position = gl.getAttribLocation(this.program, 'a_position')\n const a_texCoord = gl.getAttribLocation(this.program, 'a_texCoord')\n\n gl.enableVertexAttribArray(a_position)\n gl.enableVertexAttribArray(a_texCoord)\n gl.vertexAttribPointer(a_position, 2, gl.FLOAT, false, 16, 0)\n gl.vertexAttribPointer(a_texCoord, 2, gl.FLOAT, false, 16, 8)\n\n // μ‚¬κ°ν˜• λ Œλ”λ§\n gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4)\n }\n\n /**\n * 셰이더 ν”„λ‘œκ·Έλž¨ 생성\n */\n private _createShaderProgram(): WebGLProgram | null {\n if (!this.gl) return null\n\n // λ²„ν…μŠ€ 셰이더: 지리 μ’Œν‘œμ™€ ν…μŠ€μ²˜ μ’Œν‘œ κ°„ λ³€ν™˜\n const vertexShaderSource = `\nprecision highp float;\n\nattribute vec4 a_position; // Rectangle coordinates\nattribute vec2 a_texCoord; // Texture coordinates\nvarying vec2 v_texCoord;\n\nuniform vec2 u_resolution; // Resolution (meters per pixel)\nuniform vec2 u_offset; // Offset in map coordinates\nuniform float u_zoomResolution; // πŸš€ This will store the resolution passed from JS\n\nvoid main() {\n float x = ((a_position.x - u_offset.x * u_zoomResolution) / u_resolution.x) * 2.0 - 1.0;\n float y = ((a_position.y - u_offset.y * u_zoomResolution) / u_resolution.y) * 2.0 - 1.0;\n\n gl_Position = vec4(x, y, 0.0, 1.0);\n v_texCoord = a_texCoord;\n}\n `\n\n // ν”„λž˜κ·Έλ¨ΌνŠΈ 셰이더: 데이터 μ‹œκ°ν™”\n const fragmentShaderSource = `\n precision highp float;\n \n uniform sampler2D u_texture;\n uniform float u_opacity;\n uniform int u_dataType;\n varying vec2 v_texCoord;\n \n // 색상 κ·ΈλΌλ°μ΄μ…˜ 생성\n vec3 getColorForData(float value) {\n // κ°’ λ²”μœ„ ν™•μž₯\n value = clamp(value * 1.2, 0.0, 1.0);\n \n if (u_dataType == 0) { // μ˜¨λ„\n // νŒŒλž‘(μ €μ˜¨) -> λΉ¨κ°•(고온)\n return mix(vec3(0.0, 0.0, 1.0), vec3(1.0, 0.0, 0.0), value);\n } \n else if (u_dataType == 1) { // μŠ΅λ„\n // ν•˜λŠ˜μƒ‰(건쑰) -> μ§„ν•œ νŒŒλž‘(μŠ΅ν•¨)\n return mix(vec3(0.5, 0.5, 1.0), vec3(0.0, 0.0, 0.8), value);\n }\n else if (u_dataType == 2) { // λ°”λžŒ\n // 녹색(약함) -> λ…Έλž‘(강함)\n return mix(vec3(0.0, 0.5, 0.0), vec3(1.0, 1.0, 0.0), value);\n }\n else { // κ°•μˆ˜λŸ‰\n // 투λͺ…(μ—†μŒ) -> 보라(많음)\n float intensity = value * 1.5;\n return vec3(0.5, 0.0, 0.5) * intensity;\n }\n }\n \n void main() {\n // ν…μŠ€μ²˜μ—μ„œ 데이터 κ°€μ Έμ˜€κΈ°\n vec4 texColor = texture2D(u_texture, v_texCoord);\n \n // 데이터가 μ—†λŠ” 경우 λ¬΄μ‹œ\n if (texColor.a < 0.01) {\n discard;\n }\n \n // 데이터 채널 선택\n float value = 0.0;\n if (u_dataType == 0) value = texColor.r; // μ˜¨λ„\n else if (u_dataType == 1) value = texColor.g; // μŠ΅λ„\n else if (u_dataType == 2) value = texColor.b; // λ°”λžŒ\n else value = texColor.a; // κ°•μˆ˜λŸ‰\n \n // 데이터 μ‹œκ°ν™”\n vec3 color = getColorForData(value);\n float alpha = u_dataType == 3 ? value * u_opacity : u_opacity;\n \n gl_FragColor = vec4(color, alpha);\n }\n `\n\n // 셰이더 컴파일\n const vertexShader = this._compileShader(this.gl.VERTEX_SHADER, vertexShaderSource)\n const fragmentShader = this._compileShader(this.gl.FRAGMENT_SHADER, fragmentShaderSource)\n\n if (!vertexShader || !fragmentShader) return null\n\n // ν”„λ‘œκ·Έλž¨ 생성 및 링크\n const program = this.gl.createProgram()!\n this.gl.attachShader(program, vertexShader)\n this.gl.attachShader(program, fragmentShader)\n this.gl.linkProgram(program)\n\n if (!this.gl.getProgramParameter(program, this.gl.LINK_STATUS)) {\n console.error('WebGL ν”„λ‘œκ·Έλž¨ 링크 μ‹€νŒ¨:', this.gl.getProgramInfoLog(program))\n return null\n }\n\n return program\n }\n\n /**\n * 셰이더 컴파일\n */\n private _compileShader(type: number, source: string): WebGLShader | null {\n if (!this.gl) return null\n\n const shader = this.gl.createShader(type)!\n this.gl.shaderSource(shader, source)\n this.gl.compileShader(shader)\n\n if (!this.gl.getShaderParameter(shader, this.gl.COMPILE_STATUS)) {\n console.error('셰이더 컴파일 였λ₯˜:', this.gl.getShaderInfoLog(shader))\n this.gl.deleteShader(shader)\n return null\n }\n\n return shader\n }\n\n private _updateWebGLUniforms(worldExtent: number[], resolution: number, size: number[], pixelRatio: number) {\n if (!this.gl || !this.program) return\n\n const gl = this.gl\n gl.useProgram(this.program)\n\n const textureWidth = size[0] * pixelRatio\n const textureHeight = size[1] * pixelRatio\n\n // βœ… Apply resolution correctly (fixing zoom scaling issue)\n const u_resolution = [\n (worldExtent[2] - worldExtent[0]) / textureWidth,\n (worldExtent[3] - worldExtent[1]) / textureHeight\n ]\n\n // βœ… Convert u_offset to OpenGL coordinates\n const u_offset = [\n (worldExtent[0] - (worldExtent[2] + worldExtent[0]) / 2) / (worldExtent[2] - worldExtent[0]),\n (worldExtent[1] - (worldExtent[3] + worldExtent[1]) / 2) / (worldExtent[3] - worldExtent[1])\n ]\n\n console.log('πŸ“Œ _updateWebGLUniforms called')\n console.log('🟒 resolution:', resolution)\n console.log('🟒 pixelRatio:', pixelRatio)\n console.log('🟒 textureWidth:', textureWidth, 'textureHeight:', textureHeight)\n console.log('🟒 u_resolution:', u_resolution)\n console.log('🟒 u_offset:', u_offset)\n\n gl.uniform2fv(gl.getUniformLocation(this.program, 'u_resolution'), u_resolution)\n gl.uniform2fv(gl.getUniformLocation(this.program, 'u_offset'), u_offset)\n gl.uniform1f(gl.getUniformLocation(this.program, 'u_zoomResolution'), resolution) // πŸš€ Pass resolution!\n }\n}\n\nexport default WebGLCanvasLayer\n"]}
@@ -0,0 +1,59 @@
1
+ import BaseLayer from 'ol/layer/Base.js';
2
+ import Map from 'ol/Map.js';
3
+ import { WeatherLayerType } from '@hyperviz/weather';
4
+ export declare class WindDataTileLayer {
5
+ private source;
6
+ private layer;
7
+ private map;
8
+ private useEnhancedColors;
9
+ private __disposed;
10
+ /**
11
+ * λ°”λžŒ 데이터 타일 λ ˆμ΄μ–΄ 생성
12
+ * @param options μ˜΅μ…˜ 객체
13
+ */
14
+ constructor(options?: {
15
+ useEnhancedColors?: boolean;
16
+ });
17
+ /**
18
+ * 타일 데이터 λ‘œλ”© ν•¨μˆ˜
19
+ * @private
20
+ */
21
+ private _tileLoader;
22
+ /**
23
+ * λ ˆμ΄μ–΄ νƒ€μž… λ°˜ν™˜ (ν˜Έν™˜μ„±μš©)
24
+ */
25
+ getType(): WeatherLayerType;
26
+ /**
27
+ * ν–₯μƒλœ 색상 λ§€ν•‘ μ‚¬μš© μ—¬λΆ€ μ„€μ •
28
+ */
29
+ setUseEnhancedColors(use: boolean): void;
30
+ /**
31
+ * OpenLayers λ ˆμ΄μ–΄ 객체 생성 λ˜λŠ” λ°˜ν™˜
32
+ */
33
+ createLayer(): BaseLayer;
34
+ /**
35
+ * μš”μ²­ 쀑인 데이터 λ‘œλ“œ 쀑단 및 μ†ŒμŠ€ λ¬΄νš¨ν™”
36
+ * @private
37
+ */
38
+ private _clearSourceData;
39
+ /**
40
+ * λ ˆμ΄μ–΄λ₯Ό 맡에 μΆ”κ°€
41
+ */
42
+ addToMap(map: Map): void;
43
+ /**
44
+ * λ ˆμ΄μ–΄λ₯Ό λ§΅μ—μ„œ 제거
45
+ */
46
+ removeFromMap(): void;
47
+ /**
48
+ * λ ˆμ΄μ–΄ κ΄€λ ¨ λ¦¬μ†ŒμŠ€ ν•΄μ œ
49
+ */
50
+ dispose(): void;
51
+ /**
52
+ * λ ˆμ΄μ–΄ μ—…λ°μ΄νŠΈ μš”μ²­ (데이터 λ³€κ²½ μ‹œ)
53
+ */
54
+ updateLayer(): void;
55
+ /**
56
+ * 데이터 μ„€μ • λ©”μ„œλ“œ (ν˜Έν™˜μ„±μš©, μ‹€μ œ λ°μ΄ν„°λŠ” PNG 이미지에 고정됨)
57
+ */
58
+ setWeatherData(data: any): void;
59
+ }