PHPで経緯度から沖縄標準メッシュー番号に変換する関数
案件で住所からメッシュー番号の変換が必要になって、いろいろ調べた結果をここでメモしておきます。
- メッシュー番号はなに?
- まず、住所から経緯度に変換する
Google Maps APIを利用します。
Google Maps APIで住所から経緯度の変換はジオコーディングを使います。
ジオコーディングは実はjsからだけではなく、HTTP リクエスト経由からの利用も可能となっています。Google様!最高!
利用方法はここのページに情報が載ってます。
自分は一番シンプルのCSV形式で利用します。このように
/** * 住所の文字列から経緯度を取得 * * @param <type> $address * @return <type> 変換が成功した場合 35.8569991,139.6488487 のような経緯度結果文字列を返す */ function address2latlng($address=null) { if(!$address) return null; $address = urlencode($address); $rs = file_get_contents("http://maps.google.com/maps/geo?q=$address&output=csv&sensor=false&key=".あなたのきー; if($rs) { list($status,,$lat,$lng) = explode(",", $rs); if($status == 200) { return "$lat,$lng"; }else { return null; } }else { return null; } }
- そして、経緯度から沖縄標準メッシュー番号に変換する
このサイトのJSファイルを参考にPHP用の変換スクリプトを作りました。
沖縄標準メッシュ番号 表示サービスVer1.3
/** * $lat 経度 * $lng 緯度 * * 経度緯度から沖縄標準メッシュコードに変換する * 標準メッシュコード例: 29 45 B-3 f-7 * 参考: * http://www.okikosai.or.jp/kenkyusho/any_data/mc/mc.html */ function mc_get($lat,$lng) { /* 緯度経度を基に標準メッシュ番号を算出 */ /* Level1用配列 */ $M1 = array(); $M1[0] = Array("33","00","00","00","00","00"); $M1[1] = Array("31","32","00","00","00","00"); $M1[2] = Array("29","30","00","00","00","00"); $M1[3] = Array("26","27","28","00","00","00"); $M1[4] = Array("22","23","24","25","00","00"); $M1[5] = Array("18","19","20","21","00","00"); $M1[6] = Array("00","14","15","16","17","00"); $M1[7] = Array("00","9","10","11","12","13"); $M1[8] = Array("00","4","5","6","7","8"); $M1[9] = Array("00","00","00","00","2","3"); $M1[10] = Array("00","00","00","00","98","99"); /* Level2用配列 */ $M2 = Array(); $M2[0] = Array("91","92","93","94","95","96","97","98","99","100"); $M2[1] = Array("81","82","83","84","85","86","87","88","89","90"); $M2[2] = Array("71","72","73","74","75","76","77","78","79","80"); $M2[3] = Array("61","62","63","64","65","66","67","68","69","70"); $M2[4] = Array("51","52","53","54","55","56","57","58","59","60"); $M2[5] = Array("41","42","43","44","45","46","47","48","49","50"); $M2[6] = Array("31","32","33","34","35","36","37","38","39","40"); $M2[7] = Array("21","22","23","24","25","26","27","28","29","30"); $M2[8] = Array("11","12","13","14","15","16","17","18","19","20"); $M2[9] = Array("1","2","3","4","5","6","7","8","9","10"); /* Level3用配列 */ $M3 = Array(); $M3[0] = Array("A-5","B-5","C-5","D-5","E-5"); $M3[1] = Array("A-4","B-4","C-4","D-4","E-4"); $M3[2] = Array("A-3","B-3","C-3","D-3","E-3"); $M3[3] = Array("A-2","B-2","C-2","D-2","E-2"); $M3[4] = Array("A-1","B-1","C-1","D-1","E-1"); /* Level4用配列 */ $M4 = Array(); $M4[0] = Array("a-10","b-10","c-10","d-10","e-10","f-10","g-10","h-10","i-10","j-10"); $M4[1] = Array("a-9","b-9","c-9","d-9","e-9","f-9","g-9","h-9","i-9","j-9"); $M4[2] = Array("a-8","b-8","c-8","d-8","e-8","f-8","g-8","h-8","i-8","j-8"); $M4[3] = Array("a-7","b-7","c-7","d-7","e-7","f-7","g-7","h-7","i-7","j-7"); $M4[4] = Array("a-6","b-6","c-6","d-6","e-6","f-6","g-6","h-6","i-6","j-6"); $M4[5] = Array("a-5","b-5","c-5","d-5","e-5","f-5","g-5","h-5","i-5","j-5"); $M4[6] = Array("a-4","b-4","c-4","d-4","e-4","f-4","g-4","h-4","i-4","j-4"); $M4[7] = Array("a-3","b-3","c-3","d-3","e-3","f-3","g-3","h-3","i-3","j-3"); $M4[8] = Array("a-2","b-2","c-2","d-2","e-2","f-2","g-2","h-2","i-2","j-2"); $M4[9] = Array("a-1","b-1","c-1","d-1","e-1","f-1","g-1","h-1","i-1","j-1"); /* 算出結果格納用配列 */ $MC = Array(); /* 沖縄標準メッシュ基準点 */ $lat_sp = 93600; $lng_sp = 459450; /* 座標値を秒単位へ変換 */ $lat_ss = $lat * 3600; $lng_ss = $lng * 3600; /* Level1算出 */ $lat_diff = ($lat_ss - $lat_sp); $lng_diff = ($lng_ss - $lng_sp); $lat_no = ceil($lat_diff / 300) - 1; $lng_no = ceil($lng_diff / 450) - 1; $MC[0] = $M1[$lat_no][$lng_no]; /* Level1_No = 1 の場合の補正 $lngを半分左にシフト*/ if (($MC[0] == "98") || ($MC[0] == "99")){ if (($lng < 128.1875) || ($lng > 128.3125 )){ $MC[0] = 0; }else{ $lng_diff = $lng_diff - 225; $MC[0] = "1"; } } /* 沖縄標準メッシュエリア外判定 */ if (($MC[0] === 0) || !($MC[0])){ return ""; } /* Level2算出 */ $lat_diff2 = $lat_diff - floor($lat_diff / 300) * 300; $lng_diff2 = $lng_diff - floor($lng_diff / 450) * 450; $lat_no = ceil($lat_diff2 / 30) - 1; $lng_no = ceil($lng_diff2 / 45) - 1; $MC[1] = $M2[$lat_no][$lng_no]; /* Level3算出 */ $lat_diff3 = $lat_diff2 - floor($lat_diff2 / 30) * 30; $lng_diff3 = $lng_diff2 - floor($lng_diff2 / 45) * 45; $lat_no = ceil($lat_diff3 / 6) - 1; $lng_no = ceil($lng_diff3 / 9) - 1; $MC[2] = $M3[$lat_no][$lng_no]; /* Level4算出 */ $lat_diff4 = $lat_diff3 - floor($lat_diff3 / 6) * 6; $lng_diff4 = $lng_diff3 - floor($lng_diff3 / 9) * 9; $lat_no = ceil($lat_diff4 / 0.6) - 1; $lng_no = ceil($lng_diff4 / 0.9) - 1; $MC[3] = $M4[$lat_no][$lng_no]; return implode(" ", $MC); }
- 最後
ここまできたら、もう言うまでもないですね^^