2008-10-27

GMap2 と GStreetviewPanorama の位置情報を相互に連携する方法

Golazo MA4 team のなかじまんです。新機能のお知らせです。

Golazo MA4 で Google ストリートビューを使って、メモの位置の風景を確認できるようにしました。
Golazo MA4 でメモを表示するとき、そのメモの位置を表す Google マップに加え、Google ストリートビューを表示して、その位置の風景を確認できるようにしてみました。今回は、ココメモの "よく読む" のリンク先だけ対応しました。今後は、ココメモの追加や編集でも対応する予定です。
予定どおり、Golazo MA4 で、ココメモを追加するときと編集するときに、Google ストリートビューを表示して、その位置の風景を確認しながらメモできるようにしました。次のスクリーンショットのとおりです。



Google マップの移動に応じて、ストリートビューが連携します。また、ストリートビューの移動に応じて、Google マップが連携します。つまり、マップとストリートビューが相互に連携します。さらに、マップの地点で、ストリートビューのデータが存在しなときは、ストリートビューを非表示にします。

GMap2 と GStreetviewPanorama の移動イベントをハンドリングして、緯度経度を軸として、相互に連携するだけで簡単ジャンと思いきや、GStreetviewPanorama の不完全さ? により、実現にかなり苦労しました。

ので、ソースコードを抜粋して、ポイントを紹介しておきます。

// GStreetview
var pano = new GStreetviewPanorama(document.getElementById('pano'));
//pano.hide(); //BUG

GMap2 は生成してあるとします。まず、GStreetviewPanorama を生成します。このとき、オプションである初期の緯度経度は指定しません。

はじめは非表示とするため、hide メソッドを呼び出したいところですが、この時点で hide メソッドを使うと、show メソッドで表示できなくなってしまいました。バグっぽいです。

// GStreetviewClient
var client = new GStreetviewClient();
client.getNearestPanoramaLatLng(point, function(latlng) {
if (latlng) {
$('#pano').show();
if (pano.isHidden())
pano.show();
pano.setLocationAndPOV(point);
}
});

GStreetviewClient を使って、GMap2 の中心の緯度経度から、getNearestPanoramaLatLng メソッドを使って、ストリートビューのデータを探します。point が中心の緯度経度です。データが見つかったときは、GStreetviewPanorama を表示し、現在地として GMap2 の中心の緯度経度を指定しています。データが見つからないときは、非表示のままです。

var initialized = 0;

// GMap2.moveend
GEvent.addListener(map, 'moveend', function() {
client.getNearestPanoramaLatLng(map.getCenter(), function(latlng) {
if (latlng) {
$('#pano').show();
if (pano.isHidden())
pano.show();
if (initialized == 0)
pano.setLocationAndPOV(map.getCenter());
} else {
if (!pano.isHidden())
pano.hide();
$('#pano').hide();
}
if (initialized > 0)
initialized -= 1;
});
});

// GStreetview.initialized
GEvent.addListener(pano, 'initialized', function(location) {
initialized++;
map.setCenter(location.latlng);
});

GStreetviewPanorama の initialized イベントをハンドリングして、ストリートビューで移動したとき、GMap2 の中心がその緯度経度になるように指定しています。

GMap2 の moveend イベントをハンドリングして、マップを移動したとき、その移動先の緯度経度から、getNearestPanoramaLatLng メソッドを使って、ストリートビューのデータを探しています。データが見つかったときは、GStreetviewPanorama を表示し、現在地として GMap2 の中心の緯度経度を指定しています。データが見つからないときは、、GStreetviewPanorama を非表示としています。

ストリートビューで移動したとき、その移動先をマップの中心としていますが、このままだとマップが移動したことになり、さらに、ストリートビューを移動しようとします。つまり、意味のない連鎖のループが形成され、パラパラチラチラと、同じ緯度経度でのストリートビューの表示が繰り返されてしまいます。

ですので、initialized 変数を使って、ストリートビューの再表示が、ただ1回になるように工夫しています。何かもっと正規な方法がありそうな気がするのですが、今のところ見つかっていません。

