逆ジオコーダを試した
以下 3 つの逆ジオコーダを試した時のメモとテストに使ったグリモンソース。
- invGeocoder /
- rgeocode.php / rgeocode.php - 逆ジオコーディングサービス / ReFITS Lab
- 標高 API / http://www.alpslab.jp/api_altitude.html
自分で使うものだけをさっくり試しただけです。作者様方には非常に感謝しております。
逆ジオコーダ
invGeocoder
リクエスト
http://nishioka.sakura.ne.jp/google/ws.php?lon=139.7056&lat=35.6723&format=simple
レスポンス
<?xml version='1.0' encoding='UTF-8' ?> <geometry> <version>0.1</version> <point> <lat>35.673</lat> <lon>139.705568</lon> <address>東京都渋谷区神宮前一丁目24</address> <pref>東京都</pref> <city>渋谷区</city> <town>神宮前一丁目</town> <number>24</number> <distance>77.7210722793</distance> </point> </geometry>
rgeocode.php
せっかく? なので jsonp を使用した。XML なども可能。
リクエスト
http://refits.cgk.affrc.go.jp/tsrv/jp/rgeocode.php?jsonp=caller&v=2&lat=35.6723&lon=139.7056
レスポンス
caller({ 'status' : true, 'result' : { 'prefecture' : { 'pcode' : 13, 'pname' : '東京都' }, 'municipality' : { 'mcode' : 13113, 'mname' : '渋谷区' }, 'local' : { 'section' : '神宮前一丁目', 'homenumber' : 24 } }, 'argument' : { 'latitude' : 35.6723, 'longitude' : 139.7056 }, 'uri' : '%2Ftsrv%2Fjp%2Frgeocode.php%3Fjsonp%3Dcaller%26v%3D2%26lat%3D35.6723%26lon%3D139.7056', 'meta' : [ { 'name' : 'thanks', 'content' : 'このサービスは 国土交通省 提供 国土数値情報(行政区域データ) および 街区レベル位置参照情報 を利用しています' } ] });
標高 API
本来は標高を取得するもの、だと思わる。日本測地系。
リクエスト
http://api.alpslab.jp/v1/level?appid=guest&p=35/40/08.7,139/42/31.7
レスポンス
<?xml version="1.0" encoding="UTF-8"?> <result> <address>東京都渋谷区神宮前1丁目</address> <level>26</level> </result>
テストソース
最近 はてなフォトライフ - 無料・大容量、写真を共有できるウェブアルバム では写真に位置情報が含まれる場合に KML ファイルへのリンクが表示されるようになったのだけど、その横に緯度経度と住所を表示するようにしてみた。が、非常にいまいち…。Overview | Maps Static API | Google Developers とか使って地図を表示させようかとも思ったがやめた。逆ジオコーダを使うことが目的なので。
// ==UserScript== // @name TestReverseGeoCoding // @namespace http://d.hatena.ne.jp/hetappi // @include http://f.hatena.ne.jp/* // ==/UserScript== (function() { // anchor.href: 'http://f.hatena.ne.jp/xxxxxxx/yyyyyyyyyyyyyy?mode=kml' var anchor = document.evaluate( 'id("breadcrumbs")/a[3]', document, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; if (!anchor) return; parseKml(anchor.href, function(point) { var name = 'invGeocoder'; // var name = 'rgeocode.php'; // var name = 'ALPSLABlevel'; var coder = new GeoCoderFactory().createReverseGeoCoder(name); coder.geocode({ lat: point.lat, lon: point.lon }, function(resp) { var txt = document.createTextNode( '(' + 'lat: ' + resp.lat + ', ' + 'lon: ' + resp.lon + ', ' + 'address: ' + resp.address + ')' ); anchor.appendChild(txt); }); }); function parseKml(url, callback) { var opts = { method: 'get', url: url, onerror: function(resp) { callback(null); }, onload: function(resp) { var doc = (new DOMParser).parseFromString(resp.responseText, 'text/xml'); // todo: check <parsererror /> callback({ lon: doc.getElementsByTagName('longitude')[0].textContent, lat: doc.getElementsByTagName('latitude')[0].textContent }); } }; GM_xmlhttpRequest(opts); } })(); function GeoCoderFactory() { return { createGeoCoder: function(name) { return null; }, createReverseGeoCoder: function(name) { if (name == 'invGeocoder') return new InvGeocoder(); else if (name == 'rgeocode.php') return new RgeocodePhp(); else if (name == 'ALPSLABlevel') return new AlpsLabLevel(); return null; } }; } // 標高API // http://www.alpslab.jp/api_altitude.html // thanks ALPSLAB function AlpsLabLevel() { return { geocode: function(point, callback) { if (!callback || !point.lat || !point.lon) return null; var util = new Util; var p = util.wgs84ToTokyo({ lat: Number(point.lat), lon: Number(point.lon) }); var url = 'http://api.alpslab.jp/v1/level?' + 'appid=guest&p=' + util.degreeToDms(Number(p.lat), '/') + ',' + util.degreeToDms(Number(p.lon), '/'); GM_log(url); var opts = { method: 'get', url: url, onerror: function(resp) { callback(null); }, onload: function(resp) { var doc = (new DOMParser).parseFromString(resp.responseText, 'text/xml'); // todo: check <parsererror /> callback({ lat: point.lat, lon: point.lon, address: doc.getElementsByTagName('address')[0].textContent }); } }; GM_xmlhttpRequest(opts); } }; } // rgeocode.php // http://refits.cgk.affrc.go.jp/tsrv/jp/rgeocode.html // thanks ReFITS Lab // // rgeocode.php は、国土交通省の国土情報の閲覧・提供サービスサイトで公開されている // 「国土数値情報(行政区域データ)」および「街区レベル位置参照情報」を使用しています。 // 番地情報は、実態と異なる場合があり、またプライバシーにも関わることがありますので、 // 特に慎重に扱って下さい。 function RgeocodePhp() { return { geocode: function(point, callback) { if (!callback || !point.lat || !point.lon) return null; function caller(resp) { if (!resp.status) { callback(null); return; } var r = resp.result; callback({ lat: resp.argument.latitude, lon: resp.argument.longitude, address: r.prefecture.pname + r.municipality.mname + (r.local ? r.local.section + r.local.homenumber : '') }); } var url = 'http://refits.cgk.affrc.go.jp/tsrv/jp/rgeocode.php?' + 'jsonp=caller&v=2&lat=' + point.lat + '&lon=' + point.lon; GM_log(url); var opts = { method: 'get', url: 'http://refits.cgk.affrc.go.jp/tsrv/jp/rgeocode.php?' + 'jsonp=caller&v=2&lat=' + point.lat + '&lon=' + point.lon, onerror: function(resp) { callback(null); }, onload: function(resp) { eval(resp.responseText); } }; GM_xmlhttpRequest(opts); } }; } // invGeocoder // http://www.knya.net/archives/2005/07/rest.html // thanks nishioka function InvGeocoder() { return { geocode: function(point, callback) { if (!callback || !point.lat || !point.lon) return null; var url = 'http://nishioka.sakura.ne.jp/google/ws.php?' + 'lon=' + point.lon + '&lat=' + point.lat + '&format=simple'; GM_log(url); var opts = { method: 'get', url: url, onerror: function(resp) { callback(null); }, onload: function(resp) { var doc = (new DOMParser).parseFromString(resp.responseText, 'text/xml'); // todo: check <parsererror /> var version = doc.getElementsByTagName('version')[0].textContent; if (version != '0.1') { callback(null); return; } callback({ lat: doc.getElementsByTagName('lat')[0].textContent, lon: doc.getElementsByTagName('lon')[0].textContent, address: doc.getElementsByTagName('address')[0].textContent }); } }; GM_xmlhttpRequest(opts); } }; } function Util() { return { // http://homepage3.nifty.com/Nowral/02_DATUM/02_DATUM.html // thanks Nowral wgs84ToTokyo: function(p) { return { lat: p.lat + 0.00010696 * p.lat - p.lon * 0.000017467 - 0.0046020, lon: p.lon + 0.000046047 * p.lat + p.lon * 0.000083049 - 0.010041 }; }, degreeToDms: function(deg, delim) { var h = parseInt(deg); var m = parseInt((deg - h) * 60); var s = (deg - h - (m / 60)) * 3600; var ss = (Math.round(s * 10) / 10); if (m < 10) m = '0' + m; if (ss < 10) ss = '0' + ss; if (Number(ss).toString().indexOf('.') == -1) ss = ss + '.0'; return [h, m, ss].join(delim ? delim : '.'); } }; }