우선 포인트자료인데 일부 소스를 공개해야 하는데 문제가 되면 추후 조치를 하겠습니다.
//날씨연동시 기상청 날씨정보 파싱 및 캐시저장
if($addon_info->weather_kma == 'yes'){
//캐싱설정
$cache_path = './files/cache/snow_falling_addon/';
FileHandler::makeDir($cache_path);
$cache_name = 'snow_falling_addon';
$cache_time = 60*60; //캐시할 시간 (60분)
$cache_file = sprintf('%s%s.cache', $cache_path, $cache_name);
//캐시파일 있으면
if(file_exists($cache_file)){
//캐싱시간확인
$filemtime = filemtime($cache_file)+$cache_time;
$servertime = $_SERVER['REQUEST_TIME'];
//캐싱시간인경우 캐시파일로드
if($filemtime > $servertime){
$cache_body = FileHandler::readFile($cache_file);
}else{
//캐싱시간 지난경우 캐시파일삭제
FileHandler::removeFile($cache_file);
}
}
//캐시파일 없으면 데이터 생성 및 캐시파일로 저장
if(!file_exists($cache_file)){
//날씨정보가공
ini_set("allow_url_fopen","1"); //서버 fopen 허용
$kma_url = "http://www.kma.go.kr/wid/queryDFS.jsp?gridx=67&gridy=108"; //어디기준 날씨정보인지 확실하지않음 ㅡㅡ;
$xml = simplexml_load_file($kma_url);
//날짜데이터 시간
$weather = sprintf('%d',$xml->header->tm);
//가장 최근의 정보를 기준으로 정보저장
if(count($xml->body->data) > 1){
$weather .= sprintf(',%s',$xml->body->data[0]->wfKor); //결과) 시간,날씨상태(맑음,구름조금,구름많음,흐림,비,눈/비,눈)
}
//가공된 정보 캐시정보에 넣음
$cache_content = $weather;
//캐시생성
FileHandler::writeFile($cache_file, $cache_content);
//캐시파일로드
$cache_body = FileHandler::readFile($cache_file);
}
현재 특정 지역을 특정하여 기상정보를 확인 후 해당 기상정보로 눈효과 여부를 결정하고 있습니다.
이를.... 접속하는 유저의 지역으로 해서 기상정보를 가져와 개개인마다 다르게 해 보려고합니다.
캐시를 사용하지 않게 하고 쿠키를 사용하여 30분 정도마다 확인하게 하는게 어떨까 하는 생각을 했습니다.
http://smart-ip.net/geoip-api
여기서 위도와 경도를 구할 수 있습니다.
기상청에서는 x,y 좌표값을 사용하는데 위도,경도를 이 값으로 변환해주는 소스가 기상청에 있다고 하네요.
http://www.kma.go.kr/weather/forecast/digital_forecast.jsp
<html>
<head>
<meta charset="UTF-8">
<title>Document</title>
<style>
textarea {width:350px; height:300px; float:left}
.btnGroup {
float:left ;
padding: 25px;
}
</style>
<script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
<script>
// 위경도 -> GridXY
function fnLatLon2XY() {
var strLatLon = $.trim($("#taLatLon").val());
if(!strLatLon) { alert("위경도 데이터를 입력하여 주십시오."); return;}
var lines = strLatLon.split(String.fromCharCode(10)); //줄단위로 분할
var strXY = "";
for(var i = 0, len = lines.length; i < len; i++) {
if(lines[i] == "") continue; //빈줄은 무시하고 통과
var latlon = lines[i].split(",");
var lat = latlon[0], lon = latlon[1];
if(!lat||!lon||isNaN(lat)||isNaN(lon)) {
alert("숫자 값이 아니거나 데이터 형식이 맞지 않습니다.");
return;
}
var xy = dfs_xy_conv("toXY", lat, lon);
strXY += xy.x + ", " + xy.y + String.fromCharCode(10);
}
$('#taXY').val(strXY);
}
// 위경도 <- GridXY
function fnXY2LatLon() {
var strXY = $.trim($("#taXY").val());
if (! strXY) { alert ("Grid XY 데이터를 입력하여 주십시오."); return; }
var lines = strXY.split(String.fromCharCode(10));
var strLatLon = "";
for(var i = 0, len = lines.length; i < len; i++) {
if (lines[i] == '') continue;
var xy = lines[i].split(",");
var x = xy[0], y = xy[1];
if (!x || !y || isNaN(x) || isNaN(y)) {
alert("숫자 값이 아니거나 데이터 형식이 맞지 않습니다.");
return;
}
var ll = dfs_xy_conv("toLL", x, y);
strLatLon += ll.lat + ", " + ll.lng + String.fromCharCode(10);
}
$("#taLatLon").val(strLatLon);
}
//----------------------------------------------------------
// 기상청 홈페이지에서 발췌한 변환 함수
//
// LCC DFS 좌표변환을 위한 기초 자료
//
var RE = 6371.00877; // 지구 반경(km)
var GRID = 5.0; // 격자 간격(km)
var SLAT1 = 30.0; // 투영 위도1(degree)
var SLAT2 = 60.0; // 투영 위도2(degree)
var OLON = 126.0; // 기준점 경도(degree)
var OLAT = 38.0; // 기준점 위도(degree)
var XO = 43; // 기준점 X좌표(GRID)
var YO = 136; // 기1준점 Y좌표(GRID)
// LCC DFS 좌표변환 ( code :
// "toXY"(위경도->좌표, v1:위도, v2:경도),
// "toLL"(좌표->위경도,v1:x, v2:y) )
//
function dfs_xy_conv(code, v1, v2) {
var DEGRAD = Math.PI / 180.0;
var RADDEG = 180.0 / Math.PI;
var re = RE / GRID;
var slat1 = SLAT1 * DEGRAD;
var slat2 = SLAT2 * DEGRAD;
var olon = OLON * DEGRAD;
var olat = OLAT * DEGRAD;
var sn = Math.tan(Math.PI * 0.25 + slat2 * 0.5) / Math.tan(Math.PI * 0.25 + slat1 * 0.5);
sn = Math.log(Math.cos(slat1) / Math.cos(slat2)) / Math.log(sn);
var sf = Math.tan(Math.PI * 0.25 + slat1 * 0.5);
sf = Math.pow(sf, sn) * Math.cos(slat1) / sn;
var ro = Math.tan(Math.PI * 0.25 + olat * 0.5);
ro = re * sf / Math.pow(ro, sn);
var rs = {};
if (code == "toXY") {
rs['lat'] = v1;
rs['lng'] = v2;
var ra = Math.tan(Math.PI * 0.25 + (v1) * DEGRAD * 0.5);
ra = re * sf / Math.pow(ra, sn);
var theta = v2 * DEGRAD - olon;
if (theta > Math.PI) theta -= 2.0 * Math.PI;
if (theta < -Math.PI) theta += 2.0 * Math.PI;
theta *= sn;
rs['x'] = Math.floor(ra * Math.sin(theta) + XO + 0.5);
rs['y'] = Math.floor(ro - ra * Math.cos(theta) + YO + 0.5);
}
else {
rs['x'] = v1;
rs['y'] = v2;
var xn = v1 - XO;
var yn = ro - v2 + YO;
ra = Math.sqrt(xn * xn + yn * yn);
if (sn < 0.0) - ra;
var alat = Math.pow((re * sf / ra), (1.0 / sn));
alat = 2.0 * Math.atan(alat) - Math.PI * 0.5;
if (Math.abs(xn) <= 0.0) {
theta = 0.0;
}
else {
if (Math.abs(yn) <= 0.0) {
theta = Math.PI * 0.5;
if (xn < 0.0) - theta;
}
else theta = Math.atan2(xn, yn);
}
var alon = theta / sn + olon;
rs['lat'] = alat * RADDEG;
rs['lng'] = alon * RADDEG;
}
return rs;
}
</script>
</head>
<body>
<textarea id="taLatLon" >37.579871128849334, 126.98935225645432
35.101148844565955, 129.02478725562108
33.500946412305076, 126.54663058817043</textarea>
<div class="btnGroup">
<button onclick="fnLatLon2XY()">위경도 -> GridXY</button><br/><br/>
<button onclick="fnXY2LatLon()">위경도 <- GridXY</button>
</div>
<textarea id="taXY"></textarea>
</body>
</html>
https://javaking75.blog.me/220089575454
개발자분들은 쉽게 브라우저의 현위지 좌표를 가지고 가변적인 동네날씨 정보 주소를 가져오게 하실 수 있을 것 같아 한번 정보를 모아 질문을 드려봅니다.
눈송이 애드온 : https://xetown.com/rxe_point/96271
댓글 9
https://xetown.com/rxe_file/104275
요기서 지역을 알아내야 할거에요 근데 갠적으로 비추에요~
http://ip-api.com/
https://xetown.com/qna/833917