2010年12月27日月曜日

Tahnya x chee 「クリスマス キャロル」 at 西荻窪クワランカカフェ

西荻窪のクワランカ カフェさんで行われたTahnyaの音楽とcheeさんの絵本のコラボイベント「クリスマス キャロル」へ行ってきた。

メインイベントは、cheeさんがこの日のために書き下ろした「ぼくがひろったおとしもの」をcheeさん自身が読み聞かせてくれるというもの。

Tahnyaは音担当。BGMや歌などで雰囲気を盛り上げていた。

この時間はワンパクしていたキッズ達も相当聞き入っていたなあ。

子どもだけでなく、大人にも、読み聞かせっていいと思う。

朝のFヨコの本の時間では、本の紹介と共に少し内容を読み聞かせてくれるのだが、それが結構好きで、その時間帯になると聞き耳を立ててしまったりするものなあ。




そして今回、スペシャルゲストとして、TRI4TH円人図のトランぺッター織田祐亮さんが全編に渡って参加してくれたのだが、彼とTahnyaのセッションがもう・・・(・∀・)イイ!!

特に「couleur」での、ヒラタ君のギターと織田さんのトランペットが絡み合ったソロ。思わずヒラタ君もニヤける程の出来になっている。カッコイイなあ。




「メロディー」も、織田さんのトランペットの味付けで超COOLな仕上がりに。




今年のクリスマス・イブは、素敵な音楽をたくさん聴けて、キッズ達も一緒にみんなでワイガヤ過ごせて、温かい夜になった。

2010年12月21日火曜日

Android アプリでGoogle Maps のズームイン/アウト時に何らかのイベントを処理したい場合はOnZoomListener を実装する

Androidアプリで、Google Mapsのズームイン/ズームアウト時に何らかのイベントを処理したい場合は、OnZoomListener を実装する。

import android.os.Bundle;
import android.util.Log;
import android.widget.ZoomButtonsController.OnZoomListener;
import com.google.android.maps.MapActivity;
import com.google.android.maps.MapView;

public class MapDemoActivity extends MapActivity implements OnZoomListener {

 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);
  createMapView();
 }

 private void createMapView() {
  mapView = (MapView) findViewById(R.id.mapview);
  // デフォルトのズームコントローラーを使用する
  mapView.setBuiltInZoomControls(true);
  // ズームコントローラーのイベントを処理するリスナーを設定する
  mapView.getZoomButtonsController().setOnZoomListener(this);
 }

 @Override
 public void onZoom(boolean zoomIn) {
  if (zoomIn ? mapView.getController().zoomIn() : mapView.getController()
    .zoomOut());
  Log.i(LOGTAG, "onZoom():zoomIn=" + zoomIn);

  // タスクを実行する
  executeTask();
 }

 @Override
 public void onVisibilityChanged(boolean visible) {
 }

onZoomListener を実装すると、必ず、onZoom() とonVisibilityChanged() をオーバーライドしなければならない。

onZoom() は、正に、ズームイン/ズームアウト時に呼ばれるメソッドであり、onVisibilityChanged() は、デフォルトのズームコントローラーの表示/非表示が切り替わったときに呼ばれるメソッド。特に行いたい処理が無くても、これら2つのメソッドは記述する必要がある。


注意点としては、onZoom() の処理をオーバーライドするので、自分でzoomIn() やzoomOut() を呼ばなくてはいけなくなること。zoomIn()/zoomOut() をコールしないと、マップがズームイン/ズームアウトしなくなる。

Tweet ボタンをiframe を使って設置する

Tweet ボタンは、「Twitter / ツイートボタン」から、ウィザード形式で簡単に作成できる。

このページを使った場合、デフォルトでは、Twitter のwidgets.js をロードするコードになっている。
だが、iframe を使っても、Tweet ボタンは設置可能だ。

iframe を使っての設置方法は、Twitter のdeveloper ページに掲載されている。
Tweet Button | dev.twitter.com

<iframe allowtransparency="true" frameborder="0" scrolling="no" style="width:130px; height:20px;" src="http://platform.twitter.com/widgets/tweet_button.html?url=URL(UTF-8でエンコード)&amp;text=デフォルトで埋め込んでおきたい文字列(UTF-8でエンコード)&amp;via=Twitterのスクリーンネーム&amp;lang=ja&amp;count=horizontal(ボタン横にカウントを表示)"></iframe>

iframe のsrc は、http://platform.twitter.com/widgets/tweet_button.html であり、そのhtml にクエリーパラメータとして、以下のパラメータを与える。
  • url
  • text
  • via
  • lang
  • count
連結する「&」は、エスケープして「&amp;」と記述する点に注意。

iframe で定義しても、widgets.js をロードする場合と、全く同じ挙動になる。

Tweetボタン、Buzzボタン、FacebookのLikeボタン、いずれかが原因でIE8でページ表示に失敗する

Tweetボタン、Buzzボタン、FacebookのLikeボタンを設置したページが、IE8で表示できないという報告を、幾つか頂いた。それらのボタンが設置されていない他のページは、何ら問題なく表示されるらしい。

しかも、IE8ユーザーだと常にページが表示されないのではなく、表示されないユーザーも若干いる、という状況。自分のIE8では、表示されないと報告を受けたページは、問題なく表示される。

OSはWindows 7 32bit/64bit、Vistaと共通点が見られないが、報告をもらった方のブラウザは全てIE8だった。

ちなみに互換表示でも、表示されない状況は変わらないらしい。


どのように表示されないのか、具体的な報告を送ってくれた方のメールには、以下のエラーメッセージとエラーコードがあった。

メッセージ: HTML Parsing Error: Unable to modify the parent container element before the child element is closed (KB927917)
ライン: 0
文字: 0
コード: 0

「KB927917」については、Microsoftのサポートページに対応策が書かれている。
Why do I receive an "Operation aborted" error message when I visit a Web page in Internet Explorer?

記事を読んだ限り、div要素の内側のscriptブロックで、閉じられていないdiv要素の親コンテナーの内容を変更しようとしたときに発生するようだ。


そこで疑ったのが、TweetボタンやBuzzボタン。それらはjsを読み込んでいるが、もしかしたら、申し訳ないが、それらのjsの書き方が原因でKB927917が起こっているのではないか、ということ。

試しに、Tweetボタン、Buzzボタン、FacebookのLikeボタン、全てを非表示にしてみたところ、KB927917が発生せず、ページが完全に表示できたと報告を頂いた。他サイトのコードの埋め込みは増えているが、大切なページに埋め込むときには慎重にならないといけない。


では、jsのロードではなく、iframeではどうだろいうということで、Twitterのiframeの記述だけ加えてみた。それでまた表示できなくなったと報告を受けるかどうか、様子を見てみよう。

なお、Facebookは最初からiframeのコードが提供されている。Twitterは、デフォルトはjsをロードするコードが提供されるが、調べるとiframeのコードの書き方も提供されている

犯人はBuzzかなあ・・・?

API制限が緩くて開発者としては使いやすいサービスなので、Buzz頑張って欲しいなと思っているのだが・・・

2010年12月16日木曜日

DRMフリーのmp3がzipで固められただけの単なるデータとしての音楽。これはファンを信じていないと出来ないことだろう。 | slashonline.com

Slashの「Watch This」。

元NirvanaのドラマーDave Grohl、Guns N' Roses時代からの盟友Duff McKaganと共に、ボーカル無しで、骨太なロックを聞かせてくれる。




Slashのサイトを見に行ったら、この楽曲が入ったアルバムは、slashonline.comでSlash自身が売っている。

しかも「Watch This」のmp3は、無料でダウンロード出来るようになっている(メールアドレスの登録が必要)。
Discography - Slash Online

そしてなんと、mp3データだけの販売もある。品揃えも抱負だ。
SLASH
  • mp3データ $9.98
  • mp3データ + CD $14.98
  • mp3データ + レコード盤 $21.98
  • 上記の全てのメニューで、Tシャツを$18で追加購入可能
  • mp3データ + CD + レコード盤 + 限定Tシャツ + フルカラーブックレット + ライナーノーツのデラックス版 $59.98
限定5本だけどSlashのギター付きというメニューもあったが、さすがにそれはソールドアウト(^^;)。


ページ下部では、アルバム全曲が視聴出来るようになっている。しかも30秒だけなどではなく、最初から最後まで全部。

どこまで太っ腹なのでしょう。というか、それでも購入してくれると信じている、自信の裏返しなのか?


早速、mp3データを購入。
14曲入りで$9.98。
つまり、日本円で約840円。
1曲1ドル以下!
安すぎる。これほど良心的な価格設定がされているのだ。購入しない理由はないだろう。


日本からでも、クレジットカードで購入できた。勿論、データだけなので配送料などもない。

ダウロードリンクが購入完了ページと購入完了メール内に含まれている。

ダウンロードリンクをクリックすると、zipがダウンロードできる。展開するとアルバム全14曲のmp3と、レコーディング風景の写真が入っている。mp3にはアルバムアートワークをはじめ、最低限のタグも記入されている。

iTunesにインポートして聞くこともできるし、SDカードに入れて、Galaxy Tabで聞くこともできる。

素晴らしい。


しかし、
ダウロードリンクをどこかに公開すれば・・・
いや、14曲全部、ダウンロードデータをどこかに公開すれば・・・

誰にでもフリーで聞かれてしまうのでは?


勿論、Slash自身、そういった危険も考えているだろう。でも、Slashは自分のファンを、自分の楽曲に興味を持ってくれた人を、信じているのだろう。そこまで信じられたら、逆に、下手なことはできない。

購入完了メールには、「Your Receipt From Slash」「© Slash 」と、Slashからのレシートであることが前面に押し出されていた。こういった点も、防御になっているかもしれない。しかもファンとしては、SlashからThank Youされているようで、嬉しい。


購入システムも含めて、slashonlineのサイト全体は「Topspin」というサイトで管理されているようだ。アーティストが、手売り感覚で、簡単に商品を販売・購入できるように、というのがサイトの目的らしい。

iTunesやAmazonで購入するより、個人的には、アーティストをより身近に感じられて好感をもった。まさに手売り感覚のよう。


それにしても、DRMフリーの世界が開く地平はすごい。

2010年12月10日金曜日

世界地図がFacebook色に塗られていく | World Map of Social Networks | Vincos Blog

Vincenzo Cosenza氏が、最新の「World Map Of Social Networks」を公開している。
World Map of Social Networks | Vincos Blog

ベースにしたのは、Alexa社と、Google Trends for Websitesの統計データということだ。

2009年6月から2010年12月までのソーシャルネットワークのトラフィックデータが、世界地図上にマッピングされている。気になった点が幾つかある。

日本
今年の6月まではmixi色に塗られているが、現在はAmeba色に塗られている。