主要ブラウザで動作確認しましたが、Opera 9.5 で、ストリートビューの現在地が更新されないという不都合を確認しています。それ以外のブラウザは大丈夫でした。原因は分からずじまいです。Opera 9.2 では期待どおりですので、Flash Player とかプラグインと関係がありそうな気もします。

2008-10-26

Postal Search Ajax API 1.1.1 アップデート! タイマの扱いを見直しました。

Postal Search APIs & Solutions team のなかじまんです。

Postal Search Ajax API をアップデートしました。バージョンは 1.1.1 です。アップデートの内容は、次のとおりです。必要に応じて差し替えてください。

(1) 個々に JavaScript の setTimeout と setInterval を使うのをやめ、1つの setInterval で複数のタイマを擬似的に扱うようにしました。

次の Firefox2 のバグに対応することが目的でした。ただ1つの setInterval タイマしか使わないようにしたため、Postal Search Ajax API 単独では、このバグは再現しなくなりました。

FirefoxのsetIntervalに不具合?
FirefoxのsetIntervalは複数を一度に登録して実行するとまとめて処理してしまいます。次のコードは1秒間隔で3回、テキストエリアに実行回数と時間(秒.ミリ秒)を出力する関数を定義して、それを10回呼び出しています。
ただ、聞いたところによると、Firefox2 のセキュリティ更新の提供は、2008年12月中旬をもって終了するそうです。あと1ヶ月ちょいです。無駄なことしたかなぁという感じもありますが、

1つの setInterval を使って複数のタイマを擬似的に実現するようにしたため、同時に多数の API を呼び出すケースで、ツマッた感じがなくなって、滑らかに処理が進むようになったはずです。

(2) 最新の jQuery 1.2.6 に差し替えました。

Postal Search Ajax API に同封の jQuery 1.2.3 を 1.2.6 に差し替えました。

(3) Google Chrome にも対応しました。

Google Chrome の動作確認をし、不都合がないことを確認できました。

2008-10-25

カバンに MA4 バッチをつけて街中を歩いてます。見かけたら声をかけてくださいね。

Golazo MA4 team のなかじまんです。

Golazo MA4 は Mashup Awards 4 で沖電気工業賞と日産自動車賞をダブル受賞しました!
10月19日(日)、リクルート本社で Mashup Awards 4 の表彰式があり、Golazo MA4 は、沖電気工業賞と日産自動車賞をダブル受賞することができました。協力してくださったみなさん。ありがとうございました。
その後の Mashup Awards 4 の広まりがいまひとつという印象がありますので、自主的にささやかな宣伝活動をしちゃいます。しばらくの間、わたしのカバンに MA4 バッチをつけておきます。



金沢文庫、青物横丁、品川(駅中)、品川シーサイド、大崎(駅中)、大手町、三田(駅中)あたりを歩くことが多いです。見かけたら声をかけてくださいね。

カバンの写真は、沖電気工業さんから副賞でもらった Nikon デジタルカメラ COOLPIX P6000 で撮ったものです。



愛犬(コーギー)の写真も撮ってみました。デジカメの知識はほとんどないので、どないなもんでしょう。

2008-10-20

Golazo MA4 は Mashup Awards 4 で沖電気工業賞と日産自動車賞をダブル受賞しました!

Golazo MA4 team のなかじまんです。

10月19日(日)、リクルート本社で Mashup Awards 4 の表彰式があり、Golazo MA4 は、沖電気工業賞と日産自動車賞をダブル受賞することができました。協力してくださったみなさん。ありがとうございました。

↓表彰状の盾です。沖電気工業賞と日産自動車賞とあります。



↓受賞者みんなでの記念撮影の様子です。私は中央付近、黄色いTシャツ(ここらっとさん)の後ろにいます。わかるかな。



さっそく、沖電気工業さんの OKILab.jp 開発日記でも紹介して頂けました。ありがとうございます。今のところ機能や精度で LocoSticker 位置表現特定 API にとって変わるもの見つかっていませんので、突っ走っちゃてください。さらなる発展を期待しています。

