Home

日記
デッドボールその後Edit

デッドボール跡 この間デッドボールが当たったところ周辺が、20×10センチくらい変な色に染まっていた。さすがに145km/hは威力があるなー。ようやく黙っている分には、痛みよりも表面のかゆみの方が強くなってきた。押すとまだまだ痛いけど。

Published At2006-06-07 00:00Updated At2006-06-07 00:00

日記
街区レベル位置情報+郵便番号データEdit

次期MM/Memoというか1470.netで、位置情報関連機能を強化しようと思って、まずは位置情報→住所、郵便番号→住所→位置情報とかが手軽に変換できるように、街区レベル位置参照情報郵便番号を合成してみている。

主データとしては、街区レベル位置参照情報の方を利用する。というのは、郵便番号の方は位置情報ではなく、郵便の都合で区分けされているんで、より位置情報のキーとして使いやすそうなのは街区レベル位置参照情報の方だから。

街区レベル位置参照情報は「丁目」よりも細かい「街区符号・地番」レベルの情報も持っているけれども、そこまで扱うと

  • 住所情報としてのセンシティブさが増しすぎる
  • 郵便番号情報との粒度の違いも大きくなりすぎる
  • AjaxとかでがんがんDBを叩くにはデータサイズが増えすぎるだろう

という理由で、データとしては「丁目」レベルまでを扱い、それ以下は切り捨てることにする。

で、まずは「都道府県」「市区町村」「町域(大字・町丁目)」「緯度」「経度」というデータを街区レベル位置参照情報からインポートして、位置情報テーブル(address)を作成する。

idprefecturecitycityarealatitudelongitude

※実際にはprefecture、city、cityareaも別テーブルに切り出している

最初、上記の位置情報テーブルに、郵便番号カラムを追加してやればいいかと思っていたんだけど、郵便番号は町域レベル以内でダブって登録されていたりすることも多い(同じビルの階数ごとに別の郵便番号が振られていたり)んで、別に郵便番号テーブル(zip)を作ることになった。

idzipcodeaddress_id

郵便番号データにも「都道府県」「市区町村」「町域」という情報があるので、それらが完全一致する場合は、その位置情報をセットすればいい。しかし、それで対応できるデータというのはかなり少ない。具体的には、

  1. 一つの郵便番号で市区町村レベルまでの範囲を受け持っている
  2. 一つの郵便番号で複数の町域(細かく指定)を受け持っている
  3. 街区レベル位置参照情報には存在しない市区町村に関する郵便番号がある
  4. 街区レベル位置参照情報には存在しない町域に関する郵便番号がある
  5. 町域レベルとして地名ではなく建物名などがセットされた郵便番号がある

などの例外の割合が非常に多い。

1の場合、位置参照情報の方では、基本的に町域レベルまで指定された位置情報を持っているので、市区町村レベルまでしか指定されない場合、その市区町村に所属する複数の位置情報のどれを代表として使用するのが妥当なのかという判断が、機械的にはできない。けれども、ひとまずはデータ上最初に出てきたものをセットしてみた。つまり、このようにしてセットした行については、位置情報を調整する(市区町村レベルの中心に近い町域を指定する)必要があるかもしれない。