追記 2010.12.11
その後、Amebaはポータルやブロブホスティングプロバイダーも行っているので、純正のソーシャルネットワークサービスではないということで、トップトラフィックはmixiへ変更されたようです。
In Japan Mixi is still the most used web-based social network (Ameba that I previously mentioned it’s not a pure social networking site, but also a portal/blog-hosting provider). But if we look to mobile social networks usage the leader is Gree followeb by Mobage Town. [edited thanks to the insights from Akky Akimoto]
TechCrunchには、初発の画像が載っていますが。
World Map Of Social Networks Shows Facebook’s Ever-Increasing Dominance


モンゴル
今年の6月から現在までの間にFacebook勢力下へ。

イラン
2009年6月まではFacebookの勢力下だったが、2009年12月に空白地帯になり、現在はCloobというサイトがトップトラフィックのようだ。Facebookがトップから転落するなんて。政治的関係?

インド
以前にインドはGoogleのOrkutが普及している数少ない国だと聞いたことがある。しかし、2009年12月以降は、ここもFacebookの勢力下になったようだ。

ブラジル
ブラジルでは、GoogleのOrkutがトップトラフィックを誇っている。珍しい。でもブラジル一国でも国の面積が大きいと、バカに出来ない大きさに感じる。

ヨーロッパ
ヨーロッパは、どんどんとドメスティックなソーシャルネットワークから、Facebook勢力圏への移行が進んでいる。いろんな国があるのに、ほぼFacebook一色に塗られようとしている。


結論としては、世界地図がどんどんFacebook色に染められているということだろう。
頑固なのは、日本、ロシア、中国、ブラジル、ベトナム、オランダくらいなものだろう。
ちょっと怖いくらいだ。


World Map of Social Networks | Vincos Blog

World Map of Social Networks

15分以上の動画がアップ可能なYouTubeユーザーに選ばれたらしい。それで、何分まで可能なのだろう?

YouTubeで15分以上の動画がアップ可能になったというニュースが、TechCrunchで出ていた。
YouTube Begins To Remove Its Video Time Limits

お試しに、YouTubeアカウントでログインしてアップロードリンクをクリックしてみたら、こんなインフォメーションが。


どうやら15分以上の動画がアップ可能なユーザーとして認められたらしい。

なぜ?
動画本数は200本ほどだし、そんなに再生回数も多くない。
著作権に反するコンテンツがないから?
・・・わからない。

でも、選ばれたというだけで、ちょっと嬉しい気分になってしまう(^^;)


しかし、残念ながらアップしたいと思う15分以上の動画がないので、どうしようもないのだが、何分間の動画までアップ出来るのかは気になる。

Tahnya 3rd.album「クラシック」全国発売記念ライブ at クラブトップス藤沢

Tahnyaのアルバムが、いよいよ、全国レコード店やAmazonでも購入できるようになった。

その全国発売を記念してクラブトップス藤沢で行われたTahnyaのライブへ久しぶりに行ってきた。

ヴォーカルのナヲちゃんは、この日も元気いっぱい。



ギターのヒラタ君は、ギターのみならず、ピアニカ、ボイパーと一人何役も。
Tahnyaの演奏が、二人だけの演奏とは思えない存在感なのは、そういったK.U.F.Uにも理由があるのだろう。



最近、特にお気に入りなのは「クラシック」に含まれている「数かぞえ唄」。
易しい言葉で子どもでも楽しく歌えそうな曲なのだが、ドラマ性があって、まるで良質の絵本のよう。




「羊のパレード」も同じく良質の絵本のような曲なのだが、さらに、曲の展開がQueen的というかロックオペラ的というか、Tahnyaの新しい個性が育っている感じがする。




アルバム「クラシック」も、ストリングスチームを含めたクラシカルな仕上がりで、本当に良質な作品に仕上がっている。



彼らの音楽を知らないのは、人生の楽しみの何割かを失っているんじゃないかと、本気で思う。
多くの人に、彼らの音楽が届くといなあ。

2010年12月8日水曜日

Burritoで書き出したAndroidアプリをGalaxy Tabで起動してみる

「Adobe Flash Builder」 の次期バージョン 「Burrito」でAndroidアプリケーションを書き出してみた。

参考にしたのは以下のサイト。
Run on a device - Flex Test Drive for Mobile | Adobe Developer Connection

以前、Flash Builder 4でAir for Androidを試して撃沈したが、今回はスルスルとうまくいった。



まずはBurritoを起動して「Flex モバイルプロジェクト」としてプロジェクトを作成。


作成したら既に自動的に、srcフォルダにmxmlファイルが作成されている。viewsフォルダには、mxmlファイル名の前に「_(アンダーバー)」が付いたファイルが見える。


views下のmxmlを開いて、ドラッグアンドドロップで、ステージにボタンを適当に配置。


「デバイス」のプルダウンには、ターゲットデバイスとして以下のデバイスが用意されている。


src下のmxmlを開くと、ソースはこんな感じで書かれている。


「Project」> 「リリースビルドのエクスポート」でプロジェクトを書き出し、apkファイルを作成してみる。その前に、USBでGalaxy Tabをつなげる。USBデバッグはオン


Target plarformsは、今のところ、Google Androidしかないが、将来的にはWindows Mobileなども出来るかもしれない。


電子証明書を作成し、指定する。


エクスポートが終了すると、Galaxy Tabのアプリケーション一覧にエクスポートしたアプリが登録されている。


起動してみると、Burritoのデザインビューで見ていた状態と全く同じ状態で起動。


回転させても、ノープロブレム。


全部でものの数分。
簡単なものだったら、Eclipseでゴリ書くよりも確実に早くアプリが作成できる。

バカに出来ない出来だ。

Galaxy Tabでストリートビューを試す。ここにいたのか、ペグマン!

Google MapsのAndroidアプリで、どこからどうやればストリートビューモードになるのかずーっと分からなかったが、ようやく操作方法を発見。

まず、ストリートビューで見たい場所をマップ上でタップして長押し。すると、その場所の住所や画像などのダイアログが表示される。

ダイアログをタップすると、画面右端にストリートビューのキャラクター「ペグマン」が!君はここにいたのか!

ペグマンをタップすると、あっさりストリートビュー起動。画面右下のペグマンをドラッグ。

進みたい場所へドロップ。

ストリートビューで表示している場所が、ペグマンをドロップした場所に変わる。


Wi-Fi環境だとストリートビューの表示も軽快で、Galaxy Tabくらい大きな画面でも、さくさくバーチャルお散歩ができるなあ。

Google eBookstoreで無料ePubをダウンロードしてGalaxy Tabで読んでみる

Google eBookstoreがオープン。

残念ながら書籍を購入できるのはUSオンリーで、日本からは無料のお試し書籍を閲覧することしかできないが、現時点で300万もの書籍データが用意されている。
Discover more than 3 million Google eBooks from your choice of booksellers and devices - Official Google Mobile Blog

Google Booksプロジェクトそのものは、2004年から書籍データのデータベース化などを始めたようだが、ようやくストアのオープンに至ったようだ。Googleはいくつものプロジェクトを矢継ぎ早にリリースしているイメージがあるが、その裏では、研究や準備を何年も続けているものもあるのだろう。


GoogleのeBookstoreの特徴は、一冊の本を、PC、iPad、iPhone、iPod Touch、Android OS端末など、複数のデバイスで閲覧できることだろう。

Androidアプリをダウンロードしようとしたが、日本国内からAndroid Marketでダウンロードしようとすると、残念ながらアプリが見つからないというエラーが表示され、アプリのダウンロードはできないようだ。

しかし、無料のお試し書籍にePubデータがあるので、このePubデータをダウンロードしてGalaxy Tabで読んでみた。使用したのは、デフォルトでインストールされていたアプリ「ブック(eBook)」。

ePubデータをインポートして開いてみたところ。

フリップでページをめくり、単語の長押しで辞書検索や、WikipediaやGoogle検索、ハイライト表示、コピーなどができる。


出版社だけでなく、もし個人レベルでもGoogleのeBookstoreで書籍販売ができるようになれば、今後面白いことになりそうだ。

2010年12月4日土曜日

Galaxy TabでBloggerへの記事投稿はPC並に便利にできるのか?

Galaxy Tab標準搭載のブラウザを使って、Bloggerへの投稿がPCと変わらない程度で出来るか試してみた。

結論としては、記事を作成することはできるが、文字入力があまり便利ではないので、Galaxy Tabのブラウザを使ってBloggerの記事を積極的に書こうとは思えない、という感じ。

どう便利でないかというと、文字を入力しようとすると、文字を入力している箇所でなく、テキストボックス下部に強制的にフォーカスが移動してしまうので、入力している文章を見るために、わざわざテキストボックス上部へ移動しないといけないのだ。

ある程度文章を入力した後だったらフォーカスが下へ移動してもいいのだが、書き出し始めはとても不便だ。


文字を入力しようとすると、

テキストボックス下部へフォーカスが移動して、入力中の文字が見えなくなる。


しかし、ここ数日、Galaxy Tabをゲットしてヘビーに使ってみているが、画面が大きいのに動作が速く、非常に重宝している。iPadだとケースを付けると重すぎて長時間使うには腕が疲れて嫌になってしまったが、Galaxy Tabだと軽くて腕が疲れず、長時間使っていられる。

リッチなFlexアプリケーションも利用できるし、Flash再生も問題ない。JavaScriptプログラムを含んだPCサイトも問題なく表示、動作可能だ。

現状、PCでやっていたことは、開発以外は、ほとんどTabで出来ている。


ソフトバンクがiPadのキャンペーンを始めたこともあり、巷ではiPad熱が再燃するかもしれないし、TechCrunchではiPadの方がGalaxy Tabより愛されるとも書かれているが、私は断然Tab派です(*^_^*)。

2010年11月23日火曜日

三鷹の森ジブリ美術館は細部まで心配りされている。徹底してこだわるジブリクオリティがここにもあった。

一度は行ってみたかった三鷹の森ジブリ美術館。先日、ようやく行くことが出来ました。

入り口は、開演前から多くの人が並んでいて大混雑。
日時指定の予約制なので、入場者数はコントロールされ、そんなに混んでいないのでは?と思っていたのですが、とんでもない。しかも日本人だけでなく、韓国、中国など海外からのお客さんがたくさん。いかにジブリがワールドワイドなのかを実感しました。


美術館に入ってまず印象的だったのは、料理の面取りのように、柱や壁などの角がまあるく加工されていること。子供たちが元気に遊んでも危なくないし、見た目にも優しくて温かい雰囲気です。

屋外の地面にも、おがくずのようなものや中庭の木々に使われていたチップが敷き詰められています。転んでも危なくないし、足が疲れにくく、歩き心地もとてもソフト。こんな所まで配慮されているのかと感心しました。

また、窓が多くて、空間が明るくなるように工夫されているので、館内に居るだけで、とても心地良いです。
歴代のジブリ作品をモチーフにしたステンドグラスも各所に見られ、「これは千と千尋の神隠し」「これはラピュタ」と見て回るだけで楽しく過ごせます。



美術館中庭の風景。壁をつたう蔦が雰囲気をだしています。思わずゆっくりくつろいでしまいます。


