기상청에서 제공해주는 동네 예보, 중기 예보 등의 날씨 데이터는 공공데이터포털 data.go.kr 에 가면 얻을 수 있다. 투두날씨에서 OpenWeatherMap 을 포기한 이유는 한국에 최적화된 서비스를 고려했을 시 날씨 데이터의 정확도에서 기상청이 구라청이라는 욕을 먹기는 하지만 정확도면에서는 무시할 수 없기 때문. 다만, 실제로 연동해보니 현재 실황, 초단기 예보, 중기 예보 등등 제공해주는 데이터별로 API 가 다르고 보기 좋게 데이터를 표시하려면 각각의 API 에서 보내주는 예보 시간을 맞춰주는 꽤나 섬세한(?) 작업이 필요하다. 그리고 왜인지는 모르겠으나 어제 중기 예보를 오후 6시에는 3일후 예보를 보내주지 않겠다고... 그러면 주간 예보가 하루가 비게 되어서 난감하던 차에 동네예보통지서비스를 찾아보니 여기서 이번 주부터 3일후 예보를 보내주기 시작했다고 한다. 아마 부서간(?) 업무 역할이 좀 변경된 것 같은데 공공데이터를 사용해보면 사용자 입장은 고려하지 않고 공급자 입장에서 편하게 일을 하고 있다는 느낌을 쉽게 받을 수 있다.
기상청 데이터를 댕겨오면서 배운게 하나 있는데 OpenWeatherMap 은 주소의 위경도를 사용해서 날씨 데이터를 보내주지만 기상청 동네예보는 보통 네비게이션에서 쓰는 좌표계를 사용한다. 타원이 지구를 편평하게 펼친 지도처럼 풀어서 거기에 정사각형 격자별로 구획을 나누고 각 구회에 예보 데이터를 뿌려주는 식. 따라서 위경도만으로는 기상청의 동네예보 데이터를 가져올 수 없고 위경도를 기반으로 기상청에서 사용하는 좌표를 구해야 한다.
위경도를 기상청 격자 좌표로 변환해주는 것은 구글링을 하다가 기상청 홈페이지 소스를 사용했다는 어느 블로거의 글을 참고해서 아래와 같이 javascript 로 expo 환경에서 잘 워킹하도록 아주 약간의 수정을 거쳐서 사용했다. 아마 자바스크립트로 관련해서 뭔가를 만들려고 하는 분들에게는 필요할지도...
---
const convertXY = (code, v1, v2) => {
const { PI, tan, log, cos, pow, floor, sin, sqrt, atan, abs, atan2 } = Math
//
// LCC DFS 좌표변환을 위한 기초 자료
//
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좌표(GRID)
const YO = 136 // 기1준점 Y좌표(GRID)
const DEGRAD = PI / 180.0
const RADDEG = 180.0 / PI
const re = RE / GRID
const slat1 = SLAT1 * DEGRAD
const slat2 = SLAT2 * DEGRAD
const olon = OLON * DEGRAD
const olat = OLAT * DEGRAD
let sn = tan(PI * 0.25 + slat2 * 0.5) / tan(PI * 0.25 + slat1 * 0.5)
sn = log(cos(slat1) / cos(slat2)) / log(sn)
let sf = tan(PI * 0.25 + slat1 * 0.5)
sf = pow(sf, sn) * cos(slat1) / sn
let ro = tan(PI * 0.25 + olat * 0.5)
ro = re * sf / pow(ro, sn)
const rs = {}
let ra, theta
if (code === 'toXY') {
rs.lat = v1
rs.lon = v2
ra = tan(PI * 0.25 + (v1) * DEGRAD * 0.5)
ra = re * sf / pow(ra, sn)
theta = v2 * DEGRAD - olon
if (theta > PI) theta -= 2.0 * PI
if (theta < -PI) theta += 2.0 * PI
theta *= sn
rs.x = floor(ra * sin(theta) + XO + 0.5)
rs.y = floor(ro - ra * cos(theta) + YO + 0.5)
} else {
rs.x = v1
rs.y = v2
const xn = v1 - XO
const yn = ro - v2 + YO
ra = sqrt(xn * xn + yn * yn)
if (sn < 0.0) ra = -ra
let alat = pow((re * sf / ra), (1.0 / sn))
alat = 2.0 * atan(alat) - PI * 0.5
if (abs(xn) <= 0.0) {
theta = 0.0
} else {
if (abs(yn) <= 0.0) {
theta = PI * 0.5
if (xn < 0.0) theta = -theta
} else theta = atan2(xn, yn)
}
const alon = theta / sn + olon
rs.lat = alat * RADDEG
rs.lon = alon * RADDEG
}
// console.log(`rs: ${rs.x} ${rs.y}`)
return rs
}
---
play.google.com/store/apps/details?id=com.appswayd.todoWeatherKR
투두 날씨 - Google Play 앱
# 투두 날씨는 간편한 투두 관리와 투두가 있는 장소의 날씨를 함께 확인할 수 있습니다. #
play.google.com
https://apps.apple.com/kr/app/%ED%88%AC%EB%91%90-%EB%82%A0%EC%94%A8/id1553218120
투두 날씨
일정이 있는 지역의 날씨를 확인하기 위해 주소를 찾고 계신가요? 투두 날씨는 단순함을 컨셉으로 일정 관리와 함께 일정에 해당되는 지역의 날씨를 확인할 수 있는 앱입니다. 주소를 모르더
apps.apple.com
'APP' 카테고리의 다른 글
구글 애드몹 - 무효 트래픽 (0) | 2021.05.21 |
---|---|
투두날씨 - 개발 회고 (6) (1) | 2021.05.04 |
투두 날씨 - 개발 회고 (4) (0) | 2021.04.29 |
투두 날씨 - 개발 회고 (3) (0) | 2021.04.26 |
투두날씨 - 개발 회고 (2) (0) | 2021.04.26 |
댓글