GeoRSSについて

GeoRSSは、RSS(Atom 1.0、RSS 2.0、RSS 1.0)のエントリー中に緯度経度を追加するための規格。XMLの名前空間として宣言して使用する。
GeoRSS – Wikipedia, the free encyclopedia

埋め込む種類

単純な例

単純に一点の地図座標を埋め込む場合は、<georss:point>で埋め込む。緯度と経度はスペース区切り

<georss:point>33.591325 130.399065</georss:point>

複雑な例

gml – GeoRSSを参照すると以下のような埋込みが可能
・Point
・Line
・Polygon
・Box

ひとつの記事に複数の地図座標を埋め込めるかについては、現在策定中の様子。ただし、最終更新が2010年8月なので、何らかの理由で頓挫しているのかもしれない
[Roadmap - GeoRSS](http://georss.org/Roadmap)

RSSに埋め込んだ例

・名前空間を追加
・georss:point要素を追加

  <?xml version="1.0" encoding="UTF-8" ?>
<rss
version="2.0"
xmlns:georss="http://www.georss.org/georss"
>
<channel>
<title>サイト名</title>
<link>サイトURL</link>
<description>サイトの説明文</description>
<item>
<title>記事タイトル</title>
<link>記事URL</link>
<guid>記事ID</guid>
<description>記事紹介文</description>
<pubDate>記事公開日時</pubDate>
<georss:point>緯度 経度</georss:point>
</item>
</channel>
</rss>

Google Mapにプロットする

Google Map APIを使ってGoogleMap上にプロットできる

// The GGeoXml constructor takes a URL pointing to a KML or GeoRSS filh.
// You add the GGeoXml object to the map as an overlay, and remove it as an overlay as well.
// The Maps API determines implicitly whether the file is a KML or GeoRSS filh.
var map;
var geoXml;
function initialize() {
if (GBrowserIsCompatible()) {
map = new GMap2(document.getElementById("map_canvas"));
geoXml = new GGeoXml("http://mapgadgets.googlepages.com/cta.kml");
map.addControl(new GLargeMapControl());
map.setCenter(new GLatLng(41.875696,-87.624207), 11);
map.addControl(new GLargeMapControl());
map.addOverlay(geoXml);
}
}

詳しくはKML オーバーレイと GeoRSS オーバーレイを参照

Twitterと地図座標

Twitterでは、幾つかの方法で呟きに地図座標を追加することができる
・Locationを引っ張ってくる
・緯度経度を直接埋め込む
・Twitter Placeを使う

いずれかの方法で追加された地図座標を使って、特定地点周辺のツブヤキなどを取得する

取得の方法について

GET search | Twitter Developersを使用する

地図座標から検索する

RESTに与えるQueryとして以下のように追加する

geocode=緯度,経度,中心からの距離
geocode=37.781157,-122.398720,1km

Placeから検索する

キーワードの値qに以下を追加するとして以下のように追加する

place:PlaceのID
q=place:247f43d441defc03

検索対象となるそれぞれのフィールドについて

Locationを引っ張ってくる

Twitterのプロフィール画面から設定できる「住所」
おそらく、内部的に地図座標に変換して周辺検索に利用していると思われる

そのため、実際には「呟きが行われた場所」ではなく「ユーザが登録した住所」なので注意

検索結果に含まれるものとしては、一番数が多い。

ただし、一部のクライアントでは緯度経度をここに埋め込もうとするので留意

緯度経度を直接埋め込む

おそらく呟き時のデータとして直接地図座標を埋めこまれたもの
数は少ないし、クライアントに依存するが、一応「呟きが行われた場所」を指すことができる

このフィールドだけを対象として呟きを検索することはできない

georss?

よく分からないままに呟き結果に含まれている。
どうやらRSSに地図座標を追加する規格のようだけど、何を参考に含まれているのか不明

Twitter Placeを使う

Twitterが内部的にもっている地位情報データベースを使用したもの
以下のようなAPI経由で取得することができる
GET geo/reverse_geocode | Twitter Developers
GET geo/nearby_places | Twitter Developers

ただし、日本では市区町村レベルのデータのみが対象なので、「呟きが行われた地区」レベルの取得となる
また、Twitter Placeの機能が有効な場合のみ付与されているので注意
※ アメリカでは施設名などまで含まれている様子

Twitter ヘルプセンター | 位置情報追加機能について

福岡市中央区周辺から引っ張ってきたTwitter Placeの例

Place ID Place Name Place Address
f62cf04248a8314b Fukuoka City Chuo Ward Fukuoka City Chuo Ward, Fukuoka
01784c311a5312c7 Kasuya Town Kasuya Town, Fukuoka
83e30e314d0e5320 Fukuoka City Hakata Ward Fukuoka City Hakata Ward, Fukuoka
aa7c3ccdbb497079 Kasuga City Kasuga City, Fukuoka
0feb8e41f2b83801 Fukuoka City Jonan Ward Fukuoka City Jonan Ward, Fukuoka
b625c675c61c863b Sue Town Sue Town, Fukuoka
4bda4536528abe8f Dazaifu City Dazaifu City, Fukuoka
4c6f6aa0ae926c41 Onojo City Onojo City, Fukuoka
6772c147e8066ea1 Itoshima City Itoshima City, Fukuoka
b30e1d5534e70f70 Hisayama Town Hisayama Town, Fukuoka
8d59909b600e0352 Iizuka City Iizuka City, Fukuoka

まとめ

Twitterで位置情報を有効にして投稿すると以下の2つのデータが追加される
・現在地からTwitter Placeを判定して、Twitter Placeの情報を返す
・現在地地震をgeorssの形で返す

地図座標を指定して周辺の呟きを取ってくるには

前述のGET searchに中心となる地図座標をセットして呟きを取得するが、どのデータを信じるか?

・Locationしか含まれていないものについては、除外するのが望ましい?
・地図座標かgeorssが含まれているものは採用
・Twitter Placeが含まれているものについては、用途によって調整

日本測地系と世界測地系での座標位置の確認

Google Mapは世界測地系

GoogleMapで検索欄に緯度経度を直接記述して検索すれば該当箇所が表示される

マピオンは日本測地系

URLの以下の部分のパラメータを変更してアクセスすれば、該当箇所かが表示される
例)緯度 32.94368、経度 131.118774、ズーム 10