基本的に館内には案内板はなく、どこからどういう風に見て回っても自由です。
おかげで、日が暮れるまで隅々まで館内を探検してしまいました。
大人でもついつい探検してしまうような仕掛けが、随所に仕掛けられているのです。

隠れ場所になりそうな小部屋。
小さな螺旋階段や、大きな階段や、年代物のエレベーター。それぞれ行けるフロアが違います。
いろんなところに真っ黒クロスケが小さく描かれていて、それを見つけて回るのも楽しいです。

そして、不必要に多いドアや引き出し。
開けると何があるんだろうと、ついつい開けてしまいます。
ちなみに、ひとつだけ、ドアを開けた先が鏡になっている所があるので、是非見つけてみてください。このドアを見つけたときは、「ヤラれた」と思いました。


カメラを置いて楽しんでほしいという館主・宮崎駿氏の意思に則って、観光地で見られるような、過剰な写真撮影の風景はありません。

ただ、屋上に居るロボット兵との写真撮影は行列でした(^^;)。これはどうしても外せないのでしょうね。自分はロボット兵だけ軽くiPhoneで撮影させてもらいました。





そして土星座。

11月20日からは宮崎駿氏の最新作「パン種とタマゴ姫」が上映されています。
セリフは一切ありません。
アニメーションと音楽と効果音で構成されています。
海外からのお客さんも一緒に、皆で笑ったりハラハラしたりして見ることが出来ます。

以前見た、「プロフェッショナル 仕事の流儀」プロローグ編で、10分強のアニメーション映画では考えられないほどの枚数を、しかも全て手で描くことにこだわって製作している宮崎駿氏の様子が放送されていました。これは是非見に行ってみようと思ったのですが、行って見てよかったです。

これがアニメーションだ!という圧倒的な技量、キャラクターの動きに脱帽です。
また、最後には、未来を感じる作品でした。


一緒に行った夫は「で、結局何が言いたかったんだろう」なんて言ってましたが、恐らくそういう見方は頭が凝り固まった大人の見方で、この作品はもっとほわ~っと観るものなんだと思います。単純に楽しかったです。

土星座の入場券には、過去のジブリ作品のフィルム(本物ではないと思いますが、よく分かりません)が挟まっています。私の入場券は、ポニョでした。台風の中、ホームでリサを待つ宗介のシーンだと思います。こういうちょっとした所も嬉しいですね。

2010年11月15日月曜日

メドベージェフ大統領のツイート「解決できない紛争よりも経済協力の方が有益」には承服できませんね

ロシアのメドベージェフ大統領が週末のAPEC期間中につぶやいたツイート。

Met with Japan's prime minister. I'm certain that economic cooperation is more useful than irresolvable disputes.less than a minute ago via web



「日本の首相と会った。解決できない紛争よりも経済協力の方が有益であると私は確信している。」

訳すと、このような感じでしょうか。


まず、日本の首相について名前を書いてらっしゃらないのが気になります。
文字数は余裕で140文字以内に収まっているので、「Naoto Kan」くらい入るでしょう。

日本の首相は変わりすぎてもう名前が覚えられないということかもしれませんが、会談相手の名前を書かないのは失礼だと思います。

菅政権は多くの面で支持できませんが、自国の首相に失礼な態度を取られるのは承服できませんね。

ちなみに、メドベージェフ大統領がAPECで会談した相手についてツイートしたのは、上記の菅首相との会談だけでした。そういった意味では、多分に日本を意識しているのかもしれません。


さらに今日、福山哲郎官房副長官はNHKの番組で、メドベージェフ大統領が菅首相と会談した際、自らの国後島訪問について「北方領土に行くのが悪いことなのか」と発言していたと、明らかにしました。
「北方領土訪問、悪いのか」=ロシア大統領、菅首相に (時事通信) - Yahoo!ニュース

当然、悪いことです。

旧ソ連による北方領土への侵攻は、日本がポツダム宣言を受諾したことを連合国に告げ、敗戦を受け入れた後、つまり戦争が終結した後に行われたものであり、国際法にも反する不当なものです。

それから今日まで続く北方領土の占領も不当なものであり、北方四島のみならず、南樺太、占守島以下の千島列島の当時日本領土だった場所は、変わらず日本領土のままなはず。にも関わらず、旧ソ連・ロシアの占領で、もう北方領土にはロシアの方々が住んで何十年も経ってしまっている。

このような、明らかに両国間の領土問題の懸案となっている場所へ、日本の許可無く行くことは到底承服できません。


日本の外交には、ぶれずに原則論を主張して欲しいと望みます。

iTouch Glovesは素手と同じ操作感

picnic inc.から販売されている「iTouch Gloves」を買ってみました。
iTouch Glovesアイタッチグローブ -スマートフォンなどのタッチパネル式携帯で使える手袋-

ちなみに、iTouch GlovesでiPad上のGoogle Mapsを操作しているところを、ビデオで撮ってみました。



素手と同じ感覚で操作できます。

そして当然ですが、温かい(^^)。

手触りは普通に手袋で、思ったより柔らかかったです。

難点を強いてあげるとすれば、タイピングの時にローマ字入力を選択していると、素手で操作している時よりもミスタイプが増えるかなという点と、既に少しほつれが出てきたという点でしょうか(^^;)。
言うても、1,890円ですからね。


しかし、既にこういうものも・・・。
着けたままiPhoneを使えるおしゃれな手袋「EVOLG」 - Touch Lab - タッチ ラボ




こちらの方がカラフルでカワイイかも・・・。

でも、プライベートではいいけれど、ビジネスでははめていけないじゃないと思って、自分を納得させました(^^;)。

マップ上データのビジュアル表現で参考になるサイト

マップ上にデータをマッピングする時のビジュアル表現として、参考になるサイトやアプリケーションを幾つかリストアップ。


1. The Open PV Project

The Open PV Project - Time Map
全米各地の太陽光発電システムの導入を、ヒートマップのようにプロットしている。Google Map API+Flashを使用。


2. A World Of Tweets

a world of tweets
Twitter Streaming APIとYahoo! Placemaker APIを使ってツイートの密度をヒートマップや煙のような雲で表示している。HTML5のCanvasを使用。


3. Magic Fiddle, Glee, Magic Piano, Ocarina by Smule

Smuleが作っているiPhoneやiPadアプリでの地図上のデータ表現は、どれも直感的で美しく、参考になる。

Magic Fiddle by Smule - Experience Social Music

Glee by Smule - Experience Social Music

Magic Piano by Smule - Experience Social Music

Ocarina by Smule - Experience Social Music

Galaxy Tab 販売予定価格は機種変で約5万5千円、新規で約5万千円

本日予約が開始されるGalaxy Tab(SC-01C)。

基本的にドコモショップ店頭でしか予約が受け付けられていないこともあり、今日を逃したら次回予約まではある程度の期間待たないといけないかもしれないと思い、勇んで予約へ!(ちなみに、ドコモショップ本厚木店では電話予約も受け付けているとのこと)

行列覚悟で行ったものの、人っ子ひとりおらず、余裕で予約完了。見回したらGalaxy Tabを予約していたのは自分だけでした。多くはシニアの方で、料金プランや修理の相談の方ばかりで、ちょっと肩透かし(^^;)。


ドコモショップで予約時に頂いた用紙によると、販売予定価格は、機種変更(FOMA→FOMA)・契約変更(mova→FOMA)で55,608円新規で51,240円でした。



事前の報道では、4万円程度と言われてましたが、実際はもう少し高かったですね。

上記料金に加えて、自分はHT-03Aをスマートフォン割引で購入したので、残期間から換算して、契約解除料金が約16,800円かかるとのことでした。

合計で約7万円程度。う~ん、そもそもHT-03Aを約1万円で購入したので、それが安かったんだと思うことで自分を納得させました( ̄^ ̄)。


それにしても、ドコモショップ本厚木店さんはいつ来ても対応がいい。ここで嫌な思いをしたことがない。今日もスムーズアンドスピーディーな接客でした。15周年、おめでとうございます!
ドコモショップ本厚木店(神奈川県厚木市)

2010年11月10日水曜日

米政府へは経済政策についてFacebookを通して直接ものを申すことができる | Have a Question About the Economy and Job Growth? Ask us. | The White House

Have a Question About the Economy and Job Growth? Ask us. | The White House

米政府は、ネット求人情報会社のモンスター・ワールドワイド社と組んで、政府の景気回復への取り組みについて直接ものを申せるページを、今週Facebookに開設した。
Monster Keep America Working | Facebook

ボトムアップで進めるスタイルが、アメリカらしいなと感じる。

ちなみに、モンスター・ワールドワイド社は世界各国にオフィスを構えているが、日本のオフィスはない。
中国、香港、インド、インドネシア、韓国、マレーシア、フィリピン、シンガポール、タイ、ベトナム、オーストラリアには、オフィスやサイトが設けられている。
International Jobs, Global Jobs, Jobs Abroad | Monster.com

フーム。

2010年11月9日火曜日

AsyncTaskを使った場合ItemizedOverlayのリストを更新するときはMapViewのinvalidate()を忘れずに

AsyncTaskクラスのサブクラスを作って、バックグラウンドでリクエストデータを処理し、MapView上のItemizedOverlayを更新する処理を行っていた。

ところが、タップしないとアイテムがマップ上に描画されないという症状にはまり、試行錯誤。

結局、MapViewにアタッチされたItemizedOverlayを更新した際にはMapViewのinvalidate()をコールして強制的にビューを再描画させる、ということが肝だった。

参考にしたのは以下のページ。
Maps/NooYawkAsync/src/com/commonsware/android/maps/NooYawk.java at master from commonsguy's cw-advandroid - GitHub
public void onPreExecute() {
   if (sites!=null) {
    map.getOverlays().remove(sites);
    map.invalidate(); 
    sites=null;
   }
  }

  @Override
  public Void doInBackground(Void... unused) {
   SystemClock.sleep(5000);      // simulated work

   sites=new SitesOverlay();

   return(null);
  }

  @Override
  public void onPostExecute(Void unused) {
   map.getOverlays().add(sites);
   map.invalidate();   
  }

上記のソースでは、onPreExecute()でItemizedOverlayを削除し、onPostExecute()で追加するという処理が行れている。

しかし、試してみたところ、その処理は必要ない。
ItemizedOverlayはアプリケーション起動時からMapViewに追加しっぱなしでアイテムリストの更新ができた。

ただ肝は、onPostExecute()のinvalidate()だ。これは忘れちゃいけない。


以下はMyソース。
@Override
 protected void onPostExecute(ArrayList<OverlayItem> result) {

  GeoItemizedOverlay geoOverlay = (GeoItemizedOverlay) mapView
    .getOverlays().get(0);

  // 現在オーバーレイに追加されているアイテムを削除する
  geoOverlay.clear();
  geoOverlay.populateOverlay();

  // オーバーレイにアイテムを追加してpopulate()を呼ぶ
  geoOverlay.addAll(result);
  geoOverlay.populateOverlay();
  mapView.invalidate();
 }

