@mint-ui/map 1.2.0-test.20 → 1.2.0-test.21

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.
@@ -7,7 +7,38 @@ var MapTypes = require('../../../../types/MapTypes.js');
7
7
  require('../../../../types/MapEventTypes.js');
8
8
 
9
9
  /**
10
- * 폴리곤 offset 계산
10
+ * @fileoverview WoongCanvasLayer를 위한 유틸리티 함수들
11
+ *
12
+ * 이 파일은 좌표 변환, 히트 테스트, 색상 변환 등 WoongCanvasLayer에서
13
+ * 사용하는 다양한 유틸리티 함수들을 제공합니다.
14
+ *
15
+ * ## 주요 기능
16
+ * - **좌표 변환**: 지도 좌표(위경도) ↔ 화면 좌표(픽셀) 변환
17
+ * - **히트 테스트**: 마우스 클릭/호버 시 어떤 마커/폴리곤인지 찾기
18
+ * - **색상 변환**: 다양한 색상 형식 간 변환
19
+ * - **바운딩 박스**: 폴리곤의 경계 영역 계산
20
+ *
21
+ * @version 2.2.1
22
+ * @since 2.0.0
23
+ * @author 박건웅
24
+ */
25
+ /**
26
+ * 폴리곤 좌표를 화면 좌표로 변환
27
+ *
28
+ * GeoJSON MultiPolygon 형식의 폴리곤 데이터를 Canvas에서 그릴 수 있는
29
+ * 화면 좌표 배열로 변환합니다.
30
+ *
31
+ * @param polygonData - 변환할 폴리곤 데이터
32
+ * @param controller - 지도 컨트롤러 (좌표 변환용)
33
+ * @returns 변환된 좌표 배열 또는 null (변환 실패 시)
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const offsets = computePolygonOffsets(polygonData, controller);
38
+ * if (offsets) {
39
+ * // offsets[0][0][0] = [x, y] - 첫 번째 MultiPolygon의 첫 번째 Polygon의 첫 번째 점
40
+ * }
41
+ * ```
11
42
  */
12
43
 