MA4の最優秀賞は、ChaMap! LocoSticker賞は、Golazo MA4 (OKILab.jp開発日記)
LocoStickerの位置表現特定APIをうまく使っていただき、地図上にメモを残すといった実用性の高いサービスにマッシュアップしていただけたと思います。また、カーナビとの連携も興味深く、まさにその場所の情報を取るというサービスにぴったりです。
日産自動車さんのカーウイングスブログでも紹介して頂けました。ありがとうございます。日産車のオーナーじゃないのが心苦しいですが、一般車向けの NV-BD600DT というカーウィングスに対応したカーナビを発売するとのことで、購入を検討しています。

カーウイングスブログ: 【MA4】日産自動車賞は「Golazo MA4」に決定!
Golazo MA4は、ココナビという機能を有しており、PCで場所に関するメモをして、それをクルマの中ではインターネット情報チャンネルを利用して、使うことができます。これまでのインターネット情報チャンネルとは違って、利用者が自分のためにコンテンツを作るようなサービスと言ってもいいでしょう。素晴らしい作品ですね。
↓沖電気工業さんから副賞として、Nikon デジタルカメラ COOLPIX P6000 を頂きました。GPS を搭載していて、写真に位置情報を付与できるとのことです。位置情報と写真の関係も関心がありますので、いろいろと活用してみます。



↓日産自動車さんから副賞として、日産(モータースポーツ含む)の関連グッズをたくさん頂きました。なんと!「8曲しか入らないMP3プレーヤーを実現した、128MBのMP3プレーヤー(通称:はっちゃん)」もあるじゃないですか... ネタがわからず、ごめんなさい。NISSAN 提供のラジオドラマと関係してるみたい。

<

↓受賞者だけに配られたバッチです。



↓表彰式の出席者に配られたお土産です。リクルートさんとサンマイクロさんのグッズが盛りだくさんです。



当初は Mashup Awards 4 に応募することが目的でしたが、受賞という結果が出てさらに達成感が高まりました。ただ、優秀賞の作品は非常にレベルが高いので、比較してしまうと、ひぇーと感心するほかありませんでした。素晴らしすぎて、お手上げです。

受賞作品のリスト も公開されました。刺激になりますので、見てみるといいですよ。

2008-10-17

Golazo MA4 で公開してもらったメモを削除できるようにしました。

Golazo MA4 のなかじまんです。機能改善のお知らせです。

Golazo MA4 で、友達から公開してもらったメモを削除できるようにしました。

↓次のスクリーンショットのとおり、友達から公開してもらったメモに、削除するリンクを表示するようにしました。このメモが不要になったら削除できるということです。ここでいう削除とは、公開を中止するということで、友達のメモ自体を削除するわけではありません。



今までは、メモを公開する側の意図を優先していたのですが、公開してもらった側でメモの削除の自由がないため、その結果、メモを公開する側も気を使ってしまい、友達の間で、気軽にメモを分かち合えないという、あまりよくない状況になってしまいました。

ですが、今後は、メモを公開された側で自由にメモを削除できますので、少しでも公開したいメモがあれば、気兼ねなくどんどん公開できるようになりました。これで、メモの輪が広がることを期待しています。

2008-10-15

Golazo MA4 で Google ストリートビューを使って、メモの位置の風景を確認できるようにしました。

Golazo MA4 team のなかじまんです。新機能のお知らせです。

Golazo MA4 でメモを表示するとき、そのメモの位置を表す Google マップに加え、Google ストリートビューを表示して、その位置の風景を確認できるようにしてみました。

↓次のスクリーンショットのとおりです。

今回は、ココメモの "よく読む" のリンク先だけ対応しました。今後は、ココメモの追加や編集でも対応する予定です。



Google ストリートビューは、日本の主要都市しか対応していません。ですので、Golazo MA4 では、ストリートビューを表示できる位置(つまり、データが存在するとき)だけ、ストリートビューを表示する工夫をしてみました。

↓ソースコードを抜粋したものです。

// GStreetview
var pano = new GStreetviewPanorama(document.getElementById('pano'));