ドキュメントを見ると、ちゃんとinvalidate()がビューを強制的に再描画させるメソッドであることが書いてある。
How Android Draws Views | Android Developers

You can force a View to draw, by calling invalidate().

ドキュメントはよーくチェックしないといけませんな。

自分の目で見て耳で聞くことも出来るだけ心がけよう | 池上彰さんに聞く!日本が国際貢献にお金をかける意味ってあるんですか?:日経ビジネスオンライン

池上彰さんに聞く! 日本が国際貢献にお金をかける意味ってあるんですか?:日経ビジネスオンライン

二つの国の現場を歩いて見て得た一つの教訓は、「その国がこれから発展するかどうかは、若者が本を読んでいるかどうかを見れば分かる」。

ベトナムの首都ホーチミンを訪れたのは真夏の一番暑い時期でした。お昼時になると、みんなお店や家に引っ込んでしまう。しーんと静まり返っている。どうせ昼寝でもしているのだろうとお店の裏を覗いたら、違いました。

 木陰で店番の若者が一心不乱に本を読んでいる。1店だけじゃない。それぞれの店の若者たちがみんな、昼休みを利用して読書にいそしんでいる。「すごいな、これは」と思いました。

 さらにその後、市街の大きな本屋に立ち寄ってみました。(中略)目の前で万引きした若者が捕まって大騒ぎになっていました。彼が何を万引きしたか? 

 英語の本なんです。お金はなくても勉強したくて万引きしたわけです。万引きはもちろんほめられる行為ではありませんが、そこまで本を読んで知識を吸収したい、というベトナムの若者たちの知的渇望を図らずも目の当たりにしたわけです。

現在のベトナムの経済成長は目をみはるものがある。そのバックボーンには、池上氏が実際に目にされた読書熱心な姿に見られるように、強い向上心、向学心、真面目さ、があるのだろう。

自分も常に知識を吸収することを怠らないようにしたい。


池上氏は日本の国際貢献の場を多く取材している。「日本の国際貢献はカネだけ」というのは大いなる誤解である、と語っている。

今回、国際貢献の現場を取材して、専門家にお会いして、現地の人々の声を聞いて、改めて思ったのは、「日本の国際貢献はカネだけ」というのは大いなる誤解である、ということです。

 むしろ実態は逆の場合が多い。少なくとも私が取材したスーダンやウガンダでは、日本の国際貢献はきっちり現地で機能していました。

 それでは、なぜ日本の国際貢献が目立たないのか? 欧米の活動のように華々しく報道されないのか? それは皮肉にも、日本の国際貢献のやり方が、最も現地にカスタマイズされた「理想的な方法」で進められているからです。

私がODAについて調べた時も、ODAが始まった経緯も含めて、利権構造などを書いた書籍は多かった。池上氏が指摘しているように「日本は金を(金だけを)出す」といったイメージを自然と持ってしまうような記述も多かった。

しかし、彼が現場を見て感じたのは、日本の支援が現地に即した形で行われていること、人材も投与していること、だったようだ。


自分が主権者として何かを正確に判断するには、テレビや新聞などでのニュース報道を見るだけでは情報が足りないということを、最近、強く感じる。

インディペンデントな個人や団体が発信しているネット上のコンテンツも含めて、積極的に自分で情報を探して取りに行かないといけない。

でもそれ以上に確かなことは、自分の目で見て耳で聞くことだろう。

現場へ行ってみることも、出来るだけ、心がけよう。

2010年11月5日金曜日

硫黄島からのご遺骨帰還プロジェクトは評価に値する。全てのご遺骨を収集する意欲で取り組んで欲しい。

私が、菅政権で唯一評価しているのは「硫黄島からの遺骨帰還のための特命チーム」を作り、ご遺骨の帰還について積極的に取り組んでいること。
硫黄島からの遺骨帰還のための特命チーム

麻生政権時代にご遺骨収集のための予算がつき、プロジェクトが進められているのだが、特に菅政権は前向きに進めている。

阿久津政務官など、チームメンバーが米国公文書館へ何度も足を運び、埋葬地(どれだけ”埋葬”という言葉がふさわしいのか怪しいが)を調べ、多くのご遺骨を発見している。

この事業をやり終えるには何年もかかるだろうが、途中でやめずに、今後も進めていって欲しいと強く願っている。

メドベージェフ大統領が国後島でツイート

There are so many beautiful places in Russia! Here is Kunashir  on Twitpicメドベージェフ大統領がTwitterアカウントを持っていると知り、彼のツイート @KremlinRussia_Eを見てみたら、案の定、国後島を訪れた際の写真がTwitpicに掲載されているorz。

なぜ現在のあの島の状況を、メドベージェフ大統領の写真から知らなきゃならないんだ。

There are so many beautiful places in Russia! Here is Kunashir http://twitpic.com/32zmwrless than a minute ago via Twitpic



その2つ前のツイートには、国後島を訪れる理由と見られる彼の意思がツイートしてある。

It is the president's duty to oversee the development of every region of the country, including the most remote ones.less than a minute ago via web



国後島がロシアの領土であれば、このツイートはなんら問題はない。その通りだ。

だが、国後島は日本の領土だ。

いや、国後島、択捉島、色丹島、歯舞諸島といったいわゆる北方四島だけでなく、占守島までの千島列島全域と南樺太までのいわゆる北方領土までが、日本の領土だと私は考えている。


日本の首相官邸ページにあたるであろう、クレムリンニュース下のロシア大統領ページ。
President of Russia(英語版)
Президент России(ロシア語版)

まず、眼につくのが「News map: in the Russian regions / in the world」というFlashコンテンツ。
マウスオーバーすると、メドベージェフ大統領がいつ、何で訪れたのか、概要を表示する。

特徴的なのは、過去に訪れていて記事があるところが濃い色で、訪れておらず記事がないところが薄い色で表示されていること。これにより、彼がまだロシア領土で訪れていないところが明確に分かるようになっている。また逆に、大統領がいかにロシア各地を訪れて活動しているかも分かるようになっている。

ロシア語版では全領土が濃い色で塗られている。もし国後島を訪れなければ、国内版マップではサハリン領域だけずっと薄い色で表示されていたのかもしれない。国後島を訪れたのは、このマップを埋める一環ということもあったかもしれない。

ちなみに、英語版ではところどころ薄い色がある。英語版ニュースとして記事にするまでもない国内ニュースがあるので、国内と国外でマップデータが異なるのだろう。

トップページに、このロシア領土を表示するFlashコンテンツがあるということは、どれだけロシア政府が領土や領海を意識しているかということを表している。領土・領海に対して意識を強く持つことは、私は、ごく当たり前のことで、あるべき姿だと思う。


一方、日本の首相官邸の英語版ページ。
Prime Minister of Japan and His Cabinet

領海や領土を象徴するコンテンツは無い。
また、残念だが、ロシア政府のページの方がリッチに感じる。なぜだろう。

まず、日本は、コンテンツが少ないように感じる。
また、首相官邸ページにはファビコンがない。ロシアのものにはロシア国旗をあしらったものが設定されている。
そして、ロシア政府のページは、政府の公式TwitterやYouTubeチャンネルへのリンクがトップにある。各記事には、FacebookやTwitterへ投稿するリンクも設けられている。

あと、私はサイトのソースを見る癖があるのだが、ロシアのものはコメントが英語で書かれていて、ソースが整理されていて美しい。日本のものは日本語のコメントが随所に見られ、ソースがあまり美しくない。

首相官邸ページの日本語版はまだよい。だが、英語版のページははっきり言ってショボい。閣僚一覧ページなどは、Web 2.0どころではなく、Web 1.0レベルに感じる。
Members of the Kan Cabinet


先の記事「Twitter外交で日本の存在感なし | Twitter diplomacy: Who Follows Whom Among World Leaders」にも書いたが、日本政府の発信力を向上させる必要を、強く感じる。

Twitter外交で日本の存在感なし | Twitter diplomacy: Who Follows Whom Among World Leaders

TechCrunch.com
Twitter diplomacy: Who Follows Whom Among World Leaders

今や各国首脳は、Twitterアカウントを持ち、互いにフォローしあい、時にはダイレクトメッセージまで送り合っているようだ。これでは本当に表題通り、Twitter外交だ。

The @KremlinRussia_E and the @WhiteHouse both follow UK Prime Minister David Cameron @Number10gov. These three could actually conduct a direct and secret Twitter diplomacy in 140 characters literally spelling ‘the end of those red phones that have been sitting around for so long’ as Barack Obama recently joked.

稚拙ながら訳してみました。
@KremlinRussia_E(メドベージェフ大統領が英語でツイートするアカウント)と@WhiteHouseはどちらも英国のデービッド・キャメロン首相のカウント@Number10govをフォローしている。この3つのアカウントは、実はダイレクトで秘密の140文字Twitter外交を実際に行なったようで、”長い間居座っていたあの赤電話はもう要らないんじゃないか”とオバマ大統領が最近ジョークを言った。


例えば、メドベージェフ大統領の英語ツイートアカウント @KremlinRussia_Eは、シュワルツネッガー州知事 @Schwarzenegger、ノルウェーのイエンス・ストルテンベルグ首相 @jensstoltenberg、カナダのスティーブン・ハーパー首相 @pmharper、英国のデービッド・キャメロン首相 @Number10gov、オバマ大統領 @BarackObamaとホワイトハウス @WhiteHouseをフォローしている。

メドベージェフ大統領はフォローしているのが10人で分かりやすかったのだが、他の首相・大統領は、何万、何十万というアカウントをフォローしているので、相互フォローをチェックするのが面倒でやっていない(^^;)。

が、オバマさんのジョークのように、これからはTwitter上でダイレクトメッセージをやりとりする機会も増え、Twitterも外交の場へと成長していくだろう。


では、我が日本は?

TechCrunchの写真に菅首相は写っていないし、TechCrunchの記事中に一度もJapanという単語が出てこない。

問題だ。

彼のツイートはユニークだね、と言われるような発信力を菅首相や官邸に求めたい。

2010年11月4日木曜日

ドイツ国内の一部でGoogle MapsのStreet View機能が導入される。いつのまにかGoogle Mapsの表示が若干セカイカメラっぽくなっている。

11月2日、Google MapsのStreet View機能がドイツ国内の一部に導入された。
現在は20都市5つのランドマークのみに対応している。
Google LatLong: A special preview of beautiful Germany in Street View

ストリートビューのドイツ導入は、個人のプライバシーを侵害するとして反対が多く、なかなか進まないと報じられていたが、写真を見ると、なんだかすごくウェルカムな雰囲気の写真が多い(^^;)。
Picasa ウェブ アルバム - a+o GmbH - Street View s...


反対が多くても、Googleは、オプトアウト(個人宅の画像をぼかすといった対応)の申請を受け付けるとして、ストリートビューのドイツ対応を実施する予定だ。こういった面でもオプトアウトというのがGoogleらしい。

