날씨 진행 중 세이브

This commit is contained in:
leeheejin
2025-10-23 12:31:14 +09:00
parent 8ab36f32a0
commit 8ec54b4e7d
8 changed files with 461 additions and 8 deletions

View File

@@ -968,9 +968,14 @@ function parseKMADataWeatherData(data: any, gridCoord: { name: string; nx: numbe
clouds = 30;
}
// 격자좌표 → 위도경도 변환
const { lat, lng } = gridToLatLng(gridCoord.nx, gridCoord.ny);
return {
city: gridCoord.name,
country: 'KR',
lat,
lng,
temperature: Math.round(temperature),
feelsLike: Math.round(temperature - 2),
humidity: Math.round(humidity),
@@ -1110,6 +1115,65 @@ function getGridCoordinates(city: string): { name: string; nx: number; ny: numbe
return grids[city] || null;
}
/**
* 격자좌표(nx, ny)를 위도경도로 변환
* 기상청 격자 → 위경도 변환 공식 사용
*/
function gridToLatLng(nx: number, ny: number): { lat: number; lng: number } {
const RE = 6371.00877; // 지구 반경(km)
const GRID = 5.0; // 격자 간격(km)
const SLAT1 = 30.0; // 표준위도1(degree)
const SLAT2 = 60.0; // 표준위도2(degree)
const OLON = 126.0; // 기준점 경도(degree)
const OLAT = 38.0; // 기준점 위도(degree)
const XO = 43; // 기준점 X좌표
const YO = 136; // 기준점 Y좌표
const DEGRAD = Math.PI / 180.0;
const re = RE / GRID;
const slat1 = SLAT1 * DEGRAD;
const slat2 = SLAT2 * DEGRAD;
const olon = OLON * DEGRAD;
const olat = OLAT * DEGRAD;
const sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
const sn_log = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
const sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
const sf_pow = Math.pow(sf, sn_log);
const sf_result = (Math.cos(slat1) * sf_pow) / sn_log;
const ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
const ro_pow = Math.pow(ro, sn_log);
const ro_result = (re * sf_result) / ro_pow;
const xn = nx - XO;
const yn = ro_result - (ny - YO);
const ra = Math.sqrt(xn * xn + yn * yn);
let alat: number;
if (sn_log > 0) {
alat = 2.0 * Math.atan(Math.pow((re * sf_result) / ra, 1.0 / sn_log)) - Math.PI * 0.5;
} else {
alat = -2.0 * Math.atan(Math.pow((re * sf_result) / ra, 1.0 / sn_log)) + Math.PI * 0.5;
}
let theta: number;
if (Math.abs(xn) <= 0.0) {
theta = 0.0;
} else {
if (Math.abs(yn) <= 0.0) {
theta = 0.0;
} else {
theta = Math.atan2(xn, yn);
}
}
const alon = theta / sn_log + olon;
return {
lat: parseFloat((alat / DEGRAD).toFixed(6)),
lng: parseFloat((alon / DEGRAD).toFixed(6)),
};
}
/**
* 공공데이터포털 초단기실황 응답 파싱
* @param apiResponse - 공공데이터포털 API 응답 데이터
@@ -1171,8 +1235,13 @@ function parseDataPortalWeatherData(apiResponse: any, gridInfo: { name: string;
weatherDescription = '추움';
}
// 격자좌표 → 위도경도 변환
const { lat, lng } = gridToLatLng(gridInfo.nx, gridInfo.ny);
return {
city: gridInfo.name,
lat,
lng,
temperature: Math.round(temperature * 10) / 10,
humidity: Math.round(humidity),
windSpeed: Math.round(windSpeed * 10) / 10,