13
44
  var computePolygonOffsets = function (polygonData, controller) {
@@ -43,7 +74,21 @@ var computePolygonOffsets = function (polygonData, controller) {
43
74
  return result;
44
75
  };
45
76
  /**
46
- * 마커 offset 계산
77
+ * 마커 좌표를 화면 좌표로 변환
78
+ *
79
+ * 마커의 지도 좌표(위경도)를 Canvas에서 그릴 수 있는 화면 좌표로 변환합니다.
80
+ *
81
+ * @param markerData - 변환할 마커 데이터
82
+ * @param controller - 지도 컨트롤러 (좌표 변환용)
83
+ * @returns 변환된 화면 좌표 또는 null (변환 실패 시)
84
+ *
85
+ * @example
86
+ * ```typescript
87
+ * const offset = computeMarkerOffset(markerData, controller);
88
+ * if (offset) {
89
+ * console.log(`마커 위치: (${offset.x}, ${offset.y})`);
90
+ * }
91
+ * ```
47
92
  */
48
93
 
49
94
  var computeMarkerOffset = function (markerData, controller) {
@@ -54,7 +99,21 @@ var computeMarkerOffset = function (markerData, controller) {
54
99
  return controller.positionToOffset(markerData.position);
55
100
  };
56
101
  /**
57
- * Point-in-Polygon 알고리즘
102
+ * Point-in-Polygon 알고리즘 (Ray Casting)
103
+ *
104
+ * 주어진 점이 폴리곤 내부에 있는지 확인하는 알고리즘입니다.
105
+ * Ray Casting 방식을 사용하여 홀수 번 교차하면 내부, 짝수 번 교차하면 외부로 판단합니다.
106
+ *
107
+ * @param point - 확인할 점의 좌표
108
+ * @param polygon - 폴리곤의 좌표 배열 (순서대로 연결된 점들)
109
+ * @returns 점이 폴리곤 내부에 있으면 true, 외부에 있으면 false
110
+ *
111
+ * @example
112
+ * ```typescript
113
+ * const point = { x: 100, y: 100 };
114
+ * const polygon = [[0, 0], [200, 0], [200, 200], [0, 200]];
115
+ * const isInside = isPointInPolygon(point, polygon); // true
116
+ * ```
58
117
  */
59
118
 
60
119
  var isPointInPolygon = function (point, polygon) {
@@ -74,13 +133,31 @@ var isPointInPolygon = function (point, polygon) {
74
133
  /**
75
134
  * 폴리곤 히트 테스트 (도넛 폴리곤 지원)
76
135
  *
77
- * 로직:
78
- * 1. 외부 폴리곤( 번째): 내부에 있어야 함
79
- * 2. 내부 구멍들(나머지): 내부에 있으면 안 됨 (evenodd 규칙)
136
+ * 클릭된 좌표가 폴리곤 내부에 있는지 확인합니다.
137
+ * 도넛 폴리곤(구멍이 있는 폴리곤) 지원합니다.
138
+ *
139
+ * ## 도넛 폴리곤 처리 로직
140
+ * 1. **외부 폴리곤(첫 번째)**: 내부에 있어야 함
141
+ * 2. **내부 구멍들(나머지)**: 내부에 있으면 안 됨 (evenodd 규칙)
80
142
  *
81
- * 중요: 도넛 폴리곤과 내부 폴리곤은 별개의 polygonData로 처리됨
82
- * - 도넛 폴리곤 A: isDonutPolygon=true
83
- * - 내부 폴리곤 B: isDonutPolygon=false (별도 데이터)
143
+ * ## 중요 사항
144
+ * 도넛 폴리곤과 내부 폴리곤은 별개의 polygonData로 처리됩니다:
145
+ * - 도넛 폴리곤 A: `isDonutPolygon=true`
146
+ * - 내부 폴리곤 B: `isDonutPolygon=false` (별도 데이터)
147
+ *
148
+ * @param clickedOffset - 클릭된 좌표
149
+ * @param polygonData - 확인할 폴리곤 데이터
150
+ * @param getPolygonOffsets - 폴리곤 좌표를 가져오는 함수
151
+ * @returns 클릭된 좌표가 폴리곤 내부에 있으면 true, 외부에 있으면 false
152
+ *
153
+ * @example
154
+ * ```typescript
155
+ * const isHit = isPointInPolygonData(
156
+ * { x: 100, y: 100 },
157
+ * polygonData,
158
+ * (data) => computePolygonOffsets(data, controller)
159
+ * );
160
+ * ```
84
161
  */
85
162
 
86
163
  var isPointInPolygonData = function (clickedOffset, polygonData, getPolygonOffsets) {
@@ -145,10 +222,27 @@ var isPointInPolygonData = function (clickedOffset, polygonData, getPolygonOffse
145
222
  /**
146
223
  * 마커 히트 테스트 (클릭/hover 영역 체크)
147
224
  *
148
- * 🎯 중요: 꼬리(tail)는 Hit Test 영역에서 제외됩니다!
149
- * - markerOffset.y는 마커 최하단(꼬리 끝) 좌표
150
- * - boxHeight는 마커 본체만 포함 (꼬리 제외)
151
- * - tailHeight만큼 위로 올려서 본체만 Hit Test 영역으로 사용
225
+ * 클릭된 좌표가 마커의 클릭 가능한 영역 내부에 있는지 확인합니다.
226
+ *
227
+ * ## 중요 사항
228
+ * **꼬리(tail)는 Hit Test 영역에서 제외됩니다!**
229
+ * - `markerOffset.y`는 마커 최하단(꼬리 끝) 좌표
230
+ * - `boxHeight`는 마커 본체만 포함 (꼬리 제외)
231
+ * - `tailHeight`만큼 위로 올려서 본체만 Hit Test 영역으로 사용
232
+ *
233
+ * @param clickedOffset - 클릭된 좌표
234
+ * @param markerData - 확인할 마커 데이터
235
+ * @param getMarkerOffset - 마커 좌표를 가져오는 함수
236
+ * @returns 클릭된 좌표가 마커 내부에 있으면 true, 외부에 있으면 false
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * const isHit = isPointInMarkerData(
241
+ * { x: 100, y: 100 },
242
+ * markerData,
243
+ * (data) => computeMarkerOffset(data, controller)
244
+ * );
245
+ * ```
152
246
  */
153
247
 
154
248
  var isPointInMarkerData = function (clickedOffset, markerData, getMarkerOffset) {
@@ -163,13 +257,29 @@ var isPointInMarkerData = function (clickedOffset, markerData, getMarkerOffset)
163
257
 
164
258
  return clickedOffset.x >= x && clickedOffset.x <= x + boxWidth && clickedOffset.y >= y && clickedOffset.y <= y + boxHeight;
165
259
  };
260
+ /**
261
+ * HEX 색상을 RGBA 색상으로 변환
262
+ *
263
+ * 16진수 색상 코드를 RGBA 형식으로 변환합니다.
264
+ *
265
+ * @param hexColor - 변환할 HEX 색상 (예: "#FF0000" 또는 "FF0000")
266
+ * @param alpha - 알파 값 (0~1, 기본값: 1)
267
+ * @returns RGBA 형식의 색상 문자열
268
+ *
269
+ * @example
270
+ * ```typescript
271
+ * const rgba = hexToRgba('#FF0000', 0.5); // "rgba(255, 0, 0, 0.5)"
272
+ * const rgba2 = hexToRgba('FF0000', 1); // "rgba(255, 0, 0, 1)"
273
+ * ```
274
+ */
275
+
166
276
  var hexToRgba = function (hexColor, alpha) {
167
277
  if (alpha === void 0) {
168
278
  alpha = 1;
169
- } // NOTE: 입력된 hexColor에서 "#" 제거
279
+ } // 입력된 hexColor에서 "#" 제거
170
280
 
171
281
 
172
- var hex = hexColor.replace('#', ''); // NOTE: 6자리일 경우 알파 값은 사용자가 제공한 alpha 값으로 설정
282
+ var hex = hexColor.replace('#', ''); // 6자리일 경우 알파 값은 사용자가 제공한 alpha 값으로 설정
173
283
 
174
284
  if (hex.length === 6) {
175
285
  var r = parseInt(hex.substring(0, 2), 16);
@@ -183,14 +293,27 @@ var hexToRgba = function (hexColor, alpha) {
183
293
  var tempCanvas = document.createElement('canvas');
184
294
  var tempCtx = tempCanvas.getContext('2d');
185
295
  /**
186
- * 텍스트 박스의 너비를 계산합니다.
187
- *
188
- * @param {Object} params - 파라미터 객체
189
- * @param {string} params.text - 측정할 텍스트
190
- * @param {string} params.fontConfig - 폰트 설정 (예: 'bold 16px Arial')
191
- * @param {number} params.padding - 텍스트 박스에 적용할 패딩 값
192
- * @param {number} params.minWidth - 최소 너비
193
- * @returns {number} 계산된 텍스트 박스의 너비
296
+ * 텍스트 박스의 너비를 계산
297
+ *
298
+ * Canvas 2D API의 measureText()를 사용하여 텍스트의 실제 너비를 측정하고,
299
+ * 패딩과 최소 너비를 고려하여 최종 박스 너비를 계산합니다.
300
+ *
301
+ * @param params - 파라미터 객체
302
+ * @param params.text - 측정할 텍스트
303
+ * @param params.fontConfig - 폰트 설정 (예: 'bold 16px Arial')
304
+ * @param params.padding - 텍스트 박스에 적용할 패딩 값
305
+ * @param params.minWidth - 최소 너비
306
+ * @returns 계산된 텍스트 박스의 너비
307
+ *
308
+ * @example
309
+ * ```typescript
310
+ * const width = calculateTextBoxWidth({
311
+ * text: 'Hello World',
312
+ * fontConfig: 'bold 16px Arial',
313
+ * padding: 10,
314
+ * minWidth: 50
315
+ * });
316
+ * ```
194
317
  */
195
318
 
196
319
  var calculateTextBoxWidth = function (_a) {