10月21日のGoogleのブログ記事によると、このオプトアウトについて、24万4237世帯から求められたとある。この数は対象地域845万8084世帯の2.89%に当たる。これ全部に対応するのは大変そうだ。
European Public Policy Blog: How many German households have opted-out of Street View?

ドイツだけでなく、イタリアでも、地図にマッピングされる前に市民に知らせるように要請されたり、チェコでは、やはりプライバシーを侵害するとして今以上の画像のキャプチャーは禁止されている。ヨーロッパは、プライバシーの侵害について、かなりセンシティブなんですね。
BBC News - German Street View goes live with enhanced privacy


それにしても、今回、ドイツのランドマークのストリートビューを見ていて、Google Mapsの見えが若干セカイカメラっぽくなっていて、驚きました。ストリートビューをスクロールしている時に、Panoramioの写真やGoogle Placesアイコンがマッピングされたり。セカイカメラを参考にしたんでしょうか。

※埋め込んだGoogle Mapsの下にある「View Larger Map」をクリックすると確認できます。

View Larger Map

2010年11月1日月曜日

Buzzの日付書式のフォーマットパターンをTimeクラスのparse3339()を使って簡単にパースする

Google Buzz APIで結果を取得したときの日付書式「2010-10-15T06:51:04.000Z」を、SimpleDateFormatクラスを使って解析する方法について以前書いたが、android.text.format.Timeクラスのparse3339()を使うと、もっと簡単に解析できることが分かった。

public class Message {

 private static java.text.DateFormat FORMAT_DATE;
 private static java.text.DateFormat FORMAT_TIME;
 private Time published;

 public Message(java.text.DateFormat df, java.text.DateFormat tf) {
  FORMAT_DATE = df;
  FORMAT_TIME = tf;
  published = new Time();
 }

 public void setPublished(String published) {
  try {
   this.published.parse3339(published.trim());
  } catch (TimeFormatException e) {
   throw new RuntimeException(e);
  }
 }

 public String getPublished() {
  Date date = new Date(published.normalize(true));
  return FORMAT_DATE.format(date) + " " + FORMAT_TIME.format(date);
 }

RFC3339については、以下にドキュメントがある。
RFC3339 - Date and Time on the Internet: Timestamps


コンストラクタの引数のjava.text.DateFormatで、端末側で選択されているロケール・書式に則った、日付と時間の書式を渡している。これによって、ユーザが設定している書式に則って、日付と時間をフォーマットしている。

Message message = new Message(android.text.format.DateFormat.getDateFormat(context), android.text.format.DateFormat.getTimeFormat(context));

ItemizedOverlay 使用時にたまにArrayIndexOutOfBoundsException が発生するバグへの対応

com.google.android.maps.ItemizedOverlayを使って地図上にアイテムを配置すると、アイテムをタップした際に、たまにArrayIndexOutOfBoundsExceptionが発生して困った。

この問題を解決するには、setLastFocusedIndex(-1)をpopulate()の前にコールする。

APIドキュメントによると、フォーカスが変わったときに自動的にアップデートされるので、ItemizedOverlayを継承したサブクラスで、フォーカスのインデックスを変更する必要はない、と書かれているが・・・。

実際は、リスト更新時に、populate()の前に自分でsetLastFocusedIndex(-1)を呼び、どのアイテムにもフォーカスが設定されていない状態を作らないといけない。

public class GeoItemizedOverlay extends ItemizedOverlay<OverlayItem> {

 private ArrayList<OverlayItem> overlayArrayList = new ArrayList<OverlayItem>();

 public void add(OverlayItem overlay) {
  overlayArrayList.add(overlay);
 }

 public void clear() {
  overlayArrayList.clear();
 }

 public void populateOverlay() {

  // 必ずpopulate()の前にsetLastFocusedIndex(-1)を実行する
  // そうしないと、リストが変わった際にアイテムのインデックスがずれる場合がありArrayIndexOutOfBoundsExceptionが発生することがある
  // http://groups.google.com/group/android-developers/browse_thread/thread/38b11314e34714c3
  setLastFocusedIndex(-1);
  populate();
 }
}

オーバレイアイテム更新時には、clear()やadd()し終わった際には必ずpopulateOverlay()を呼ぶようにする。

// 現在オーバーレイに追加されているアイテムを削除する
geoOverlay.clear();
// 必ずsetLastFocusedIndex(-1)とpoopulate()を実行
geoOverlay.populateOverlay();

for (int i = entries.getLength() - 1; i >= 0; i--) {

 OverlayItem overlayItem = new OverlayItem(・・・);
 // アイテムを追加
 geoOverlay.add(overlayItem);

}

// 必ずsetLastFocusedIndex(-1)とpoopulate()を実行
geoOverlay.populateOverlay();

解決には以下の記事を参考にさせていただいた。
ItemizedOverlay & ArrayIndexOutOfBoundsException > explanation AND solution !! - Android Developers | Google グループ

Android – ItemizedOverlay + ArrayIndexOutOfBoundsException / NullPointerException workarounds « Developmentality


先日のNullPointerExceptionが発生する件といい、ItemizedOverlayを使う際には注意が必要です。

2010年10月26日火曜日

タッチイベントはMapViewとItemizedOverlayのどちらにまず伝わるのか

Android+Google MAP APIでタッチイベントを処理する時のイベントの流れを確認する。
使ったのは以下のクラス。

・MapDemoActivityクラス
MapActivityを継承したクラス。実行クラス。

・CusomizedMapViewクラス
MapViewを継承したクラス。MapDemoActivityのContentViewとして設定。

・GeoItemizedOverlayクラス
ItemizedOverlayを継承したクラス。


これらのクラスは、下から積み上げると以下のような階層関係にある。

GeoItemizedOverlay
|
CusomizedMapView
|
MapDemoActivity


・検証

ディバイスの画面にタッチしたときには、onTouchEvent(MotionEvent event)が呼び出される。

MapViewを使ったときは、Activityに記述したonTouchEventではなくMapView側のonTouchEventが呼び出されることは、前の記事に書いた。

では、MapViewにItemizedOverlayが追加されているときは、タッチイベントはMapViewとItemizedOverlayのどちらにまず伝わるのか。

public class MapDemoActivity extends MapActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  /** マップビュー作成 */
  CustomizedMapView mapView = (CustomizedMapView) findViewById(R.id.mapview);

  Drawable drawable = this.getResources().getDrawable(R.drawable.star);
  GeoItemizedOverlay geoOverlay = new GeoItemizedOverlay(drawable, this);

  /** オーバーレイをマップに追加 */
  List<Overlay> mapOverlays = mapView.getOverlays();
  mapOverlays.add(geoOverlay);
 }
}
public class CustomizedMapView extends MapView {
 @Override
 public boolean onTouchEvent(MotionEvent event) {
  Log.i("onTouchEvent", "CustomizedMapView.onTouchEvent");
  return super.onTouchEvent(event);
 }
}
public class GeoItemizedOverlay extends ItemizedOverlay<OverlayItem> {
 @Override
 public boolean onTouchEvent(MotionEvent event, MapView mapView) {
  Log.i("onTouchEvent", "GeoItemizedOverlay.onTouchEvent");
  return super.onTouchEvent(event, mapView);
 }
}

試してところ、ItemizedOverlayよりも先にMapViewへタッチイベントが伝わることが分かった。
10-26 13:29:55.577: INFO/MapDemo(4253): CustomizedMapView.onTouchEvent
10-26 13:29:55.577: INFO/MapDemo(4253): GeoItemizedOverlay.onTouchEvent

上記のクラスで言うと、

CustomizedMapView→GeoItemizedOverlay

の順番だ。


・結論

MapView側に記述してあるonTouchEventがまず呼ばれる。

そして、MapViewのonTouchEventの最後に実行する、super.onTouchEvent(event)により、MapViewに追加されている各Overlayへタッチイベントが伝えられていく、という流れのようだ。

ItemizedOverlayをMapViewに追加しているときにアイテムが無いとNullPointerExceptionが発生するバグへの対応

ItemizedOverlayがMapViewに追加されているときは、MapViewクラスのonTouchEvent(MotionEvent event)が実行される際に、ItemizedOverlayのonTouchEvent(MotionEvent event)にもイベントが投げられる。

問題は、それがアイテム数が0の時にも起こるので、アイテム数が0の時に画面にタッチするとNullPointerExceptionが発生すること。

10-26 12:00:24.607: ERROR/AndroidRuntime(2753): java.lang.NullPointerException
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.ItemizedOverlay.getItemsAtLocation(ItemizedOverlay.java:617)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.ItemizedOverlay.getItemAtLocation(ItemizedOverlay.java:586)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.ItemizedOverlay.handleMotionEvent(ItemizedOverlay.java:498)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.ItemizedOverlay.onTouchEvent(ItemizedOverlay.java:572)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at hoge.MapDemo.GeoItemizedOverlay.onTouchEvent(GeoItemizedOverlay.java:54)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.OverlayBundle.onTouchEvent(OverlayBundle.java:63)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at com.google.android.maps.MapView.onTouchEvent(MapView.java:625)
10-26 12:00:24.607: ERROR/AndroidRuntime(2753):     at hoge.MapDemo.CustomizedMapView.onTouchEvent(CustomizedMapView.java:52)

今の所この現象を避けるには、ItemizedOverlayを継承したクラスのコンストラクタで、super(boundCenterBottom(defaultMarker));の後で、populate()を呼ぶこと。


・ItemizedOverlayを使うときは、必ずコンストラクタ内でpopulate()を呼ぶ

populate()はアイテムを追加した後に必ず呼ぶメソッドだが、アイテムがあろうがなかろうが、最初からコールしておくということ。これでNullPointerExceptionは発生しなくなる。

public class GeoItemizedOverlay extends ItemizedOverlay<OverlayItem> {

 private ArrayList<OverlayItem> mOverlays = new ArrayList<OverlayItem>();
 private Context mContext;

 public GeoItemizedOverlay(Drawable defaultMarker, Context context) {
  super(boundCenterBottom(defaultMarker));
  mContext = context;
  populate();//これが大事!
 }
}

このバグはIssueとして管理されているので、早めに解決して欲しい方はvoteしてください。
Issue 2035 - android - NullPointerException when scrolling through a MapView with an ItemizedOverlay with no OverlayItems - Project Hosting on Google Code

MapView継承クラスでonTouchEvent()を処理するときに気をつけること

MapViewを利用すると、MapActivityを継承したクラス内にonTouchEvent(MotionEvent event)を書いてもイベントをキャッチできない。

以下のようなコードを書いても、MapViewの方にイベントが取られて、ログが出力されない。

public class MapDemo extends MapActivity {
 @Override
 public boolean onTouchEvent(MotionEvent event) {

  String action = "";
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   action = "ACTION_DOWN";
   break;
  case MotionEvent.ACTION_UP:
   action = "ACTION_UP";
   break;
  case MotionEvent.ACTION_MOVE:
   action = "ACTION_MOVE";
   break;
  case MotionEvent.ACTION_CANCEL:
   action = "ACTION_CANCEL";
   break;
  }