2の場合、郵便番号データの町域情報では、そのような複数の町域指定を「町域共通部(町域1、町域2)」のような形式で指定しているようなので、ひとまず「(」の前までの町域共通部を利用して、そこまでマッチする位置情報が存在した場合は、その位置情報として登録するようにした。これは1と同様の問題があり得る。

3に関しては想定外だったが、街区レベル位置情報では網羅されていない市区町村というものが思いのほかたくさんあった。これらは、

  • 単に街区レベル位置参照情報データには、掲載されなかった市区町村
  • 新しくできた・合併した・改名された市区町村

などだろうか。特に地方(北海道や沖縄など)で目立つようだ。これらのデータに関しては、本来addressテーブルレベルで何らかの対応をするべきだろう(既登録データの修正もしくは新規登録など)が、その際には郵便番号データにしか存在しない市区町村データに関して、一件ごとの具体的な対応の検討等も必要になるため、現在は未対応(zip.zipcodeは登録したがzip.addressはnull)である。

4に関しては、ひとまず街区レベルの情報は無視して、1と同様の対応を行った。これは1と同様の問題があると同時に、場合によっては3と同様にaddressテーブルレベルでの対応も行うべきだろう。新規にaddressテーブルに追加する場合は、独自に位置情報データ用意する必要がある。

5に関しては、2と同じような対応を行っているが、2よりもずれが大きい可能性が高い。というのは、基本的に文字列一致で処理を行っている都合上、街区レベル位置参照情報データと郵便番号データの二つで、町域レベルでの指定よりも建物レベルの指定の方が、その表記のずれが大きい可能性が高いからだ。これらも最終的にはデータ一つ一つに対しての検討が必要だ。

と、いろいろ問題はあるけれども、機械的に合成したデータでもそれなりに使えることは使えるようだ。このデータベースに対して、Wikiみたいに誰でも自由に位置情報の詳細を登録・修正できるインターフェースを用意してアップデートをかけていくと良さそうな気がするんだけど、それを実現するためにはいろいろ考えなければならないことがありそうなんで、ひとまずは機械的に作成したバージョンを公開しておく。

あと、それを使って作ってみたGoogle Mapsとの連動サンプルも。こちらはそのうち消える(というか1470.netのリニューアルバージョンの一部として再構成される)だろうけど。一応Firefoxでは一通り動くはず。Opera 8でも大丈夫っぽい。IEだと微妙に動作が怪しい(selectの自動生成周りの互換性が怪しい)けど、まあその辺は後々の課題ってことで。Google Mapsを使っているんでJavaScript必須ね。

4のパターンは

漢字表記が違うというのもあるらしい。「杉並区堀ノ内」が「杉並区堀之内」になっていたり。どっちが正しいんだろう? っつーか地名表記漢字に「公式」ってのはあるのかな?

作ったとたんに

たたみラボ: GoogleがGeocodingAPIリリース!なんて話が……。

Published At2006-06-13 00:00Updated At2006-06-13 00:00

日記
アルファな人のRSSは直接購読しないEdit

アルファな人たちの情報を追いかけていると、ネタの幅と深さを同時に追求してしまうことになりがちだし、しかも情報の鮮度が高い分、興味を持ったときに自分で調べるコストも高くなりがち。そこでアルファな人たちのRSSを直接購読するのはやめ、アルファな人たちのRSSを直接購読している人たちのRSS(二次情報RSS)だけを購読するようにする。すると、ほどよいフィルタリングで取捨選択されたネタに関して、初めから必要な情報がうまくまとめられた段階で接することになり、情報収集が効率化する。

という夢を見た。

目が覚めたら、現実はどうだったかを知りたいところ。

Bloglinesの左フレームに「(200)」が並んでますが、なにか?

Published At2006-06-14 00:00Updated At2006-06-14 00:00

日記
アルファな人のRSSは直接購読しない 実践編Edit

アルファな人のRSSは直接購読しないは単に思いつきネタで、全然実践する気もない話なんだけど、なんかマジレス気味なコメント(ブクマ)が多い気がするんで、その辺対策を真面目に考えてみる。

基本的には、RSSはすべて購読する。ただしまめにチェックしている暇はないんで、未読管理数制限があると困る(Bloglinesの200だと間に合わない)。で、一般的なRSSリーダーの機能は一通りありつつ、次の機能を追加する。

それは、未読記事の中から注目された記事だけを抽出して、まとめ読みができるモード。注目記事ってのは、はてなブックマークみたいなSBSとか、あるいはtechnoratiのランキングとか、あたりから適当に引っ張ってきてURLマッチさせれば十分。そのモードで読んだ記事もちゃんと既読になって未読数は減る。

すると、未読を全部読まなくても、未読のうちの重要な記事だけを先行してチェックできることになるし、その分の未読数もちゃんと消化できる。まあなんて便利。

はてなRSSなんかだったら、すでにエントリー抽出SQLではてブ被ブクマ数(bookmarkcount)も持っているみたいだから、未読記事を被ブクマ数逆順でソートして表示(where bookmarkcount > [threshold] order by bookmarkcount desc)するだけだし、実装は簡単だよね。ちょちょいっとつけてみる気はないかい。その機能が載ったら、個人カスタマイズできるはてブのフィルターとして使えて便利そうだ。

あらかじめ言っておこう

それPla禁止。

Published At2006-06-14 00:00Updated At2006-06-14 00:00

日記
駅の位置情報Edit

国土数値情報ダウンロードサービスで配布されている鉄道の数値情報を元に、路線+駅+位置(緯度・経度)情報を抽出しようと思ったんだけど、位置情報は扱いが難しいなー。データと仕様を見ても、しばらく何がなんだかわからなかった。けれども、しばらく見ているうちにようやく意味が理解できたんで、コンバートしてみた。が、いくつか問題があった。

駅ノードの属性番号と同一のメッシュコード+番号を含むラインデータ(=路線)がある場合は、その駅はその路線に所属している、というロジックでデータを抽出してみたんだけど、

  • どの路線にも所属しない駅が発生する
  • 複数路線に所属するはずの駅でも、一つの路線(基本的にはJR)にしか所属しない

ということになった。前者はデータ欠けを埋めていくだけだから、多少量が多くてもマンパワーをかければ埋まっていくと思うけれども、後者は難しいなー。複数乗り入れ駅(乗り入れ路線数付き)の一覧データとかがないと、マンパワーをかけたところでデータの埋まり具合がさっぱりわからない。でもまあマンパワーをかけつつ地道に埋めていくしかないのかな。どこかに複数乗り入れ駅一覧データをもったてっちゃんはいねが。

その他表記の揺らぎがあるとか、データが古いんで駅名とか路線名とかが最新の情報に追随していないとか、微妙な問題は他にもあるけれども、そっちはまあひとまず置いておいてもいいかな。

これももうちょいまとまったら公開しつつ、オープンな形で完成度を高めていく方策を考えよう。

Published At2006-06-14 00:00Updated At2006-06-14 00:00

日記
リニューアル後の検索周りのサンプルEdit

ひとまずAmazon検索で実装してみたけど、

/search/[type]/[query]?[その他パラメータ]

というURI構成で表現しきれるだろうか?

あとAllowEncodedSlashes周りでちょっとはまった。っつーかAllowEncodedSlashes Onにしても%2Fを含むURLのrewriteが通らないんだけど、情報が古いんだろうか? まあコードレベルで対応できそうだからさして重要じゃないんだけど。

Published At2006-06-15 00:00Updated At2006-06-15 00:00

日記
駅の位置情報 初版公開Edit

ひとまず機械的に作ったものにちょっとだけ手を加えた(コンバート中に気づいた元データの間違いらしい部分を修正+所属路線不明の駅を手作業でいくつか登録)ものを公開。これでもそれなりに使い物にはなるけれども、まだ完全にはほど遠い。

まず、データコンバート中に気がついたんだけど、元データにわずかながらバグが混ざっている模様(一つは配布元に報告済み)。データの不整合を起こすようなデータならば、わかりやすいんだけど、もしもコンバート上は問題ないけれども、意味的には間違っているデータが混在していた場合、それらを修正する必要がある。あと、私がコンバート作業中に持ち込んでしまったバグも混ざっている可能性がある。

続いて、missing.txtに列挙してある、機械的なコンバートでは所属路線が一つも登録されなかった駅(700件弱)について、その所属路線を確定する(railway_stationに追加)する必要がある。ちなみに手作業でいくつかやってみたけれども、

  • 同名の駅が複数ある場合に、正しい情報を特定するのがちょっと難しい
  • 駅や路線の統廃合、改名などによって現状には即していない内容があり得る

という話があって、扱いは結構微妙。特に後者の場合、路線情報のレベルからデータの整合性を取り直す必要が出てくる可能性がある。が、ひとまず路線情報は現状のものを生きとして、それに駅情報を一通り合わせるところからはじめようかと思っている。

また、現状のデータでは一つの駅は一つの路線にしか所属していない。が、実際には複数路線が乗り入れている駅が多々ある。そのようなデータについて、路線−駅リンクテーブル(railway_station)に追加していく必要がある。

また、現在路線−駅リンクテーブルには元データに登録されていた順序で駅を登録していっているんで、それなりに路線上の駅順に近い並びで駅が登録されているけれども、上記のような作業を行っていくうちに並び順がどんどんおかしくなっていくはず。

路線−駅リンクテーブルには、路線単位での駅順序ソートキー(station_order)を用意しているんで、一通りデータがそろった段階で、そのソートキーを使って駅順序を正しく指定できるようにしてやる必要がある。

と、完成度を高めるにはまだ作業が必要な感じだけれども、ひとまずサンプルアプリで適当な場所に移動してから、[現在地の最寄り駅に移動]で最寄り駅に移動していると、何となく楽しいんで、試してみてくださいな。

Published At2006-06-15 00:00Updated At2006-06-15 00:00

日記
違いが分からないEdit

はてな認証APIで返されるJSON形式のデータをZend_Json(のSubversion上の最新版)でデコードしようとするとエラーが出る。調べた結果、Zend_Json_Decorder::_eatWhitespace

'/(\t|\b|\f|\n|\r| )*/s'

という正規表現を、

'/[\t\b\f\n\r ]*/s'

に変えると正しく動作する(前者だとホワイトスペース除去がうまく動作しないせいで、Illegal Tokenになる)んだけど、その理由がわからない。

Published At2006-06-15 00:00Updated At2006-06-15 00:00

日記
有効範囲指定付きチケットを使ったAPIEdit

リニューアル後は、Bookeyみたいなツールからの利用がやりやすいように、ちゃんとしたAPIを作る予定。

うちの場合は、外部認証サービスを利用しているんで、自前でパスワード的なものは持っていない。けれども、API用の認証を行うならば、やっぱりそれ的なものが必要になるだろう。だから、API専用の認証キーをランダム発行(ランダム再発行可能)し、それをAPI専用に使う(非ランダムなパスワード文字列は持たない)。

うちはSSLは使わないつもりなんで、毎回認証キーを流すのは気持ち悪い。だから認証キーを使って期限が短いチケットを発行させ、そのチケットを使ってAPIへのリクエストを行う形式を採用する。

チケット発行APIに、ユーザーID、認証キー、オプションパラメータを投げると、チケットIDが返される。オプションパラメータでそのチケットの有効範囲を指定する。

有効範囲ってのは、

  • 利用回数(無制限可)
  • 有効期限(必須。デフォルト値あり)
  • 利用可能なAPI(指定した場合)
  • 環境チェック(有効な場合、チケット発行時と同一のIPアドレス、ユーザーエージェントからのリクエストのみ許可)

あたりをイメージしている。

使う側で利便性とセキュリティのバランスを考えて、チケットを発行して使ってね、って感じ。

こういうチケットの仕組みって、どこかで使っているところあるかな? Flickrはread/write権限とか持っているみたいだけど、有効期限とか呼び出し回数のコントロールも可能なんだろうか(調べてない)。あるいはチケットにあまり機能を持たせると、負荷的に不利だからあまり採用されていない、とかあるのかも。まあ試してみよう。

ちなみにこの仕組みは非Webアプリからの利用しか考えていない。Webアプリ(第3者管理サーバー)でコールバックを使った認証委譲を利用したい場合は、その部分を別途考える必要がある(けど、多分そこまで作らない)。

っつーかその場合、外部Webアプリ → うちのサーバー → 外部認証サーバー(TypeKeyとか) → うちのサーバー → 外部Webアプリ って流れになるのか。なかなかわけわからない仕組みになりそうだな。

Published At2006-06-16 00:00Updated At2006-06-16 00:00

日記
検索条件の指定方法Edit

andで複数条件をつないで指定する際に、わざわざ

$db = $table->getDbAdapter();
$table->fetchAll(array(
$db->quoteInto('foo = ?', $foo),
$db->quoteInto('bar > ?', $bar),
));

みたいな書き方をしていたけど、

$table->fetchAll(array(
'foo = ?' => $foo,
'bar > ?' => $bar,
));

で良かったのか。

Published At2006-06-18 00:00Updated At2006-06-18 00:00