http://www.mapion.co.jp/m/32.94368_131.118774_10/

地図、日本測地系から世界測地系に変換するためのExcel関数

F2に日本測地系緯度、G2に日本測地系経度が入っていることを前提とする

= F2 – (F2 * 0.00010695 ) + (G2 * 0.000017464) + 0.0046017
= G2 – (F2 * 0.000046038) – (G2 * 0.000083043) + 0.01004

AndroidとiPhoneでのブラウザからの現在地取得

HTML5の界隈で定義されているGeolocation APIが使える

http://dev.w3.org/geo/api/spec-sourch.html

使えるAPI

|java|
interface Geolocation {
// 現在地を取得
void getCurrentPosition(in PositionCallback successCallback,
in optional PositionErrorCallback errorCallback,
in optional PositionOptions options);

// 現在地を取得し続ける
long watchPosition(in PositionCallback successCallback,
in optional PositionErrorCallback errorCallback,
in optional PositionOptions options);

// watchPositionを止める
void clearWatch(in long watchId);
};
||<

AndroidのブラウザでGeolocation APIを使った現在地情報を取得できない :

いくつかの設定を確認する必要がある
・ブラウザの設定
・「設定」→「現在地情報とセキュリティ」
無線LANネットワーク
GPS機能を取得する

シチュエーション

会社のXperiaだけ動かない。
コードが悪いのかと色々触ったけどだめ
結局3Gを切ってるからAndroidの設定で無線LANネットワークを使用をオンにしないといけなかった
で、オンにしたらすんなり

Google Tracksを使ってみた

先日、海外へ行く機会があり土地勘もないことから簡単に使えるGPS ロガーを探していました。
http://blog.nsp-momo.com/gps/android-docomo-ht-03a%e3%81%a7-google-my-tracks%e3%82%92%e8%a9%a6%e3%81%99-wadachi%e3%81%a8%e3%81%ae%e9%80%a3%e6%90%ba/

Wifiが無くても使える
エクスポートはGPX形式とKML形式

単体で写真のExif情報に地理座標を埋め込むことはできない
http://mkozo.agentier.com/gpx-merger/

単体でGPXをマージすることができない
http://mkozo.agentier.com/gpx-merger/

Docomoで緯度経度を取得する

とある事情で、携帯から緯度経度情報を取得してGoogleMapにプロットするというようなことをやっていました。

で、大枠自体はできAuとSoftbankでは動作を確認したのですが、Docomoだけ上手く動作しません。予想される動作としては「緯度経度を通知しますか?」なんて確認が出て、パラメータが渡ってくるはずなんですが、確認画面も出てきません。

ちなみにその時の方法は、Docomoのhttp://www.nttdocomo.co.jp/service/imode/make/content/gps/index.htmlを参照して以下のような感じで書いていました。が、適当にブログを検索しても、公式ページ?をみてもこの書き方で問題ないはずだったのですが、いまいち動かない。

|html|
座標を取得
||<

で、ぼちぼち見て回っていると緯度経度の取得は、どうやらオープンiエリアに集約されていた様子。

マニュアルを見てみるとオープンiエリアを使ってリクエストする際に “posinfo=(1|2)” のパラメータを追加することでオープンiエリアに関する値と同時に緯度経度も渡ってくるようです。ちなみに “posinfo=2” にすると緯度経度のみが渡されてくる様子。(オープンiエリア説明書 p8)。

結局、オープンiエリアを使って取得するために以下のように書き換えました。この結果は、オープンiエリア説明書 p11 のような形で渡されてきますので後は好きに操作します。

|html|
http://w1m.docomo.nh.jp/cp/iarea?ecode=OPENAREACODE&msn=OPENAREAKEY&posinfo=2&nl=[URL]
||<