  Log.i("onTouchEvent", "action = " + action + ", " + "x = "
    + String.valueOf(event.getX()) + ", " + "y = "
    + String.valueOf(event.getY()));

  return super.onTouchEvent(event);
 }
}

そのため、MapViewクラスを継承したオリジナルのMapViewクラスを作成し、そのクラス内にonTouchEvent(MotionEvent event)を記述した。その時に気をつけること。


・MapViewクラスを継承する場合は、MapViewクラスのコンストラクタMapView(Context context, AttributeSet attrs)を必ずオーバーライドする

そうしないと、デフォルトのズームコントローラーを使ったり、フリップしてマップを動かすことができない。
静止画像のようにマップが表示されるだけの画面になってしまう。

コードは以下。

public class CustomizedMapView extends MapView {
 public CustomizedMapView(Context context, AttributeSet attrs) {
  super(context, attrs);
 }
 @Override
 public boolean onTouchEvent(MotionEvent event) {

  String action = "";
  switch (event.getAction()) {
  case MotionEvent.ACTION_DOWN:
   action = "ACTION_DOWN";
   break;
  case MotionEvent.ACTION_UP:
   action = "ACTION_UP";
   break;
  case MotionEvent.ACTION_MOVE:
   action = "ACTION_MOVE";
   break;
  case MotionEvent.ACTION_CANCEL:
   action = "ACTION_CANCEL";
   break;
  }

  Log.i("onTouchEvent", "action = " + action + ", " + "x = "
    + String.valueOf(event.getX()) + ", " + "y = "
    + String.valueOf(event.getY()));

  return super.onTouchEvent(event);
 }
}
この時のレイアウトは以下。
<?xml version="1.0" encoding="utf-8"?>
<hoge.MapDemo.CustomizedMapView
 xmlns:android="http://schemas.android.com/apk/res/android"
 android:id="@+id/mapview"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:clickable="true"
 android:apiKey="apiKey" />
MapView呼び出しはこんな感じ。
public class MapDemoActivity extends MapActivity {
 @Override
 public void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.main);

  /** マップビュー作成 */
  CustomizedMapView mapView = (CustomizedMapView) findViewById(R.id.mapview);
 }
}

2010年10月22日金曜日

Buzzの日付書式のフォーマットパターン

Google Buzz APIで結果を取得したときの日付書式は、以下のもの。

2010-10-15T06:51:04.000Z

JavaのSimpleDateFormatクラスへ、この日付書式をパースするフォーマットパターンを与えると、以下になる。

yyyy-MM-dd'T'HH:mm:ss.SSS


使い方としてはこんな感じ。
private static final SimpleDateFormat FORMATTER_INPUT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
private Date published;

 public void setPublished(String published) {
  try {
   this.published = FORMATTER_INPUT.parse(published.trim());
  } catch (ParseException e) {
   throw new RuntimeException(e);
  }
 }

追記 2010.11.01
android.text.format.Timeクラスのparse3339()を使うと、もっと簡単に解析できることが分かりました。
明日に向かって昇龍拳: Buzzの日付書式のフォーマットパターンをTimeクラスのparse3339()を使って簡単にパースする

2010年10月21日木曜日

公聴会には社長だけでなくトヨタ一丸で出席していたのかもしれない | トヨタはリコールを乗り越えたか?:日経ビジネスオンライン

トヨタはリコールを乗り越えたか?:日経ビジネスオンライン

米国トヨタ自動車販売社長のジェームス・レンツ氏は、今年2月に米議会の公聴会へ出席したとき、背後に、社員やディーラーの気を感じたと語っている。

公聴会は、トヨタの命運がかかった、とても重要な場だったろう。多くの社員やディーラーがかたずをのんで見ていて、そんな彼らの気が公聴会に居る社長へ伝わったのかもしれない。


私は、全社一丸となって~なんて、アメリカの会社文化の中にはないのでは、と思っていた。
が、トヨタには彼らを束ねる価値観があるようだ。この記事の中で社長が語っていた、トップから社員まで同じ現場に立って課題に取り組んでいく「トヨタウェイ」というスピリットが、それなのかもしれない。


ディーラーの方が語った「オレはトヨタが好きなんだ」という言葉。
この言葉は作り手にとって何よりも嬉しいご褒美だろう。そんな言葉をもらうために、私は私のものづくりを頑張ろう。


それで結局、この公聴会で議論になった問題はどうなったのか。
どうやら多くの場合は運転ミスが原因だったようだ。

トヨタ急加速は大半運転ミス? 電子制御異常なし 米運輸省調査 - SankeiBiz(サンケイビズ)

58件のうち35件はブレーキが踏み込まれておらず、運転ミスの可能性が高いことを示している。5件からはデータを得ることができなかった。(・・・)急加速の原因は電子制御スロットル装置の異常ではないというトヨタの主張に沿った形といえそうだ。(・・・)NHTSAから、安全問題の対応をめぐり1637万5千ドルの民事制裁金の支払いを課された。

ええー!、結局、自分たちの主張が正しかったと結論づけられようとしているのに、1637万5千ドル(日本円で約14億円)も制裁金を支払い、リコールに対応して・・・。大変だったろう。

公聴会では、トヨタに対して「恥を知れ」と言った女性もいた。
「トヨタは恥を知れ」 急加速体験の女性、米公聴会で証言 写真3枚 国際ニュース : AFPBB News

でも、その方が売却したレクサスの新しいオーナーは、なんの問題もないと言っている。
米国 / 急加速したトヨタ車、その後はトラブルなし / The Wall Street Journal, Japan Online Edition - WSJ.com


人生には、本当に理不尽で「まさか」と思う事が起こることがあるのだろう。

でもトヨタはこの経験を教訓にして、来年からアメリカでは全車にブレーキ優先機能を標準装備し、さらに安全な車にしようとしている。
トヨタ、全車にブレーキ優先機能を標準装備 来年から米国で (産経新聞) - Yahoo!ニュース


がんばれ、トヨタ。

2010年10月20日水曜日

AndroidではJSONとAtomのどちらが速いの?

APIの呼び出しでは、JSONとAtomの両方のフォーマットでレスポンスを取得できる場合が多いが、どちらがパフォーマンスがよいのだろう?

同じような疑問を持った人がいるようだ。
Benchmarking JSON vs XML Parsing in Android - ubikapps.net

彼はAtomをSAXでパースする方が、JSONより3倍も速かったと言っている。
So despite having smaller response sizes, overall JSON is 3 times slower! For the foreseeable future I’ll stick with the Atom reading list and SAX. Hopefully a future version of Android will have JSON streaming support built in.

接続環境や機体によって結果は変わるだろうし、またチューン次第ということもあり、一概にAtomの方がよいとは言えないかもしれないが、データとして参考にしよう。


ちなみに、AtomのパースはDOMよりSAXの方が速いようだ。
Android XML Parser Performance — Developer.com

Google Buzz APIで検索した時に返ってくるデータフォーマット(Atom形式)

TwitterのSearch APIと同じように、Google Buzz APIでも、searchクエリにパラメータを与えて、HTTP GETリクエストを発行して検索する。

例:
https://www.googleapis.com/buzz/v1/activities/search?lat=42.370498&lon=-71.083603&radius=100&prettyprint=true&alt=atom

「いつ、どこで、誰が、何をつぶやいたのか」という情報だけに限ると、チェックするタグは、以下にまとめたものくらい。

※Atom形式
<feed>

  <entry>
    <!-- メッセージ -->
    <title>あいうえお</title>

    <!-- 投稿日 -->
    <published>2010-10-15T06:51:05.485Z</published>

    <author>
      <!-- gmailアカウントの姓名 -->
      <name>おおつかみさほ</name>

      <!-- ユーザのサムネイル画像パス -->
      <link rel='photo' type='' href='' />

    </author>
    <activity:object>
      <buzz:attachment>
        <!-- 添付写真パス -->
        <link rel='enclosure' type='' href='' />

        <!-- 添付写真のプレビュー画像(小さめ)パス。1枚でも複数のタグが含まれる? -->
        <link rel='preview' type='' href='' />

      </buzz:attachment>
    </activity:object>

    <!-- 投稿された場所の緯度経度 -->
    <georss:point>42.370498 -71.083603</georss:point>

  </entry>

  <!-- 以下、結果件数だけ、entryタグが連続する -->

</feed>
これだけ押さえていれば、「いつ、どこで、誰が、何をつぶやいたのか」を表示できる情報が最低限集められる。


ちなみに、レスポンスデータの全タグを列挙すると以下になる。
<?xml version="1.0" encoding="UTF-8"?>

<feed>
  
 <!-- httpsから始まる、発行したリクエストのURI -->
 <link rel="" type=""/>
 <!-- 検索結果をブラウザなどで表示した時のタイトル -->
 <title></title>
 <!-- 検索結果内の最も新しい更新日 -->
 <updated></updated>
 <!-- この検索のID -->
 <id></id>
 <generator uri="http://www.google.com/buzz">Google Buzz</generator>
 
 <entry gd:kind="buzz#activity">
  <title></title>
  <published></published>
  <updated></updated>
  <!-- このBuzzのID -->
  <id></id>
  <!-- このBuzzのURI -->
  <link rel="alternate" type="text/html" href=""/>
  <!-- このBuzzのフィード -->
  <link rel="self" type="application/atom+xml" href=""/>
  <!-- このBuzzのコメントのフィード -->
  <link rel="replies" type="application/atom+xml" href=""/>
  
  <author>
   <!-- ユーザID(数字)-->
   <poco:id></poco:id>
   <poco:photoUrl></poco:photoUrl>
   <name></name>
   <!-- ユーザのプロフィールURI-->
   <uri></uri>
   <link rel="photo" type="" href=""/>
   <activity:object-type>http://activitystrea.ms/schema/1.0/person</activity:object-type>
  </author>
  
  <!-- メッセージ。titleと同じもの -->
  <content type="html"></content>
  <activity:verb>http://activitystrea.ms/schema/1.0/post</activity:verb>
  
  <activity:object>    
   <activity:object-type>http://activitystrea.ms/schema/1.0/note</activity:object-type>
   <!-- メッセージ。titleと同じもの -->
   <content type="html"></content>
   <buzz:original-content type="text"/>
   <!-- このBuzzのURI -->
   <link rel="alternate" type="text/html" href=""/>
   <!-- このBuzzに添付されたデータ -->
   <buzz:attachment>
    <activity:object-type>http://activitystrea.ms/schema/1.0/photo</activity:object-type>
    <link rel="enclosure" type="image/jpeg" href="/>
    <link rel="alternate" type="text/html" href=""/>
    <link rel="preview" type="image/jpeg" href=""/>
   </buzz:attachment>
  
 </activity:object>
  
  <source>
   <activity:service>
    <title>Mobile</title>
   </activity:service>
  </source>
  
  <!-- このBuzzを見る権限-->
  <buzz:visibility>
   <buzz:aclentry type="group">
    <poco:id>G:@me:@public</poco:id>
    <uri>https://www.googleapis.com/buzz/v1/people/@me/@groups/G:@me:@public?alt=atom</uri>
    <poco:name>Public</poco:name>
   </buzz:aclentry>
  </buzz:visibility>
  
  <!-- likedの件数やURI -->
  <link rel="http://schemas.google.com/buzz/2010#liked" type="application/poco+xml" href="" buzz:count="0"/>
  <georss:point></georss:point>
  <!-- 郵便番号など-->
  <georss:featureName></georss:featureName>
  
  <poco:address>
   <!-- 投稿されたロケーションをフォーマットした文字列 -->
   <poco:formatted>X-X 〇〇町, Atsugi, Kanagawa Prefecture, Japan</poco:formatted>
  </poco:address>
 
