@uniai-fe/uds-templates 0.5.28 → 0.6.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 +3 -6
- package/dist/styles.css +1 -1
- package/package.json +1 -1
- package/src/cctv/styles/variables.scss +1 -1
- package/src/weather/_legacy/apis/index.ts +4 -0
- package/src/weather/_legacy/data/response.ts +36 -0
- package/src/weather/_legacy/hooks/index.ts +5 -0
- package/src/weather/{hooks → _legacy/hooks}/useOpenWeatherMap.ts +1 -1
- package/src/weather/{hooks → _legacy/hooks}/useWeatherKorea.ts +4 -7
- package/src/weather/{hooks → _legacy/hooks}/useWeatherKoreaAlert.ts +2 -4
- package/src/weather/_legacy/types/api.ts +221 -0
- package/src/weather/_legacy/types/base.ts +70 -0
- package/src/weather/_legacy/types/index.ts +4 -0
- package/src/weather/_legacy/utils/index.ts +5 -0
- package/src/weather/_legacy/utils/locale.ts +28 -0
- package/src/weather/_legacy/utils/location.ts +139 -0
- package/src/weather/_legacy/utils/weather.ts +460 -0
- package/src/weather/apis/client.ts +339 -0
- package/src/weather/apis/index.ts +2 -4
- package/src/weather/apis/server.ts +264 -0
- package/src/weather/components/icon/Address.tsx +7 -0
- package/src/weather/components/icon/Weather.tsx +7 -6
- package/src/weather/components/page-header/Address.tsx +14 -0
- package/src/weather/components/page-header/Alert.tsx +17 -13
- package/src/weather/components/page-header/Container.tsx +12 -19
- package/src/weather/components/page-header/Forecast.tsx +21 -28
- package/src/weather/components/page-header/NextDays.tsx +10 -0
- package/src/weather/components/page-header/Today.tsx +86 -158
- package/src/weather/components/page-header/index.ts +5 -0
- package/src/weather/data/response.ts +4 -23
- package/src/weather/hooks/index.ts +3 -3
- package/src/weather/hooks/useWeather.ts +52 -0
- package/src/weather/hooks/useWeatherAlert.ts +35 -0
- package/src/weather/index.tsx +2 -2
- package/src/weather/jotai/coordinate.ts +4 -0
- package/src/weather/jotai/farm-idx.ts +4 -0
- package/src/weather/types/api.ts +393 -114
- package/src/weather/types/base.ts +15 -32
- package/src/weather/types/index.ts +0 -3
- package/src/weather/types/page-header.ts +118 -68
- package/src/weather/utils/index.ts +6 -4
- package/src/weather/utils/locale.ts +7 -69
- package/src/weather/utils/location.ts +6 -141
- package/src/weather/utils/weather.ts +53 -456
- package/src/weather/data/alert-regions-meta.json +0 -1286
- package/src/weather/data/weather-regions-meta.json +0 -9833
- package/src/weather/types/provider.ts +0 -34
- package/src/weather/utils/alert.ts +0 -30
- /package/src/weather/{apis → _legacy/apis}/korea/client.ts +0 -0
- /package/src/weather/{apis → _legacy/apis}/korea/server.ts +0 -0
- /package/src/weather/{apis → _legacy/apis}/open-weather-map/client.ts +0 -0
- /package/src/weather/{apis → _legacy/apis}/open-weather-map/server.ts +0 -0
- /package/src/weather/{types → _legacy/types}/korea.ts +0 -0
- /package/src/weather/{types → _legacy/types}/open-weather-map.ts +0 -0
- /package/src/weather/{utils → _legacy/utils}/date-time.ts +0 -0
- /package/src/weather/{utils → _legacy/utils}/validate.ts +0 -0
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
API_Res_WeatherAlertItem,
|
|
3
|
+
API_Res_WeatherForecast,
|
|
4
|
+
API_Res_WeatherNextDays,
|
|
5
|
+
API_Res_WeatherNow,
|
|
5
6
|
} from "./api";
|
|
6
|
-
import type {
|
|
7
|
-
OWM_Res_Weather_Forecast,
|
|
8
|
-
OWM_Res_Weather_Now,
|
|
9
|
-
} from "./open-weather-map";
|
|
10
7
|
|
|
11
8
|
/**
|
|
12
|
-
* Weather Page Header; locale
|
|
9
|
+
* Weather Page Header; locale 옵션.
|
|
13
10
|
* @property {string} [locale] 표시 언어 코드. 기본 지원값은 ko, en, ja이며 타입은 확장 가능한 string으로 유지한다.
|
|
14
11
|
*/
|
|
15
12
|
export interface WeatherLocaleOptions {
|
|
@@ -20,7 +17,7 @@ export interface WeatherLocaleOptions {
|
|
|
20
17
|
}
|
|
21
18
|
|
|
22
19
|
/**
|
|
23
|
-
* Weather Page Header; 텍스트
|
|
20
|
+
* Weather Page Header; 텍스트 옵션.
|
|
24
21
|
* @property {string} currentWeatherLoading 현재 날씨 로딩 문구
|
|
25
22
|
* @property {string} forecastWeatherLoading 예보 날씨 로딩 문구
|
|
26
23
|
* @property {string} alertLoading 특보 로딩 문구
|
|
@@ -106,11 +103,15 @@ export interface WeatherPageHeaderTexts {
|
|
|
106
103
|
}
|
|
107
104
|
|
|
108
105
|
/**
|
|
109
|
-
* Weather Page Header; locale과 텍스트 override 조합
|
|
106
|
+
* Weather Page Header; locale과 텍스트 override 조합 옵션.
|
|
110
107
|
* @property {string} [locale] 표시 언어 코드
|
|
111
108
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
112
109
|
*/
|
|
113
110
|
export interface WeatherPageHeaderLocaleOptions extends WeatherLocaleOptions {
|
|
111
|
+
/**
|
|
112
|
+
* 표시 언어 코드
|
|
113
|
+
*/
|
|
114
|
+
locale?: string;
|
|
114
115
|
/**
|
|
115
116
|
* 서비스에서 주입한 표시 문구
|
|
116
117
|
*/
|
|
@@ -118,47 +119,32 @@ export interface WeatherPageHeaderLocaleOptions extends WeatherLocaleOptions {
|
|
|
118
119
|
}
|
|
119
120
|
|
|
120
121
|
/**
|
|
121
|
-
* Weather Page Header;
|
|
122
|
-
* @property {
|
|
123
|
-
* @property {
|
|
122
|
+
* Weather Page Header; 통합 weather query 결과.
|
|
123
|
+
* @property {API_Res_WeatherNow} [now] 현재 날씨 응답
|
|
124
|
+
* @property {API_Res_WeatherForecast} [forecast] 예보 날씨 응답
|
|
125
|
+
* @property {API_Res_WeatherAlertItem[]} alert 특보 목록
|
|
126
|
+
* @property {boolean} isFetching 현재/예보/특보 조회 상태
|
|
124
127
|
* @property {boolean} isFetchingNow 현재 날씨 조회 상태
|
|
125
128
|
* @property {boolean} isFetchingForecast 예보 날씨 조회 상태
|
|
129
|
+
* @property {boolean} isFetchingAlert 특보 조회 상태
|
|
126
130
|
*/
|
|
127
|
-
export interface
|
|
131
|
+
export interface WeatherPageHeaderWeather {
|
|
128
132
|
/**
|
|
129
133
|
* 현재 날씨 응답
|
|
130
134
|
*/
|
|
131
|
-
now?:
|
|
135
|
+
now?: API_Res_WeatherNow;
|
|
132
136
|
/**
|
|
133
137
|
* 예보 날씨 응답
|
|
134
138
|
*/
|
|
135
|
-
forecast?:
|
|
136
|
-
/**
|
|
137
|
-
* 현재 날씨 조회 상태
|
|
138
|
-
*/
|
|
139
|
-
isFetchingNow: boolean;
|
|
140
|
-
/**
|
|
141
|
-
* 예보 날씨 조회 상태
|
|
142
|
-
*/
|
|
143
|
-
isFetchingForecast: boolean;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* Weather Page Header; OpenWeatherMap query 결과
|
|
148
|
-
* @property {OWM_Res_Weather_Now} [now] 현재 날씨 응답
|
|
149
|
-
* @property {OWM_Res_Weather_Forecast} [forecast] 예보 날씨 응답
|
|
150
|
-
* @property {boolean} isFetchingNow 현재 날씨 조회 상태
|
|
151
|
-
* @property {boolean} isFetchingForecast 예보 날씨 조회 상태
|
|
152
|
-
*/
|
|
153
|
-
export interface WeatherPageHeaderOpenWeatherMapWeather {
|
|
139
|
+
forecast?: API_Res_WeatherForecast;
|
|
154
140
|
/**
|
|
155
|
-
*
|
|
141
|
+
* 특보 목록
|
|
156
142
|
*/
|
|
157
|
-
|
|
143
|
+
alert: API_Res_WeatherAlertItem[];
|
|
158
144
|
/**
|
|
159
|
-
*
|
|
145
|
+
* 현재/예보/특보 조회 상태
|
|
160
146
|
*/
|
|
161
|
-
|
|
147
|
+
isFetching: boolean;
|
|
162
148
|
/**
|
|
163
149
|
* 현재 날씨 조회 상태
|
|
164
150
|
*/
|
|
@@ -167,73 +153,137 @@ export interface WeatherPageHeaderOpenWeatherMapWeather {
|
|
|
167
153
|
* 예보 날씨 조회 상태
|
|
168
154
|
*/
|
|
169
155
|
isFetchingForecast: boolean;
|
|
156
|
+
/**
|
|
157
|
+
* 특보 조회 상태
|
|
158
|
+
*/
|
|
159
|
+
isFetchingAlert: boolean;
|
|
170
160
|
}
|
|
171
161
|
|
|
172
162
|
/**
|
|
173
|
-
* Weather Page Header; 상위 container에서 준비한 weather query
|
|
174
|
-
* @property {
|
|
175
|
-
* @property {WeatherPageHeaderOpenWeatherMapWeather} [openWeatherMapWeather] OpenWeatherMap query 결과
|
|
163
|
+
* Weather Page Header; 상위 container에서 준비한 weather query 결과.
|
|
164
|
+
* @property {WeatherPageHeaderWeather} [weather] 통합 weather query 결과
|
|
176
165
|
*/
|
|
177
166
|
export interface WeatherPageHeaderDataOptions {
|
|
178
167
|
/**
|
|
179
|
-
*
|
|
168
|
+
* 통합 weather query 결과
|
|
180
169
|
*/
|
|
181
|
-
|
|
182
|
-
/**
|
|
183
|
-
* OpenWeatherMap query 결과
|
|
184
|
-
*/
|
|
185
|
-
openWeatherMapWeather?: WeatherPageHeaderOpenWeatherMapWeather;
|
|
170
|
+
weather?: WeatherPageHeaderWeather;
|
|
186
171
|
}
|
|
187
172
|
|
|
188
173
|
/**
|
|
189
|
-
* Weather Page Header; container props
|
|
174
|
+
* Weather Page Header; container props.
|
|
190
175
|
* @property {string} [locale] 표시 언어 코드
|
|
191
176
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
192
177
|
*/
|
|
193
|
-
export
|
|
178
|
+
export interface WeatherPageHeaderContainerProps extends WeatherPageHeaderLocaleOptions {
|
|
179
|
+
/**
|
|
180
|
+
* 표시 언어 코드
|
|
181
|
+
*/
|
|
182
|
+
locale?: string;
|
|
183
|
+
/**
|
|
184
|
+
* 서비스에서 주입한 표시 문구
|
|
185
|
+
*/
|
|
186
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
187
|
+
}
|
|
194
188
|
|
|
195
189
|
/**
|
|
196
|
-
* Weather Page Header; address props
|
|
190
|
+
* Weather Page Header; address props.
|
|
197
191
|
* @property {string} [locale] 표시 언어 코드
|
|
198
192
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
199
193
|
*/
|
|
200
|
-
export
|
|
194
|
+
export interface WeatherPageHeaderAddressProps extends WeatherPageHeaderLocaleOptions {
|
|
195
|
+
/**
|
|
196
|
+
* 표시 언어 코드
|
|
197
|
+
*/
|
|
198
|
+
locale?: string;
|
|
199
|
+
/**
|
|
200
|
+
* 서비스에서 주입한 표시 문구
|
|
201
|
+
*/
|
|
202
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
203
|
+
}
|
|
201
204
|
|
|
202
205
|
/**
|
|
203
|
-
* Weather Page Header; today props
|
|
206
|
+
* Weather Page Header; today props.
|
|
204
207
|
* @property {string} [locale] 표시 언어 코드
|
|
205
208
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
206
|
-
* @property {
|
|
207
|
-
* @property {WeatherPageHeaderOpenWeatherMapWeather} [openWeatherMapWeather] OpenWeatherMap query 결과
|
|
209
|
+
* @property {WeatherPageHeaderWeather} [weather] 상위 container에서 준비한 통합 weather query 결과
|
|
208
210
|
*/
|
|
209
|
-
export
|
|
210
|
-
WeatherPageHeaderDataOptions
|
|
211
|
+
export interface WeatherPageHeaderTodayProps
|
|
212
|
+
extends WeatherPageHeaderLocaleOptions, WeatherPageHeaderDataOptions {
|
|
213
|
+
/**
|
|
214
|
+
* 표시 언어 코드
|
|
215
|
+
*/
|
|
216
|
+
locale?: string;
|
|
217
|
+
/**
|
|
218
|
+
* 서비스에서 주입한 표시 문구
|
|
219
|
+
*/
|
|
220
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
221
|
+
/**
|
|
222
|
+
* 통합 weather query 결과
|
|
223
|
+
*/
|
|
224
|
+
weather?: WeatherPageHeaderWeather;
|
|
225
|
+
}
|
|
211
226
|
|
|
212
227
|
/**
|
|
213
|
-
* Weather Page Header; forecast props
|
|
228
|
+
* Weather Page Header; forecast props.
|
|
214
229
|
* @property {string} [locale] 표시 언어 코드
|
|
215
230
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
216
|
-
* @property {
|
|
217
|
-
* @property {WeatherPageHeaderOpenWeatherMapWeather} [openWeatherMapWeather] OpenWeatherMap query 결과
|
|
231
|
+
* @property {WeatherPageHeaderWeather} [weather] 상위 container에서 준비한 통합 weather query 결과
|
|
218
232
|
*/
|
|
219
|
-
export
|
|
220
|
-
WeatherPageHeaderDataOptions
|
|
233
|
+
export interface WeatherPageHeaderForecastProps
|
|
234
|
+
extends WeatherPageHeaderLocaleOptions, WeatherPageHeaderDataOptions {
|
|
235
|
+
/**
|
|
236
|
+
* 표시 언어 코드
|
|
237
|
+
*/
|
|
238
|
+
locale?: string;
|
|
239
|
+
/**
|
|
240
|
+
* 서비스에서 주입한 표시 문구
|
|
241
|
+
*/
|
|
242
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
243
|
+
/**
|
|
244
|
+
* 통합 weather query 결과
|
|
245
|
+
*/
|
|
246
|
+
weather?: WeatherPageHeaderWeather;
|
|
247
|
+
}
|
|
221
248
|
|
|
222
249
|
/**
|
|
223
|
-
* Weather Page Header; alert props
|
|
250
|
+
* Weather Page Header; alert props.
|
|
224
251
|
* @property {string} [locale] 표시 언어 코드
|
|
225
252
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
253
|
+
* @property {WeatherPageHeaderWeather} [weather] 상위 container에서 준비한 통합 weather query 결과
|
|
226
254
|
*/
|
|
227
|
-
export
|
|
255
|
+
export interface WeatherPageHeaderAlertProps
|
|
256
|
+
extends WeatherPageHeaderLocaleOptions, WeatherPageHeaderDataOptions {
|
|
257
|
+
/**
|
|
258
|
+
* 표시 언어 코드
|
|
259
|
+
*/
|
|
260
|
+
locale?: string;
|
|
261
|
+
/**
|
|
262
|
+
* 서비스에서 주입한 표시 문구
|
|
263
|
+
*/
|
|
264
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
265
|
+
/**
|
|
266
|
+
* 통합 weather query 결과
|
|
267
|
+
*/
|
|
268
|
+
weather?: WeatherPageHeaderWeather;
|
|
269
|
+
}
|
|
228
270
|
|
|
229
271
|
/**
|
|
230
|
-
* Weather Page Header; next days props
|
|
272
|
+
* Weather Page Header; next days props.
|
|
231
273
|
* @property {string} title 날짜 라벨
|
|
232
|
-
* @property {
|
|
274
|
+
* @property {API_Res_WeatherNextDays} [data] 예보 데이터
|
|
233
275
|
* @property {string} [locale] 표시 언어 코드
|
|
234
276
|
* @property {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 표시 문구
|
|
235
277
|
*/
|
|
236
278
|
export interface WeatherPageHeaderNextDaysProps extends WeatherPageHeaderLocaleOptions {
|
|
279
|
+
/**
|
|
280
|
+
* 표시 언어 코드
|
|
281
|
+
*/
|
|
282
|
+
locale?: string;
|
|
283
|
+
/**
|
|
284
|
+
* 서비스에서 주입한 표시 문구
|
|
285
|
+
*/
|
|
286
|
+
texts?: Partial<WeatherPageHeaderTexts>;
|
|
237
287
|
/**
|
|
238
288
|
* 날짜 라벨
|
|
239
289
|
*/
|
|
@@ -241,11 +291,11 @@ export interface WeatherPageHeaderNextDaysProps extends WeatherPageHeaderLocaleO
|
|
|
241
291
|
/**
|
|
242
292
|
* 예보 데이터
|
|
243
293
|
*/
|
|
244
|
-
data?:
|
|
294
|
+
data?: API_Res_WeatherNextDays;
|
|
245
295
|
}
|
|
246
296
|
|
|
247
297
|
/**
|
|
248
|
-
* Weather Icon; 날씨 아이콘 props
|
|
298
|
+
* Weather Icon; 날씨 아이콘 props.
|
|
249
299
|
* @property {string | null} [code] 날씨 아이콘 코드
|
|
250
300
|
* @property {string | null} [name] 날씨 상태 이름
|
|
251
301
|
* @property {string} [alt] 아이콘 대체 텍스트 fallback
|
|
@@ -266,7 +316,7 @@ export interface WeatherIconProps {
|
|
|
266
316
|
}
|
|
267
317
|
|
|
268
318
|
/**
|
|
269
|
-
* Weather Address Icon; 위치 아이콘 props
|
|
319
|
+
* Weather Address Icon; 위치 아이콘 props.
|
|
270
320
|
* @property {string} [alt] 아이콘 대체 텍스트
|
|
271
321
|
*/
|
|
272
322
|
export interface WeatherAddressIconProps {
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export * from "./location";
|
|
2
|
-
export
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
export {
|
|
3
|
+
isWeatherForecastResponse,
|
|
4
|
+
isWeatherNowResponse,
|
|
5
|
+
isWeatherSummaryResponse,
|
|
6
|
+
} from "./weather";
|
|
7
|
+
export { getWeatherLocaleKey, resolveWeatherPageHeaderTexts } from "./locale";
|
|
@@ -1,8 +1,4 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
WeatherPageHeaderTexts,
|
|
3
|
-
WeatherProviderCapabilityRegistry,
|
|
4
|
-
WeatherProviderKey,
|
|
5
|
-
} from "../types";
|
|
1
|
+
import type { WeatherPageHeaderTexts } from "../types";
|
|
6
2
|
|
|
7
3
|
const WEATHER_PAGE_HEADER_DEFAULT_TEXTS: WeatherPageHeaderTexts = {
|
|
8
4
|
currentWeatherLoading: "현재 날씨 불러오는 중...",
|
|
@@ -23,34 +19,10 @@ const WEATHER_PAGE_HEADER_DEFAULT_TEXTS: WeatherPageHeaderTexts = {
|
|
|
23
19
|
alertIssueCommandLabel: "발령",
|
|
24
20
|
};
|
|
25
21
|
|
|
26
|
-
const OPEN_WEATHER_MAP_LANG_BY_LOCALE: Record<string, string> = {
|
|
27
|
-
ko: "kr",
|
|
28
|
-
en: "en",
|
|
29
|
-
ja: "ja",
|
|
30
|
-
};
|
|
31
|
-
|
|
32
|
-
const WEATHER_DEFAULT_PROVIDER: WeatherProviderKey = "openWeatherMap";
|
|
33
|
-
|
|
34
|
-
const WEATHER_PROVIDER_BY_LOCALE_KEY: Record<string, WeatherProviderKey> = {
|
|
35
|
-
ko: "kma",
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
export const WEATHER_PROVIDER_CAPABILITIES: WeatherProviderCapabilityRegistry =
|
|
39
|
-
{
|
|
40
|
-
kma: {
|
|
41
|
-
now: true,
|
|
42
|
-
forecast: true,
|
|
43
|
-
alert: true,
|
|
44
|
-
},
|
|
45
|
-
openWeatherMap: {
|
|
46
|
-
now: true,
|
|
47
|
-
forecast: true,
|
|
48
|
-
alert: false,
|
|
49
|
-
},
|
|
50
|
-
};
|
|
51
|
-
|
|
52
22
|
/**
|
|
53
|
-
* Weather Locale; locale 기준 키
|
|
23
|
+
* Weather Locale; locale 기준 키 정규화.
|
|
24
|
+
* @util
|
|
25
|
+
* @desc service locale 문자열에서 weather API/표시 로직에 사용할 기본 언어 키를 추출한다.
|
|
54
26
|
* @param {string} [locale] locale 코드
|
|
55
27
|
* @return {string} 전달된 locale의 기본 언어 코드
|
|
56
28
|
* @example
|
|
@@ -60,30 +32,9 @@ export const getWeatherLocaleKey = (locale?: string): string =>
|
|
|
60
32
|
locale?.trim().toLowerCase().split(/[-_]/)[0] || "ko";
|
|
61
33
|
|
|
62
34
|
/**
|
|
63
|
-
* Weather Locale;
|
|
64
|
-
* @
|
|
65
|
-
* @
|
|
66
|
-
* @example
|
|
67
|
-
* resolveWeatherProvider("ko-KR")
|
|
68
|
-
*/
|
|
69
|
-
export const resolveWeatherProvider = (locale?: string): WeatherProviderKey => {
|
|
70
|
-
const localeKey = getWeatherLocaleKey(locale);
|
|
71
|
-
|
|
72
|
-
return WEATHER_PROVIDER_BY_LOCALE_KEY[localeKey] ?? WEATHER_DEFAULT_PROVIDER;
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Weather Locale; KMA provider 사용 여부
|
|
77
|
-
* @param {string} [locale] locale 코드
|
|
78
|
-
* @return {boolean} KMA provider 대상 locale 여부
|
|
79
|
-
* @example
|
|
80
|
-
* isKoreaWeatherLocale("ko-KR")
|
|
81
|
-
*/
|
|
82
|
-
export const isKoreaWeatherLocale = (locale?: string): boolean =>
|
|
83
|
-
resolveWeatherProvider(locale) === "kma";
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Weather Locale; page-header 텍스트 병합
|
|
35
|
+
* Weather Locale; page-header 텍스트 병합.
|
|
36
|
+
* @util
|
|
37
|
+
* @desc service가 주입한 일부 표시 문구를 weather page-header 기본 문구와 병합한다.
|
|
87
38
|
* @param {Partial<WeatherPageHeaderTexts>} [texts] 서비스에서 주입한 텍스트
|
|
88
39
|
* @return {WeatherPageHeaderTexts} 기본 fallback과 서비스 주입 텍스트를 병합한 텍스트
|
|
89
40
|
* @example
|
|
@@ -95,16 +46,3 @@ export const resolveWeatherPageHeaderTexts = (
|
|
|
95
46
|
...WEATHER_PAGE_HEADER_DEFAULT_TEXTS,
|
|
96
47
|
...texts,
|
|
97
48
|
});
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Weather Locale; OpenWeatherMap API lang 값 변환
|
|
101
|
-
* @param {string} [locale] locale 코드
|
|
102
|
-
* @return {string} OpenWeatherMap lang 파라미터
|
|
103
|
-
* @example
|
|
104
|
-
* getOpenWeatherMapLang("ko")
|
|
105
|
-
*/
|
|
106
|
-
export const getOpenWeatherMapLang = (locale?: string): string => {
|
|
107
|
-
const localeKey = getWeatherLocaleKey(locale);
|
|
108
|
-
|
|
109
|
-
return OPEN_WEATHER_MAP_LANG_BY_LOCALE[localeKey] ?? localeKey;
|
|
110
|
-
};
|
|
@@ -1,18 +1,13 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
GeoCoordinate,
|
|
3
|
-
KMA_GridCoordinate,
|
|
4
|
-
KMA_Req_BaseGridCoordinate,
|
|
5
|
-
WeatherCoordinate,
|
|
6
|
-
} from "../types";
|
|
1
|
+
import type { GeoCoordinate } from "../types";
|
|
7
2
|
|
|
8
3
|
/**
|
|
9
|
-
* 날씨 도구; 접속위치
|
|
4
|
+
* 날씨 도구; 접속위치 추출.
|
|
10
5
|
* @util
|
|
11
|
-
* @
|
|
6
|
+
* @desc 브라우저 geolocation API에서 현재 위치를 읽고, 사용할 수 없으면 null 좌표를 반환한다.
|
|
7
|
+
* @return {Promise<GeoCoordinate>} 브라우저 geolocation에서 읽은 위경도
|
|
12
8
|
*/
|
|
13
9
|
export const userLocation = async (): Promise<GeoCoordinate> => {
|
|
14
10
|
if (typeof window === "undefined" || !window.navigator.geolocation) {
|
|
15
|
-
// console.log("[userLocation] window 없음");
|
|
16
11
|
return { latitude: null, longitude: null };
|
|
17
12
|
}
|
|
18
13
|
|
|
@@ -22,143 +17,13 @@ export const userLocation = async (): Promise<GeoCoordinate> => {
|
|
|
22
17
|
window.navigator.geolocation.getCurrentPosition(resolve, reject);
|
|
23
18
|
},
|
|
24
19
|
);
|
|
25
|
-
|
|
26
|
-
|
|
20
|
+
|
|
21
|
+
return {
|
|
27
22
|
latitude: position.coords.latitude,
|
|
28
23
|
longitude: position.coords.longitude,
|
|
29
24
|
};
|
|
30
|
-
return res;
|
|
31
25
|
} catch (error) {
|
|
32
26
|
console.error("[userLocation] 위치 정보 에러", error);
|
|
33
27
|
return { latitude: null, longitude: null };
|
|
34
28
|
}
|
|
35
29
|
};
|
|
36
|
-
|
|
37
|
-
/**
|
|
38
|
-
* 날씨 도구; 위경도 -> 격자 좌표 변환
|
|
39
|
-
* @util
|
|
40
|
-
* @param {GeoCoordinate} coordinate - 위경도 좌표
|
|
41
|
-
* @param {number} coordinate.latitude - 위도
|
|
42
|
-
* @param {number} coordinate.longitude - 경도
|
|
43
|
-
* @return {KMA_GridCoordinate} 격자 좌표
|
|
44
|
-
* @desc
|
|
45
|
-
* - 위경도 좌표를 기상청 격자 좌표로 변환합니다.
|
|
46
|
-
* - 출처: 기상청
|
|
47
|
-
* @see https://apihub.kma.go.kr/
|
|
48
|
-
* @see https://apihub.kma.go.kr/getAttachFile.do?fileName=%EB%8B%A8%EA%B8%B0%EC%98%88%EB%B3%B4%20%EC%A1%B0%ED%9A%8C%EC%84%9C%EB%B9%84%EC%8A%A4_API%ED%99%9C%EC%9A%A9%EA%B0%80%EC%9D%B4%EB%93%9C_241128.docx
|
|
49
|
-
*/
|
|
50
|
-
export function convertCoordinateToGrid({
|
|
51
|
-
latitude,
|
|
52
|
-
longitude,
|
|
53
|
-
}: GeoCoordinate): KMA_GridCoordinate {
|
|
54
|
-
const res: KMA_GridCoordinate = { x: 0, y: 0 };
|
|
55
|
-
|
|
56
|
-
if (latitude === null || longitude === null) return res;
|
|
57
|
-
|
|
58
|
-
const RE = 6371.00877; // Earth radius (km)
|
|
59
|
-
const GRID = 5.0; // Grid spacing (km)
|
|
60
|
-
const SLAT1 = 30.0; // Projection latitude 1 (degree)
|
|
61
|
-
const SLAT2 = 60.0; // Projection latitude 2 (degree)
|
|
62
|
-
const ORIGIN_LONGITUDE = 126.0; // Origin longitude (degree)
|
|
63
|
-
const ORIGIN_LATITUDE = 38.0; // Origin latitude (degree)
|
|
64
|
-
const XO = 43; // Origin X coordinate (GRID)
|
|
65
|
-
const YO = 136; // Origin Y coordinate (GRID)
|
|
66
|
-
|
|
67
|
-
const RADIAN = Math.PI / 180.0;
|
|
68
|
-
const re = RE / GRID;
|
|
69
|
-
const slat1 = SLAT1 * RADIAN;
|
|
70
|
-
const slat2 = SLAT2 * RADIAN;
|
|
71
|
-
const origin_longitude = ORIGIN_LONGITUDE * RADIAN;
|
|
72
|
-
const origin_latitude = ORIGIN_LATITUDE * RADIAN;
|
|
73
|
-
|
|
74
|
-
const sn =
|
|
75
|
-
Math.log(Math.cos(slat1) / Math.cos(slat2)) /
|
|
76
|
-
Math.log(
|
|
77
|
-
Math.tan(Math.PI * 0.25 + slat2 * 0.5) /
|
|
78
|
-
Math.tan(Math.PI * 0.25 + slat1 * 0.5),
|
|
79
|
-
);
|
|
80
|
-
|
|
81
|
-
const sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
|
|
82
|
-
const sfPow = (Math.pow(sf, sn) * Math.cos(slat1)) / sn;
|
|
83
|
-
|
|
84
|
-
const ro =
|
|
85
|
-
(re * sfPow) /
|
|
86
|
-
Math.pow(Math.tan(Math.PI * 0.25 + origin_latitude * 0.5), sn);
|
|
87
|
-
|
|
88
|
-
const ra =
|
|
89
|
-
(re * sfPow) /
|
|
90
|
-
Math.pow(Math.tan(Math.PI * 0.25 + latitude * RADIAN * 0.5), sn);
|
|
91
|
-
let theta = longitude * RADIAN - origin_longitude;
|
|
92
|
-
if (theta > Math.PI) theta -= 2.0 * Math.PI;
|
|
93
|
-
if (theta < -Math.PI) theta += 2.0 * Math.PI;
|
|
94
|
-
theta *= sn;
|
|
95
|
-
|
|
96
|
-
res.x = Math.floor(ra * Math.sin(theta) + XO + 0.5);
|
|
97
|
-
res.y = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);
|
|
98
|
-
|
|
99
|
-
// console.log("[WEATHER] 위/경도 -> 기상청 격자값", res);
|
|
100
|
-
|
|
101
|
-
return res;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* 날씨 도구; 위도/경도 -> 기상청 격자 좌표 변환
|
|
106
|
-
* @util
|
|
107
|
-
* @param {WeatherCoordinate} [coordinate] - 사용자 위치 이외의 특정 위도/경도 좌표
|
|
108
|
-
* @param {number} coordinate.lat - 위도
|
|
109
|
-
* @param {number} coordinate.lng - 경도
|
|
110
|
-
* @return {KMA_Req_BaseGridCoordinate} 기상청 격자 좌표
|
|
111
|
-
*/
|
|
112
|
-
export async function getWeatherGridLocation(
|
|
113
|
-
coordinate?: WeatherCoordinate,
|
|
114
|
-
): Promise<KMA_Req_BaseGridCoordinate> {
|
|
115
|
-
const res: KMA_Req_BaseGridCoordinate = { nx: 0, ny: 0 };
|
|
116
|
-
|
|
117
|
-
if (typeof window === "undefined") return res;
|
|
118
|
-
|
|
119
|
-
const geo: GeoCoordinate = {
|
|
120
|
-
latitude: coordinate?.lat ?? null,
|
|
121
|
-
longitude: coordinate?.lng ?? null,
|
|
122
|
-
};
|
|
123
|
-
const hasInjectedAddress =
|
|
124
|
-
typeof coordinate?.address === "string" && coordinate.address.trim() !== "";
|
|
125
|
-
|
|
126
|
-
// console.log("[getWeatherLocation] 특정 좌표지정 확인", coordinate);
|
|
127
|
-
|
|
128
|
-
// 변경 설명: 서비스가 address만 명시적으로 주입한 경우에는 geolocation fallback을 재시도하지 않는다.
|
|
129
|
-
if (
|
|
130
|
-
typeof window !== "undefined" &&
|
|
131
|
-
!hasInjectedAddress &&
|
|
132
|
-
(typeof coordinate === "undefined" ||
|
|
133
|
-
geo.latitude === null ||
|
|
134
|
-
geo.longitude === null)
|
|
135
|
-
) {
|
|
136
|
-
const { latitude, longitude } = await userLocation();
|
|
137
|
-
|
|
138
|
-
if (latitude === null || longitude === null) {
|
|
139
|
-
// console.log("[getWeatherLocation] window.navigator 실패", geo);
|
|
140
|
-
return res;
|
|
141
|
-
}
|
|
142
|
-
geo.latitude = latitude;
|
|
143
|
-
geo.longitude = longitude;
|
|
144
|
-
// console.log("[getWeatherLocation] 사용자 위치", geo);
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
// 위경도 좌표를 기상청 격자좌표로 변환
|
|
148
|
-
const grid = convertCoordinateToGrid(geo);
|
|
149
|
-
|
|
150
|
-
if (grid.x === 0 || grid.y === 0) {
|
|
151
|
-
// console.error("[getWeatherLocation] 위치 정보를 가져오는데 실패했습니다.", {
|
|
152
|
-
// latitude: geo.latitude,
|
|
153
|
-
// longitude: geo.longitude,
|
|
154
|
-
// });
|
|
155
|
-
return res;
|
|
156
|
-
}
|
|
157
|
-
// console.log("[getWeatherLocation] 기상청 격자좌표", grid);
|
|
158
|
-
|
|
159
|
-
res.nx = grid.x;
|
|
160
|
-
res.ny = grid.y;
|
|
161
|
-
|
|
162
|
-
// console.log("[getWeatherLocation] result", res);
|
|
163
|
-
return res;
|
|
164
|
-
}
|