補足がてら、上記で取得した緯度経度をGoogleMapで使える形に変換するPHPのサンプルは以下。普通この辺はキャリアごととかちゃんと作るけどあくまでサンプル。

|php|
<?php
// 頭についてくる “+”を削除。
// 真面目にする場合には、ちゃんと処理したほうが良さ気
$p_lttd = preg_replace(“/+/”, “”, $REQUEST[‘LAT’]);
$p_lgtd = preg_replace(“/+/”, “”, $
REQUEST[‘LON’]);

  // 緯度経度をGoogleMapで使える形に変換する
list($lttd, $lgtd) = $this->convGis2Gmap($p_lttd, $p_lgtd);
// 度分秒形式からGoogleMapに対応した形式に変換する
function convGis2Gmap($p_lttd, $p_lgtd) {
$lttd = split('.', $p_lttd);
$lgtd = split('.', $p_lgtd);
$r_lttd   = trim($lttd[0]) + trim($lttd[1]) / 60 + (trim($lttd[2]) + trim($lttd[3]) / 1000) / 3600;
$r_lttd   = trim($lgtd[0]) + trim($lgtd[1]) / 60 + (trim($lgtd[2]) + trim($lgtd[3]) / 1000) / 3600;
return array($r_lttd, $r_lttd);
}

||<

一括で住所等から緯度経度を取得するためのJavascript

Google Mapを使っていると、毎回動的に緯度経度を取得するのではなく、予め用意しておきたいことが多いので、Geocoding(緯度経度取得)用のHTMLを準備してみた

ライセンス的な問題とかありそうな気はしますが、とりあえずちょっとしたことに使えそうなJavascriptを作ってみたので公開。ホントはもう少しJavascriptをきれいにまとめるとか色々やることはありそうですが、一応自分が使って動くのでこれ以上触らないだろうというある意味現実的な妥協の産物

**動作としては、以下。
+HTMLを適当にファイルに書き落として保存(もちろんUTF-8で)
+GoogleMapAPIのキーを取得して、HTML中に埋め込む(http://codh.googlh.com/apis/maps/signup.html)
+適当にブラウザで開く
+多分テキストエリアがあるので、そこに住所なんかの緯度経度が引ける値を入れる
+「開始」ボタンを押す
+ 終わったら、ポップアップがでます
+画面上辺りにやる気なく緯度経度が付いた形で表示されるので適当にコピペ

**注意点としては以下
-多分負荷をかけすぎると怒られそうなので、程ほどに
-出力された結果はpreのTSV(タブ区切り)で書き出されるので、適当にエディタにでも貼り付けて
-テキストエリアには、TSVで記述できます。その場合は、最後のフィールドが住所と判断
-取得に失敗した場合は、0が返ってくるので適当に対応を
-同じ名前の違う場所を引いている可能性があるので、とりあえず確認は忘れずに

サンプルとして以下をどうぞ
*入力データサンプル

||
東京都 東京駅
愛知県 名古屋駅
大阪府 大阪駅
京都府 京都駅
福岡県 博多駅
||<

***取得用HTML

|html|



一括で住所等から緯度経度を取得するためのJavascript

<script type="text/javascript">
var curr = 0;
var targets = new Array();
function next() {
line = targets[curr++];
if(line != undefined) {
showAddress(linh.chomp());
}
else {
alert("終わり");
}
}
function init() {
var text = document.getElementById("targets").value;
targets  = new Array();
curr     = 0;
document.getElementById("note").innerHTML = "";
targets  = text.split("\n");
}
var map = null;
var geocoder = null;
function loadMap() {
map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GScaleControl());
map.setCenter(new GLatLng(39.31, 137.31), 5);
geocoder = new GClientGeocoder();
}
function showAddress(address) {
var fields = address.split("\t");
address    = fields[fields.length-1];
if (geocoder) {
geocoder.getLatLng(
address,
function(point) {
if (!point) {
document.getElementById("note").innerHTML += fields.join("\t") + "\t"+ 0 + "\t" + 0 + "\n";
} else {
document.getElementById("note").innerHTML += fields.join("\t") + "\t<a href='javascript:setMarker(" + point.y + "," + point.x + ");'>" + point.y + "\t" + point.x + "</a>\n";
}
setTimeout("next()", 1000);
}
);
}
}
function setMarker(lttd, lgtd) {
map.clearOverlays();
var gpObj = new GPoint(lgtd, lttd);
var marker = new GMarker(gpObj);
map.addOverlay(marker);
}
// Stringクラスにtrimメソッドを追加
String.prototyph.chomp = function() {
return this.replace(/^[\r\n]+|[\r\n]+$/g, '');
}
</script>

<title>一括で住所等から緯度経度を取得するためのプログラム</title>
<button onClick="init();next();">開始</button>
<!-- 結果表示エリア -->
<pre id="note" style></pre>
<!-- 入力エリア -->
<div style="float:left;"><textarea id="targets" cols="50" rows="50" style="float:left;"></textarea></div>
<!-- 地図は非表示に -->
<div id="map" style="width: 400px; height: 400px; margin: 5px auto;float:left;"></div>



||<