</entry>

</feed>

BuzzのデフォルトのレスポンスフォーマットはAtom。TwitterはJSON推奨で、Atom形式も現状は使用できるが、今後はサポートされなくなる。

PubSubHubbubもフィードが必要だし、BuzzはAtomとの親和性が高いんでしょうか。

2010年10月19日火曜日

iPhoneのカメラで撮影した写真を含んだ投稿をBuzzへポストすると、ロケーション検索結果に含まれる

Google Buzz APIで、lat/lon, radiusを指定してバズを検索したとき、位置情報付きで投稿した覚えがない、夫のバズが検索結果に含まれていた。



調べてみると、バズ自身に位置情報が付けられていなくても、iPhoneのカメラで撮影した写真をバズに付けた場合、写真のヘッダに含まれている位置情報が読み取られて、検索結果に含まれるということが分かったw(゚o゚)w。

ユーザは自分では位置情報を付けた覚えがないので、まさか自分の投稿がロケーション条件付き検索に含まれるとは思わないだろう。

出来れば、Google Buzz API側で、写真の位置情報はロケーションの割り出しには使わない仕様へ変更した方がよいと思う。


ユーザとしてこれを防ぎたい場合は、iPhoneのカメラで撮影した時に、位置情報を付けない設定に変更するとよい。

iOS3.xまではオール・オア・ナッシングで、全てのアプリケーションで位置情報が利用されるのを許可するかしないかだったが、iOS4ではアプリケーション毎に位置情報のオンオフが選択できるようになったので、便利だ(^-^)。

変更方法は以下のとおり。

iPhoneの「設定」 > 「一般」 > 「位置情報サービス オン」をタップ > カメラのオンをオフへ変更

詳しくは下記の記事が参考になる。
琴線探査: iPhoneの標準カメラアプリで位置情報がついてしまう事への対処法(iOS4以降)


Buzzで位置情報付きで検索すると、上の例も含めて、位置情報が付いたバズしか結果に含まれないので、データが見やすくて良い。

それに、レスポンスデータのサンプルもAPIドキュメントに載っているので、学びやすいなあ( ̄ー ̄)。

Google Buzz API にはrate limitingはあるのか?geoで検索は可能か?

Google Buzz APIを調査。

今年のGoogle I/OでBuzz APIがお披露目されてから5ヶ月程経つ。まだそれほど利用出来る機能はないかなと思っていたが、予想以上にAPIが整理されていて驚いた。

・RESTでBuzz APIを利用するためのドキュメント
Developer's Guide (v1): Using REST - Google Buzz API - Google Code

・OACurl(curlを使ったコマンドラインユーティリティ)を使ってBuzz APIを利用するためのドキュメント
OACurl Cookbook (v1) - Google Buzz API - Google Code


TwitterのAPIで気になっていた点である、位置情報に基づく検索は可能か、リクエストに回数制限はあるのかなどをまず調べる。


1. 位置情報に基づく検索は可能か

可能。

・lat/lon, radiusを指定してのBuzz検索
例:
https://www.googleapis.com/buzz/v1/activities/search?prettyprint=true&lat=42.370498&lon=-71.083603&radius=100&alt=atom

・places IDを指定してのBuzz検索
例:
https://www.googleapis.com/buzz/v1/activities/search?prettyprint=true&pid=CkQ6AAAA11-ykKK8mNCmfSTu9mOJzycQEMmYhAHcmOBt_G0IfZaA-0bPCDUTZaLKnskzqipJi3ljzUqlJ3SUvqL2GpyThRIQOPA13i2LQ3ttW4skW22YyxoUzIpT90QeEa9nswO7XqpywYuyErQ&alt=atom

・バウンディングボックスを指定してのBuzz検索
例:
https://www.googleapis.com/buzz/v1/activities/search?prettyprint=true&bbox=-79.38728,43.64183,-79.36265,43.66737&alt=atom


また、lat/lon, radiusなどでフィルタリングして、なおかつ、firehoseのようなリアルタイムな更新情報を取得することも出来る。但し、PubSubHubbubを使うのが前提。

例:
https://www.googleapis.com/buzz/v1/activities/track?q=query&lat=latitude&lon=longitude&radius=radius

このリクエストの結果では、PubSubHubbubのリアルタイム更新で必要となるフィードのメタデータが取得できる。


2. リクエストに回数制限(rate limiting)はあるのか

ある。

書き込みや更新系の処理は、1ユーザあたり1500回/時。
その他のリクエストは、1IPあたり50回/秒。
制限を緩和して欲しい場合はフォーラムに問い合わせてくれとあるが、十分な数だ。

Are Buzz API requests rate limited?
Yes, requests to write or modify data are limited to 1500 requests per hour, per user. All other requests are limited to 50 requests per second, per IP address. If you require a higher limit, please inquire in the forum.


ちなみに、PubSubHubbubを使った時もこのrate limitingが適用されるのかは分からない。


次は、実際にAPIを試してみて、具体的なlat/lanを含んだBuzzがどれだけあるのか確認してみよう。

ジョブズ氏曰くiOSとAndroidの違いは「integrated versus fragmented」

アップル社の第4四半期収益の発表の場にスティーブ・ジョブズ氏が登場し、5分ほどスピーチをしたようだ。
その模様がYouTubeで「見れないが、聞ける」。It’s a must-listenだ。

彼が逆さまなのはご愛嬌^^?



このスピーチの中で、ジョブズ氏は、

GoogleはAndroidをオープンでiOSをクローズドと特徴づけようとしている。でもそれは不誠実だ。iPhoneとAndroidの本当の違いは”統合されているか、バラバラか”ということだ、と語っている。
Google likes to characterize Android as open and iOS as closed. We think this is disingenuous. The real difference between the iPhone and Android is, “integrated versus fragmented.”

確かに、様々な種類のOSバージョン、画面サイズや、インターフェースの違いなど、機種の違いにあわせてテストしたり、異なるバージョンをマーケットに用意したりという手間が、Androidの場合は必要だ。

iOSでは、Appleが用意している幾つかの動作環境のみに集中すればよいので、開発者は真にクリエイティブなことだけに注力できるかもしれない。


でもね、ジョブズ。
一生懸命企画して、開発して、テストして、それでもAppleの審査に通らない、リリースできない場合があるというのは、開発サイドにとってはすごく負荷が高いしリスキーなことなのですよ。

作れば直ぐにマーケットに出せるという自由さは、何ものにも代えがたい価値のように、最近私は痛感しています。

2010年10月18日月曜日

靖国神社へ初めて参拝する

日本人として一度は行かねばと思っていた靖国神社だが、先日ようやく参拝できた。

まず、大鳥居の大きさに驚いた。「空をつくよな大鳥居」と歌われていたそうだが、正にそのとおり。

沿道には銀杏の木が等間隔に並んでいた。銀杏が色づく11月下旬頃に靖国神社を訪れると、とても美しい風景が見られるだろう。

神門と第二鳥居の間の、上空がぽっかり空いた空間がとても清々しくて心地良かった。この日はちょうど快晴で、見上げると青く澄み渡った空が広がっていた。本当にここは清らかな空間で聖地なのだなと感じる。

土曜日だからか、参拝者が多かった。電車の時間を気にしてらっしゃる方もいて遠方からいらっしゃったのかもしれない。また、海外からいらっしゃった方も多く、ハングルや中国語、フランス語、英語など、いろんな言葉が聞こえた。靖国神社は日本人だけでなく海外の方も参拝するような大きな神社なのだなと感じる。


今月の社頭掲示は楠瀬益實命の「魂は永遠に生きる」だった。

「人類の幸福、世界の平和の礎のために之が最適の死に場所だ」

楠瀬殿が書き記された言葉は、自らの死が、祖国のみならず世界、人類の平和につながるようにと願ったものだと思う。繰り返し読む。


拝殿の脇には槍が立てられていた。

平和は自ら勝ち取るものだという意味なのか。それとも何かいわれがあるのだろうか。
祖国のために散っていった方々の冥福をお祈りし感謝を申し上げる場所という印象を靖国神社に持っていたので、こんなに大きな槍が拝殿前に立っていたのは、少し驚きだった。


拝殿へ参拝した後は、遊就館を見学する。

「御祭神の遺徳を尊び、また古来の武具などを展示する施設」として構想された遊就館。だからからか、鎧兜、日本刀、弓矢、大砲、零式艦上戦闘機、人間魚雷回天に到るまで多くの武器が展示されていた。

遊就館の展示や置かれている配布物で気になったのは、大東亜戦争初期などで「赫々(かくかく)たる戦果をあげた」という記述だ。

赫々たる戦果は英語で表現すると、win a glorious victoryとでも言うか、つまりgloriousでbrilliantな成果という意味だ。

更に、それだけ成果があったということは、その裏には当然命を落とした敵軍の方が多くいるということだろう。

国のために散っていかれた御霊に祈りを捧げる靖国神社に併設されている施設として、ふさわしい記述なのか気になった。


遊就館は予想以上に展示フロアが広くて、2時間ほど見て回ったが、最後は駆け足になってしまった。

遊就館に行きたかったのは、祖国、つまりは今ある私達を守るために、大東亜戦争や支那事変などで亡くなった方々のお写真やお手紙を拝見するなどして、彼らに会いに行くことだった。だが、それらは最後の方に展示してあり、残念ながらじっくり見る時間がなかった。

次の機会にはもっと時間を作って、じっくり拝見したいと思う。

TwitterのStreaming APIでlocationsを指定する方法とSearch APIでgeocodeを指定する方法

位置情報付きのツイートを利用するには、Streaming APIでlocationsを指定する方法と、REST型Search APIでgeocodeを指定する方法の2種類がある。

どちらにも、ご利用上の注意があり、どちらが正解とも言えない。
明日に向かって昇龍拳: TwitterのStreaming APIでlocationsを指定する場合の注意点
明日に向かって昇龍拳: TwitterのSearch APIでgeocodeを指定する場合の注意点


しかし個人的には、位置情報付きのツイートを取得するには、現時点では、Streaming APIでlocationsを指定する方がよいと思う