var client = new GStreetviewClient();
client.getNearestPanoramaLatLng(point, function(latlng) {
if (latlng) {
$('#pano').show();
pano.setLocationAndPOV(point);
}

GStreetviewPanorama オブジェクトを生成するとき、オプションの緯度経度をを与えません。そして、ストリートビューを表示する div 要素は、事前に display:none; で非表示としています。

GStreetviewClient オブジェクトの getNearestPanoramaLatLng メソッドを使って、メモの位置(point 変数がそれ)付近に、ストリートビューのデータがあるかどうか問い合わせています。

メモの位置付近にデータ(latlng 変数がそれ)が存在するときは、前述の div 要素を表示し、GStreetviewPanorama オブジェクトの setLocationAndPOV メソッドを使って、その位置のストリートビューを表示しています。メモの位置付近にデータが存在しないときは、何もしないので、ストリートビューは表示されなことになります。

Google ストリートビュー APIのノウハウをいくつか tips [okyuu.com] がとても参考になりました。ありがとうございます。

今回は、ただ単に、ストリートビューを表示するだけで、地図との連携といったインタラクティブな機能はありません。どのような機能や操作性が有益なのか、まだ掴めきれていませんので、よいアイディアがありましたら、ぜひ教えてください。

注意点です。主要な OS とブラウザで動作確認しましたが、MacOS X の Firefox2 だとストリートビューが表示されない現象を確認しています。また、古いバージョンの Flash Player だと、ストリートビューを操作するとき、JavaScript エラーが発生することがあります。Flash Player 9 以上をオススメします。

2008-10-12

Golazo MA4 のココモバでメモるとき、その場で友達に公開できるようにしました。

Golazo MA4 team のなかじまんです。新しい機能のお知らせです。

Golazo MA4 のココモバ(携帯電話版)で、現在地をメモするとき、指定した会員に、そのメモを公開できるようにしました。外出先のその場から直接メモを公開して共有できますので、即時性のあるフレッシュなメモを分かち合うことができます。また、PC を使ってメモを公開するという手間もなくなりました。

次のとおり、ココメモの登録ページに "公開する会員" という項目を追加し、メモを公開できる会員を一覧表示するようにしました。ここで、公開したい会員をチェックして、メモを登録すると、チェックした会員にそのメモが公開されます。



そうそう。昨日、Mashup Awards 4 の応募作品一覧 が公開されました。Golazo MA4 は、CARWINGSLocoStickerMextractr (メタデータ自動抽出API) のカテゴリに登録されています。ほかの応募作品などを見ると、いろいろな使い方や応用方法が見れるので、アイディアを刺激されます。

2008-10-08

Golazo MA4 のココモバで、現在地からメモまでの乗換案内を表示できるようにしました

Golazo MA4 team のなかじまんです。新しい機能のお知らせです。

Golazo MA4 のココモバ(携帯電話版)で、現在地からメモまでの乗換案内を表示できるようにしました。現在地から少し離れたメモが見つかったとき、そのメモの場所までの路線や所要時間を確認できるので、役立つこと間違いなしです。

次のとおり、メモのページに "乗換案内" というリンクを追加しました。このリンクを選択すると、



現在地からメモの場所までの乗換案内を表示します。乗換案内は Google トランジット を使っています。最寄り駅の直近の発車時刻とかも分かるので、駅で待ちぼうけしないような時間調整にも役立つかもしれませんね。



Google トランジットは、地名や駅名などのテキストしか入力できない印象があったのですが、いろいろ試してみると、"35.278834,139.675839" といった緯度経度が入力でき、地点から地点の乗換案内も検索してくれるようです。素晴らしいのひとこと。

乗換案内は aquilegia さんから貰った要望 & アイディアです。ありがとうございました。

2008-10-03

Aptana Jaxer で生成したページが70文字前後で意図せず改行されてしまう(ことがある)

次のような、改行を含まない textarea 要素があったとします。

<textarea rows="12" cols="48">Modern web sites and applications use Ajax to create engaging user experiences: the HTML and CSS are set in motion using JavaScript running in the browser and calling back the server. To achieve this, the server needs to prepare the web page appropriately, and to know what to do when the JavaScript calls it. But the server knows nothing about the HTML and CSS DOM, nor how to handle JavaScript data, and you can't code it in JavaScript...</textarea>

ブラウザで、この textarea 要素を表示すると、当然ですが、次のようになります。



Aptana Jaxer 0.9.7.2472 を介して、この textarea 要素を含む HTML ページを生成すると、次のように、70文字前後で意図せず改行されてしまうのです。

<textarea rows="12" cols="48">Modern web sites and applications use
Ajax to create engaging user experiences: the HTML and CSS are set in
motion using JavaScript running in the browser and calling back the
server. To achieve this, the server needs to prepare the web page
appropriately, and to know what to do when the JavaScript calls it. But
the server knows nothing about the HTML and CSS DOM, nor how to handle
JavaScript data, and you can't code it in JavaScript...</textarea>

ですので、ブラウザで、この textarea 要素を表示すると、次のように、意図しないところで改行されることになります。なんてこった。



サーバサイドの JavaScript で textarea 要素の内容を調べてみたところ、意図しない改行は含まれていなかったので、Aptana Jaxer が DOM をシリアライズするときに、なんらかの理由(理由なんてあるのか?)で、改行を追加していると推測できます。

んで、新しい Aptana Jaxer 1.0.0.3674 RC B で試してみたら、改行されることなく、期待どおり表示されました。どうやら Aptana Jaxer の不具合だったようですね。ただ、Aptana Support を探しても、それらしき報告が見つからないのです。いつ直したんだろうか。

なので、別の視点で調べたところ、Mozilla 関連で同じような事象がある(あった?)ようです。2005年となっているので、かなり古い話題ですね。

Mozilla-gumi Forum [One Topic All View / Re[4]: composerでソースの改行の抑制 / Page: 0]
HTMLのソースファイルが72文字くらいで自動的にwrapされてしまいます。時々半角英数字と全角文字の間で改行されることがあって,困っております。「元のソースの形式を維持する」,「HTMLソースを再整形する」どちらでも同じです。この自動的な改行を抑制することは可能でしょうか?
新しいバージョンの Aptana Jaxer では改善されているので、深追いする必要はないのですが、改善する意図なく Mozilla との関係で、なんとなく直っちゃったみたいな感じだと嫌(なんて自分勝手な感覚なんでしょう)なので、時間があるときに、もう少し背景を調べてみます。

2008-10-02

Aptana Jaxer から Mextractr を使ってメモから位置表現と緯度経度を抽出する(後編)

Aptana Jaxer から Mextractr を使ってメモから位置表現と緯度経度を抽出する(前編)
Golazo MA4 は Mextractr メタデータ自動抽出 API も使って、メモから位置情報を自動抽出しています。... Google Maps API を使って、位置表現から緯度経度を求めています。Google Maps API をどのように呼び出しているかは、後編で紹介しようと思います。
Golazo MA4Mextractr メタデータ自動抽出 API を使って抽出した位置表現の緯度経度を Google Maps API (Geocoding via HTTP) を使って求めています。Google Maps API というと JavaScript API のイメージが強大ですが、REST API もサポートしてたりするのです。

Golazo MA4 から Google Maps API をどう呼び出しているか、実際のソースコードを引用して紹介します。

// Google Maps API - Geocoding via HTTP
// http://code.google.com/apis/maps/documentation/services.html#Geocoding_Direct
var url = 'http://maps.google.com/maps/geo?' +
$.param({ q: text, output: 'xml', key: Golazo.GOOGLE_APIKEY });

Google Maps API の URL とクエリを準備します。クエリの URL エンコードは jQuery を使っています。text は抽出対象のテキストです。apikey は Google Maps API キー です。output は出力形式です。省略すると json になりますが、eval が好みじゃないので XML を取得してから JSON に変換するアプローチとしています。

var xml;
try {
xml = Jaxer.Web.get(url, { as: 'xml' });
} catch (e) {
throw new Error(''+e);
}

Google Maps API を GET メソッドで呼び出して、実行結果の XML を DOMDocument オブジェクトとして取得しています。as プロパティに xml を指定すると、XML をパースしてくれます。

// jQuery XML to JSON Plugin
// http://fyneworks.com/jquery/xml-to-json/
var kml = $.xml2json(xml, true);

jQuery XML to JSON Plugin を使って XML を JavaScript オブジェクトに変換しています。第2引数の true は、要素数に関わらず Array オブジェクトに変換することを意味しています。

//var code = kml
//.Response[0]
//.Status[0]
//.code[0]
//.text;

実行結果を表すコードを参照できますが、コード分類が大雑把な印象で、具体的なメッセージも付与されないため、エラーであっても処理を継続しています。ですので、コメントアウトしてあります。

var places = (kml.Response[0].Placemark || [])
.map(function(placemark) {

//var address = placemark
//.AddressDetails[0]
//.Country[0]
//.AddressLine[0]
//.text;

var coordinates = placemark
.Point[0]
.coordinates[0]
.text
.split(/,/);

return {
//address: address,
latitude: coordinates[1],
longitude: coordinates[0],
altitude: Golazo.WHERE_TOKYO.altitude
};
});

return places;

実行結果から緯度経度を取り出して、配列にまとめています。抽出対象のテキストから、さらに具体的な位置表現をも得られます。が、今回は使っていないので、コメントアウトしています。address 変数がそれです。

なお Mextractr メタデータ自動抽出 API は、代表的な地名(都市名などかな?)のとき、実行結果に緯度経度を付与して返却してくれます。ただ、すべての位置表現に対して、緯度経度が付与されるわけではないので、Google Maps API を使って、位置表現から緯度経度を求めています。

2008-10-01

Aptana Jaxer から Mextractr を使ってメモから位置表現と緯度経度を抽出する(前編)

Aptana Jaxer から LocoSticker を使ってメモから位置表現と緯度経度を抽出する
Golazo MA4 は LocoSticker 位置表現特定 API を使って、メモから位置情報を自動抽出しています。... 1件も位置表現が抽出できないときは、別の API を使って、メモから位置情報を抽出しようと試みます。この続きは、後日、紹介します。
Golazo MA4Mextractr メタデータ自動抽出 API も使って、メモから位置情報を自動抽出しています。 Mextractr メタデータ自動抽出 API は、場所などの位置表現に加えて、人名や法人名、日時表現、何をするかの表現など、テキストから様々な角度のデータを抽出できます。まさにメタデータ抽出といったところです。

Golazo MA4 から Mextractr メタデータ自動抽出 API をどう呼び出しているか、実際のソースコードを引用して紹介します。

// Mextractr Web API
// http://www.emetadata.net/doc
var url = 'http://api.emetadata.net/mextractr';
var data = $.param({ text: text, apikey: Golazo.MEXTRACTR_APIKEY });

Mextractr メタデータ自動抽出 API の URL とクエリを準備します。クエリの URL エンコードは jQuery を使っています。text は抽出対象のテキストです。apikey は Mextractr API キー です。

var xml;
try {
xml = Jaxer.Web.post(url, data, { as: 'xml' });
} catch (e) {
throw new Error(''+e);
}

Mextractr メタデータ自動抽出 API を POST メソッドで呼び出して、実行結果の XML を DOMDocument オブジェクトとして取得しています。as プロパティに xml を指定すると、XML をパースしてくれます。

// jQuery XML to JSON Plugin
// http://fyneworks.com/jquery/xml-to-json/
var feed = $.xml2json(xml, true);
if (feed.message)
throw new Error(feed.message[0].text);

jQuery XML to JSON Plugin を使って XML を JavaScript オブジェクトに変換しています。第2引数の true は、要素数に関わらず Array オブジェクトに変換することを意味しています。

// 位置表現だけを抜き出す
feed.entry.forEach(function(entry) {
if (entry.where) {
entry.where.forEach(function(where) {
response.push({ label: where.valueString });
});
}
});

実行結果から位置表現だけを取り出して、配列にまとめています。

// 位置表現から緯度経度を求める
Golazo.each(response, function(i, where) {
var geos;
try {
geos = Golazo.Geo.get(where.label);
} catch (e) {
throw new Error(''+e);
}

var geo = geos[0] || {};
where.latitude = geo.latitude;
where.longitude = geo.longitude;
where.altitude = geo.altitude;

if (where.latitude)
return false; // break
});

Google Maps API を使って、位置表現から緯度経度を求めています。Google Maps API をどのように呼び出しているかは、後編で紹介しようと思います。

位置表現から緯度経度が取得した時点でループを抜け出します。つまり、メモの先頭よりの位置表現を採用しているということです。ですので、メモの意味するところと違う結果になることがありえます。まだまだ改善の余地があるところです。