255 lines
8.5 KiB
PHP
255 lines
8.5 KiB
PHP
<?php
|
|
/**
|
|
* @file vworld.php
|
|
* @date 2018-01-11
|
|
* @author Go Namhyeon <abuse@catswords.net>
|
|
* @brief Geo Helper based on vWorld (vworld.kr, molit.go.kr)
|
|
*/
|
|
|
|
if(!is_fn("vworld_utf8_replace")) {
|
|
function vworld_utf8_replace($data) {
|
|
$regex = <<<'END'
|
|
/
|
|
(
|
|
(?: [\x00-\x7F] # single-byte sequences 0xxxxxxx
|
|
| [\xC0-\xDF][\x80-\xBF] # double-byte sequences 110xxxxx 10xxxxxx
|
|
| [\xE0-\xEF][\x80-\xBF]{2} # triple-byte sequences 1110xxxx 10xxxxxx * 2
|
|
| [\xF0-\xF7][\x80-\xBF]{3} # quadruple-byte sequence 11110xxx 10xxxxxx * 3
|
|
){1,100} # ...one or more times
|
|
)
|
|
| . # anything else
|
|
/x
|
|
END;
|
|
if (is_array($data)) {
|
|
foreach ($data as $k=>$v) {
|
|
$data[$k] = vworld_utf8_replace($v);
|
|
}
|
|
}
|
|
else if (is_string($data)) {
|
|
$data = preg_replace($regex, '$1', $data);
|
|
}
|
|
return $data;
|
|
}
|
|
}
|
|
|
|
if(!is_fn("vworld_geocode_keyword")) {
|
|
function vworld_geocode_keyword($keyword, $category="Poi", $multiple=false) {
|
|
global $config;
|
|
|
|
$geopoint = array(
|
|
"address" => "",
|
|
"latitude" => "", // y-pos
|
|
"longitude" => "" // x-pos
|
|
);
|
|
|
|
$req_urls = array(
|
|
"http://map.vworld.kr/search.do" // 키워드로 요청
|
|
);
|
|
|
|
// Poi 는 장소 검색. Jibun은 지번주소 검색. Juso는 도로명주소 검색
|
|
$poss_cates = array("Poi", "Jibun", "Juso");
|
|
if(!in_array($category, $poss_cates)) {
|
|
$category = "Poi";
|
|
}
|
|
$callback = "";
|
|
$q = $keyword;
|
|
$pageUnit = 1;
|
|
$output = "json";
|
|
$pageIndex = 1;
|
|
$apiKey = $config['vworld_api_key'];
|
|
|
|
// 전송 내용 명시
|
|
$req_data = array(
|
|
"callback" => $callback,
|
|
"q" => $q,
|
|
"category" => $category,
|
|
"pageUnit" => $pageUnit,
|
|
"output" => $output,
|
|
"pageIndex" => $pageIndex,
|
|
"apiKey" => $apiKey
|
|
);
|
|
$req_data_query = http_build_query($req_data);
|
|
$req_props = "";
|
|
$req_cnt = 0;
|
|
$succ_flag = false; // 성공했는지 여부
|
|
foreach($req_urls as $base_url) {
|
|
$req_props = "";
|
|
$req_real_url = $base_url . '?' . $req_data_query;
|
|
|
|
// request addr2coord
|
|
$ch = curl_init();
|
|
curl_setopt($ch,CURLOPT_URL, $req_real_url);
|
|
curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
|
|
// curl_setopt($ch,CURLOPT_HEADER, false);
|
|
if($req_output = curl_exec($ch)) {
|
|
if(!empty(trim($req_output))) {
|
|
$req_props = json_decode($req_output);
|
|
// 좌표만을 추출
|
|
$geo_list = array();
|
|
foreach($req_props->LIST as $req_row) {
|
|
$req_row = get_object_vars($req_row);
|
|
$geo_list[] = $req_row;
|
|
}
|
|
|
|
// 단일인지 복수인지
|
|
if(count($geo_list) > 0) {
|
|
if($multiple == false) {
|
|
$req_props = $geo_list[0];
|
|
} else {
|
|
$req_props = $geo_list;
|
|
}
|
|
|
|
$succ_flag = true;
|
|
} else {
|
|
$succ_flag = false;
|
|
}
|
|
}
|
|
}
|
|
curl_close($ch);
|
|
|
|
// 요청 횟수를 기록
|
|
$req_cnt++;
|
|
|
|
// 성공했을 시 다음 주소로 넘어가지 않음
|
|
if($succ_flag == true) {
|
|
$xpos = $req_props['xpos'];
|
|
$ypos = $req_props['ypos'];
|
|
// store lat and lon
|
|
if($ypos > 0 && $xpos > 0) {
|
|
$geopoint['address'] = $req_props['juso'];
|
|
$geopoint['latitude'] = $ypos;
|
|
$geopoint['longitude'] = $xpos;
|
|
}
|
|
break;
|
|
} elseif($req_cnt = count($req_urls)) {
|
|
$req_props = array();
|
|
} else {
|
|
$req_props = array();
|
|
}
|
|
}
|
|
return $geopoint;
|
|
}
|
|
}
|
|
|
|
// get geocode from vworld
|
|
if(!is_fn("vworld_geocode_addr2coord")) {
|
|
function vworld_geocode_addr2coord($addr) {
|
|
global $config;
|
|
|
|
$geopoint = array(
|
|
"address" => "",
|
|
"latitude" => "", // y-pos
|
|
"longitude" => "" // x-pos
|
|
);
|
|
// base url
|
|
$req_urls = array(
|
|
"http://apis.vworld.kr/jibun2coord.do", // 구주소 요청
|
|
"http://apis.vworld.kr/new2coord.do" // 신주소 요청
|
|
);
|
|
|
|
// 기본 설정
|
|
$apiKey = $config['vworld_api_key'];
|
|
$domain = $config['vworld_api_domain'];
|
|
$output = "json";
|
|
$epsg = "EPSG:4326"; // default is EPSG:4326
|
|
$callback = "";
|
|
|
|
// 전송 내용 명시
|
|
$req_data = array(
|
|
"q" => $addr,
|
|
"apiKey" => $apiKey,
|
|
"domain" => $domain,
|
|
"output" => $output,
|
|
"epsg" => $epsg,
|
|
"callback" => $callback
|
|
);
|
|
$req_data_query = http_build_query($req_data);
|
|
|
|
$req_props = "";
|
|
$req_cnt = 0;
|
|
$succ_flag = false; // 성공했는지 여부
|
|
foreach($req_urls as $base_url) {
|
|
$req_props = "";
|
|
$req_real_url = $base_url . '?' . $req_data_query;
|
|
|
|
// request addr2coord
|
|
$ch = curl_init();
|
|
curl_setopt($ch, CURLOPT_URL, $req_real_url);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
// curl_setopt($ch,CURLOPT_HEADER, false);
|
|
if($req_output = curl_exec($ch)) {
|
|
if(!empty(trim($req_output))) {
|
|
$req_props = json_decode($req_output);
|
|
if(count($req_props) > 0) {
|
|
$req_props = get_object_vars($req_props);
|
|
$req_props = vworld_utf8_replace($req_props);
|
|
$succ_flag = true;
|
|
}
|
|
}
|
|
}
|
|
curl_close($ch);
|
|
|
|
// 요청 횟수를 기록
|
|
$req_cnt++;
|
|
// 성공했을 시 다음 주소로 넘어가지 않음
|
|
if($succ_flag == true) {
|
|
$xpos = 0;
|
|
$ypos = 0;
|
|
switch($epsg) {
|
|
case "EPSG:900913":
|
|
$xpos = $req_props['EPSG_900913_X'] ;
|
|
$ypos = $req_props['EPSG_900913_Y'];
|
|
if($xpos > 0 && $ypos> 0) {
|
|
$geopoint['address'] = $req_props['JUSO'];
|
|
$geopoint['latitude'] = $ypos;
|
|
$geopoint['longitude'] = $xpos;
|
|
}
|
|
break;
|
|
case "EPSG:4326": // default is EPSG:4326
|
|
default:
|
|
$xpos = $req_props['EPSG_4326_X'];
|
|
$ypos = $req_props['EPSG_4326_Y'];
|
|
if($xpos > 0 && $ypos> 0) {
|
|
$geopoint['address'] = $req_props['JUSO'];
|
|
$geopoint['latitude'] = $ypos;
|
|
$geopoint['longitude'] = $xpos;
|
|
}
|
|
break;
|
|
}
|
|
|
|
break;
|
|
} elseif($req_cnt = count($req_urls)) {
|
|
$req_props = "";
|
|
} else {
|
|
$req_props = "";
|
|
}
|
|
}
|
|
return $geopoint;
|
|
}
|
|
}
|
|
|
|
if(!is_fn("vworld_adaptive_addr2coord")) {
|
|
function vworld_adaptive_addr2coord($addr) {
|
|
$geopoint = array(
|
|
"address" => "",
|
|
"latitude" => "", // y-pos
|
|
"longitude" => "" // x-pos
|
|
);
|
|
|
|
if(!empty($addr)) {
|
|
$georesult = vworld_geocode_keyword($addr);
|
|
if(empty($georesult["address"])) {
|
|
$georesult = vworld_geocode_addr2coord($addr);
|
|
}
|
|
|
|
if(empty($georesult["address"])) {
|
|
$addr_blocks = explode(' ', $addr);
|
|
$newaddr = implode(' ', array_slice($addr_blocks, 0, -1));
|
|
$georesult = vworld_adaptive_addr2coord($newaddr);
|
|
}
|
|
}
|
|
|
|
return $georesult;
|
|
}
|
|
}
|