Streaming APIを使うメリット: 1. rate limitingがない

マップをインターフェースにするなどして、頻繁にTwitterのサーバへリクエストを発行するような仕様にする場合には、回数制限というのは大きなボトルネックだ。Streaming APIでは、一度開いた接続は基本的に無期限だ。回数制限という概念がない。


Streaming APIを使うメリット: 2. geo要素がnot nullなツイートしか検索結果に含まれない

位置情報が必ず指定されている、つまりgeo要素がnot nullなツイートしか検索結果に含まれないので、結果データが扱いやすい。

Search APIではやたらめったら結果が含まれてくるが、その中から使えるデータを精査して取り出すなど手を加える必要がある。作るときにも、その面は手間がかかるし、アプリケーションのパフォーマンスにも、コストとして影響するだろう。

更に、Search APIでは位置情報が付いたツイートが何ページ目に出現するのか分からないので、結局多くの結果にアクセスする必要が出てくる。当然、rate limitingに引っ掛かり易くなる。

geoがnot nullなツイートに限られることは、結果数が少なくなるというデメリットでもある。
しかしそれは、位置情報が付いたツイートが増えるように位置情報を付け易いクライアントを別途用意したり、少しずつでも位置情報付きのツイートが将来的に増えていくことで、状況も変わっていくだろう。


Streaming APIを利用するには、OAuthの利用や、切断時のリトライなど、実装しなくてはならないことが幾つかあるが、それらを考えても、やはり、上記のメリットの方が現時点では上回る。

TwitterのSearch APIでgeocodeを指定する場合の注意点

TwitterのREST型Search APIでは、geocodeをパラメータに含めて、ある地点の近くのツイートを取得することができる。いわゆるnearby検索だ。しかし、実際に使ってみると問題が多々ある。


1. geoがnullなツイートがほとんど

検索結果に含まれるツイートは、ほとんど(95%以上)geo要素がnullで、位置情報が含まれていないものばかり。

では、どうやって位置情報がプロットできるツイート数を増やすか。

まずは、プロフィールに入力されている住所をジオコードしたり、「iPhone:35.xxx, 132.xxx」などの文字列を自分でパースして緯度経度を取得したりする方法が考えられる。手間だが、これを行えば、100件中10件ほどは位置情報がプロットできるツイートになる。

次に、検索結果は最大約1500件取得できるので、1ページあたり最大100件で、ページナンバーの値を1から15まで変えながら、つまり15回リクエストを発行すれば、位置情報がプロットできるツイート数を増やせるだろう。しかし、この場合はrate limiting(IPベースのリクエスト制限回数)をオーバーしないか、注意が必要だ。


2. 検索結果が必ずしも指定した条件に合致していない

検索条件にgeocode及び半径 N km と指定しても、指定条件に当てはまりそうにないツイートが検索結果に入ってくる。検索対象が日本のどこかの場合は、現住所に日本と書かれているユーザのツイートも検索結果に含むというのが、Twitter側の仕様のようだ。


3. 検索結果の並び順が指定できない

ツイート日の降順に検索結果は並んでいる。指定したgeocodeに近い順には並んでいないので、そのようなリストを作りたかったら自分でソートする必要がある。


4. 検索結果が安定しない

同じクエリーを投げても、検索するたびに検索結果が変わる。なぜだかは分からない。


結論としては、「TwitterのSearch APIで、指定した緯度経度から半径 N km内のツイートを全て取得する」 ことは、簡単ではないということだ。

rate limitingを上回らないように気をつけながら、独自のパーサーなども絡ませて位置情報をプロットできるツイート数を増やして、使っていくことになる。

rate limitingを気にしたくなければStreaming APIを使う手もあるが、それも決してバラ色の解決策ではないのだ。
明日に向かって昇龍拳: TwitterのStreaming APIでlocationsを指定する場合の注意点

2010年10月16日土曜日

TwitterのREST型Search APIを使う場合の注意点

TwitterのSearch APIを使う時は、以下の点に注意する。


1. ユーザ認証は不要

Search APIの利用には認証は必要ない。誰でもリクエストが可能。



2.rate limiting(IPベースの制限回数)がある

Rate Limiting | dev.twitter.com

ユーザ認証が要らず、アノニマスで接続できる分、1IPあたり1時間内に発行できるリクエスト回数が限られている

不必要な検索や荒らしを防ぐために、それが何回なのかは公開されていない。Search APIと同じくREST型のREST APIは1時間あたり150回だが、ちなみにそれよりは多いらしい。多くのアプリケーションでは十分ではなかろうかというくらい、とある。

Requests to the Search API, hosted on search.twitter.com, do not count towards the REST API limit. However, all requests coming from an IP address are applied to a Search Rate Limit. The Search Rate Limit isn't made public to discourage unnecessary search usage and abuse, but it is higher than the REST Rate Limit. We feel the Search Rate Limit is both liberal and sufficient for most applications and know that many application vendors have found it suitable for their needs.

でも気をつけないといけないのは、IPあたりという点だ。

Search APIを使った自分のプログラムのリクエスト以外にもTwitterのAPIを呼び出しているものがあれば、それもSearch APIの制限回数の中に含まれる。

つまり、何らかのTwitterクライアントを動かしていたり、他のサービスでTwitterのAPIを使っている場合は、それらもSearch APIの回数にカウントされるので、その分も考慮しないと、デバッグしているだけで制限回数をオーバーしかねない。

制限回数をオーバーするとHTTPステータスコード 420 がTwitterのサーバから返ってくる。

あまりにも制限回数を超えるような高負荷なリクエストを連続してTwitterへ送った場合は、ブラックリストに登録されることもある。ブラックリストに載ったかもと思ったらAPIサポートページに相談して解除を申請することになる。



3. User-Agentを含まないとリクエストの制限回数がより少なくなる

Search APIによるリクエストには、ユニークで識別可能なUser-Agentが含まれている必要がある。でないと制限回数はより少なくなってしまう。



4. 制限回数を増やすような相談は可能だが、まずは自分でやることやってから

REST APIにはホワイトリストがあり、申請が認められれば1時間あたり20,000回まで制限が緩和できる。
が、Search APIの場合は、まずは自分でパフォーマンスチューニングをしてください、と。もうこれ以上は無理だ!となった場合にしか、APIサポートページに相談してこないでね、とある。

There isn't a whitelist for the Search API in the same way there is for the REST API. However, under some rare circumstances we have worked with developers to raise rate limiting for their applications search requests.

We do not give preemptive whitelisting for the Search API though. You must have a working application that has proven it requires more capacity before we will discuss whitelisting. If you feel that your application is doing everything it can to limit and combine queries where appropriate you can contact the email address on the API support page to discuss your needs.

また、IPベースかユーザーアカウントベースでホワイトリストへの申請が可能なREST APIとは異なり、Search APIではIPベースしか認められていない。

制限回数がとてもシビアな問題な場合は、Streaming APIを使ってね、ということだ。

TwitterのStreaming APIでlocationsを指定する場合の注意点

TwitterのStreaming APIを使って、プッシュ型で位置情報付きのツイートを取得する時は、以下の点に注意する。


1. Geotagging APIを使用して作成され、且つ、追跡する対象領域内に位置するツイートだけが結果に含まれる

つまり、ユーザーのプロフィールにある現在地の情報はツイートのフィルターには使われない

もし、ユーザーがプロフィールの現在地に“San Francisco”と設定していても、そのツイートがGeotagging APIを使っていなくてgeo要素がなければ、検索結果のストリームには含まれない。

Only tweets that are both created using the Geotagging API and are placed from within a tracked bounding box will be included in the stream – the user’s location field is not used to filter tweets (e.g. if a user has their location set to “San Francisco”, but the tweet was not created using the Geotagging API and has no geo element, it will not be included in the stream).


2. 追跡する対象領域はカンマで区切った経度と緯度のペア指定

最初のペアは対象領域の南西の角を示す。
例えばlocations=-122.75,36.8,-121.75,37.8はサンフランシスコエリアのツイートを追跡する指定になる。

バウンディングボックス、つまり追跡する対象領域は複数の指定ができて最大25個まで可能。例えばlocations=-122.75,36.8,-121.75,37.8,-74,40,-73,41はサンフランシスコとニューヨーク市エリアのツイートを追跡する指定になる。

Bounding boxes are specified as a comma separate list of longitude/latitude pairs, with the first pair denoting the southwest corner of the box. For example locations=-122.75,36.8,-121.75,37.8 would track tweets from the San Francisco area. Multiple bounding boxes may be specified by concatenating latitude/longitude pairs, for example: locations=-122.75,36.8,-121.75,37.8,-74,40,-73,41 would track tweets from San Francisco and New York City.

(・・・)and you may specify up to 25 bounding boxes.


3. locationsの指定とtrackの指定の両方を行なうとOR検索になる

なんと、対象領域の指定が論理ORなのである。

よって、検索キーワードの指定(trackの指定)に「twitter」、追跡する対象領域(locationsの指定)に-122.75,36.8,-121.75,37.8を行なうと、 twitterを含むツイート(geo要素がないツイートでも)か、あるいはサンフランシスコエリアのツイートという条件を指定したことになる。

Bounding boxes are logical ORs. A locations parameter may be combined with track parameters, but note that all terms are logically ORd, so the query string track=twitter&locations=-122.75,36.8,-121.75,37.8 would match any tweets containing the term Twitter (even non-geo tweets) OR coming from the San Francisco area.


特に、1と3が問題だ。

3は、ドキュメントを読んでいて、「ちょっとちょっと~」とついつい突っ込みたくなった。なんでORなの?そこはANDでしょう。

しかし、Twitter側で実装していないのであれば、ストリームで送られてくる検索結果を自分でフィルタリングすればよいだけのこと。まあ、まだよい。


しかし、1の方は大きな障害になるかもしれない。

1は、Twitter側のアプローチとして考えると、正しい。位置情報で絞り込みたいので、位置情報を指定していないツイートは検索結果に含まれるべきではない。

但し、まだまだgeo要素を含んだツイートは少ない。geoがnullでないツイートに限ると、結果件数はとても寂しいものになるだろう。そんな状態でアプリケーションを作っても、ゴーストタウンのようになってしまうかもしれない。何らかの工夫が必要だ。

逆に、プロフィールの現在地をストリームで取得する方法があるのか調べてみたが、今のところストリーム系の3つのAPI、Streaming APIUser StreamsSite Streamsのどれにもそれらしい記述は見当たらない。


ところで、Streaming APIは、2010年8月31日からベーシック認証がdeprecatedになり、OAuthを使うこととなったので、それもチェックポイントだ。
Transitioning from Basic Auth to OAuth | dev.twitter.com

OAuthの具体的な使用方法は、ドキュメントをまだ詳しく読んでないので分からないが、のっけから、「Transitioning from Basic Authentication to OAuth isn't simple for everyone. (ベーシック認証からOAuthへ切り替えることはすべての人にとって簡単というわけではない)」とあるゾ。