kaz_29@はてな

2011-12-14

CakePHP2+PostgreSQLでGeoデータを簡単に扱う!?

| 20:35 |  CakePHP2+PostgreSQLでGeoデータを簡単に扱う!?を含むブックマーク

@tkengoさんから引き続き CakePHP Advent Calendar 14日目の記事です。

深く考えず参加申し込みをしたらダブルヘッダーになってしまいヒーヒー言っているわたなべです(^^;

この記事はCakePHP2系の記事です。


明日にはこんなイベントも開催されるようで、最近は位置情報を扱う機会も多いのではないかと思います。

先月くらいに位置情報に関して色々試していて、CakePHPから扱う場合にいつもと同じように扱いたいなぁということでPostgres Datasourceを拡張してみたので解説したいと思います。


PostgreSQLで扱える位置情報の種類

PostgreSQLで扱える位置情報関連のデータ型には以下のようなものがあります。

型名 表現
point平面における座標点
line無限の直線
lseg有限の線分
box 矩形
path 閉経路
path開経路
polygon 多角形
circle

幾何データ型

今回は携帯での位置情報を簡単に扱えるようにという目標なのでこの中からデータ型としては 'point'型と'box'型のサポートをしました。

位置情報関連の演算子

下記のマニュアルページを見ていただければ分かる通り、たくさんの演算子がサポートされています。

幾何データ演算子

今回はこの中から以下の演算子をサポートを追加しました。

演算子説明
@含む、または境界上
~=同等か?
<->距離

スキーマ定義

今回の追加機能のテスト用に作成したFixtureは下記になります。

<?php
class PostgresGeoFixture extends CakeTestFixture {

/**
 * name property
 *
 * @var string 'PostgresGeo'
 */
	public $name = 'PostgresGeo';

/**
 * fields property
 *
 * @var array
 */
	public $fields = array(
		'id' => array('type' => 'integer', 'key' => 'primary'),
		'loc' => array('type' => 'point', 'null' => false),
		'rect' => array('type' => 'box', 'null' => false),
	);
}

point型の locとbox型の rect フィールドを作成しています。

使い方

データを保存する場合は、以下の様に座標データを配列形式で設定すればOKです。

box型の場合は左上の座標と、右下の座標を配列で渡します。

<?php

$data = array(
  'loc'	 => array(10.1,10.1),
  'rect' => array(array(10.1,10.2), array(100.1,100.2)),
);

$Model->create();
$Model->set($data);
$result = $Model->save();

特定の円の中に含まれているデータを検索する場合はこんな感じです。

<?php
// @ operator
// compare to circle
$conditions = array(
  'loc @' => array('circle' => array('point'=> array(10.1,10.1), 100)),
);
// order by distance
$order = array(
  'loc <-> point(10.1,10.1)'
);

$result = $model->find('all', array('conditions'=>$conditions, 'order'=>$order));

この例では中心座標 10.1,10.1、半径100の範囲内に含まれるデータが取得できます。また、<->演算子で並べ替えることで、中心座標に近い順に並べ替えることが可能です。

Postgresデータソースのテストを書いてあるのでそちらも見ていただけると、もう少しイメージが湧くかと思います。

誤算

当初この修正を始めたときは、PostgreSQLデータソース内部ですべて解決できそうな気がした(^^; ので、CakePHP2をforkして作業を始めたのですが、実際に作業を進めて見た結果、DboSource(データベース関連データソースの共通クラス)にも手を入れないと実現ができませんでした。

さすがにDatasource固有の演算子サポートのためにDboSourceに手を入れる修正はコアに取り込んでもらえないなぁと思い、今後この機能をプラグイン化できないか調査をしているところです。

実際に動くコードは、GitHubに上がっているのでもし興味がある方は試してみてください。結構便利だと思いますよ。

明日は @scriptwork さんです。よろしくお願いします!

zinniaでお手軽手書き文字認識

| 14:44 |  zinniaでお手軽手書き文字認識を含むブックマーク

@haoyayoi さんから引き続き iOS Advent Calendar 14日目の記事です。

アプリ自体はまだ2本しか出していないわたなべです。

iOS Advent Calendar はそうそうたるメンバーがとても参考になる記事を書かれているのでいろいろ勉強させてもらってます(><)!

こんな私ですが、@k_katsumiさんに背中を押されたので、最近試している手書き文字認識エンジン zinniaについて書いてみます

zinnia ってなに?

zinnia は Taku Kudoさんが作成された「手書き文字認識エンジン」です。このエンジンに文字のストローク座標の連続データを渡すことで、高速に文字を認識することができます。確からしさ順にN個の結果を取得することができるので、変換候補を表示したりも出来ます。


iPhone上で動かすには...

@FLCLjp さんが作成されたサンプルが Githubで公開されているのでそれを見るのが一番だと思います。

実際に動かしてみると以下のようにしっかり認識できるはずです。


f:id:kaz_29:20111214124235p:image:w360

で、これだけだと全く中身がない話になってしまうので(^^; もう少し書きますよ〜。


認識率は...

zinniaのサイト上で配布されれいる 認識用モデルファイル(Zinnia-Tomoe) を使って試用した感じではかなり認識率は高いと思います。ただ画数の少ない文字はどうしても正しく認識してくれないケースが多かったです。まぁ、仕方が無いですね。

ですが、特定の文字種に限って(たとえば数字だけとか...)認識できればいいのであれば、自前で認識用モデルファイルを作ってしまえばかなり認識率を高めることはできそうです。

実際、私を含め身近な数人に数字のストロークを入力してもらい作成した認識用モデルファイルを使うと、ほぼ100%に近い確率で認識できました!


認識用モデルファイル

認識用モデルファイルはS式で記述された学習データを元に、zinnia付属のコマンドで作成します。公式ページにも記述がありますが実際の形式は以下のような形式です。

S式フォーマット

(character
 (value 認識したい文字)
 (width キャンバス幅)
 (height キャンバス高さ)
 (strokes
   ((0画目x 0画目y) ... (0画目x 0画目y))
   ((1画目x 0画目y) ... (1画目x 1画目y))
   ((2画目x 2画目y) ... (2画目x 2画目y))
   ...))

フォーマット自体はとてもシンプルなのですが、このデータを作るには実際に認識させるデバイス上で文字のストローク情報を集める必要があります。おそらくzinniaを使っている方はみんな何らかの文字収集ツールを書いてるんじゃないかなぁと思います。


ということで、自分用にiPhoneで動作するアプリを書いたので解説します。

手書きストローク収集ツール(TegakiStroke)

iPhone-Zinnia-TegakiStroke@GitHub


もともと自分用に収集アプリを書いていたのですが、不特定多数の人のストロークを集めたかったので、データをサーバーに上げる方式で作っていました。これだとお手軽に試してもらうわけにはいかないので、すべてのデータをローカルなsqlitedbに保存する形で作り直しました。テーブル構成は以下のようなとても簡単な作りになっているので、、付属のtemplate.dbを覗いてもらえればわかるかと思います。

モデル情報(models) => モデルに含まれる文字情報(characters) => 実際のストローク情報(strokes)

以下がschema構築用のsqlファイルです。

CREATE TABLE models (
id INTEGER PRIMARY KEY,
name TEXT,
created
);

CREATE TABLE characters (
id INTEGER PRIMARY KEY,
model_id INTEGER,
character TEXT,
created
);

CREATE TABLE strokes (
id INTEGER PRIMARY KEY,
character_id INTEGER,
strokes TEXT,
created
);

INSERT INTO models (name,created) values ('number', '2011/12/13');

INSERT INTO characters(model_id,character, created) values(1,'0','2011/12/13');
INSERT INTO characters(model_id,character, created) values(1,'1','2011/12/13');
... 以下略

実際の動作は...

まず入力するモデルを選んで...

f:id:kaz_29:20111214141228p:image:w360

「文字入力」ボタンを押して....

f:id:kaz_29:20111214141229p:image:w360


実際に文字を入力します....

f:id:kaz_29:20111214141230p:image:w360


登録されている文字の入力が終わると、文字一覧に戻ってくるので「S式書出し」ボタンを押せば完了です。

f:id:kaz_29:20111214141229p:image:w360


書きだしたデータは、Documentsフォルダに保存されていますのでiTunes ファイル共有か何かで取り出してください。


f:id:kaz_29:20111214141231p:image:w360


吐き出された、*.sファイルをzinnia付属の zinnia_learn にかければ実際に使えるモデルファイルが出来上がります。

またアプリ内部で使用している sqliteのファイルもDocumentsフォルダに保存してあるので、適宜モデルや文字を追加するなり、自前でstrokeデータを抜き出して加工するなり、いろいろできるのではないかと思います。


まとめ

zinniaを使うと非常に簡単に手書き文字認識を実装できます。実際のアプリで使うには色々と工夫が必要かと思いますが...。

ソースはGitHubに上げてありますので、試してみてください!

若干やっつけ感が漂っているところもありますが(^^; 、時間ができたら機能を追加していこうと思ってます。

明日は @hIDDEN_xv さんです!

it-executive-searchit-executive-search 2012/09/05 08:42 はじめまして、
人材紹介会社株式会社キープレイヤーズ社長室の山内と申します。

唐突なお話で大変恐縮ですが、

弊社のクライアントの
大手インターネット企業が、
貴殿のブログ見まして、非常に興味を持っていまして、
ご紹介できればと思っております。

もし差し支えなければ、
一度メール等でやり取りさせていただくことは可能でしょうか?

突然のご連絡で恐縮ではございますが、
何卒よろしくお願いいたします。

トラックバック - http://d.hatena.ne.jp/kaz_29/20111214

2011-10-03

PHP Matsuriに参加しよう!

| 19:52 |  PHP Matsuriに参加しよう!を含むブックマーク

色々ばったばったしているわたなべです。

このエントリーは、10/15-16に大阪で開催されるPHP Matsuriリレーブログエントリーです!

http://2011.phpmatsuri.net/

まだ若干の余裕はありますが、急がないと埋まってしまう可能性もあるので後悔したくない人は今すぐ申し込んでしまいましょう!

私は昨年のPHP Matsuriにも参加したのですが、私が感じたこうしたら楽しめた(はず)!という内容を書きたいと思います。

作るものをある程度考えておく

f:id:kaz_29:20101002093601j:image

当日は興味深いセッションワークショップが盛りだくさんなので、以外にハックの時間がとれないかもしれません。当日作るもの/やる事をある程度考えて事前準備をしておくと良いと思います。開発環境も準備出来る方は事前に準備しておくのも良いと思いますが、期間中に使用可能なインスタンススポンサーさんが貸してくれるとの話もある様なので、環境構築も周りのみんなの構築方法とかを聞きながら色々試すのも面白いと思います。

食事タイムにも交流

f:id:kaz_29:20111003190735j:image

photo by @ichikaway

期間中は、参加者/ゲスト全員で食事をする機会が4回あります。この食事時間も絶好の交流のチャンスです。気になるゲストのそばに陣取るのもいいですね。また、気になる参加者やスタッフをポジションペーパーでチェックして一緒に食事をとるのも楽しいと思いますよ!

疲れたら休憩にして動き回る

f:id:kaz_29:20111003191052j:image

photo by @ichikaway

講演/ワークショップ/ハックに疲れたら、少し休憩にしてうろうろしてみると面白いと思います。昨年は深夜にいきなりゲーム大会が始まったり、ビール片手に海外ゲストと談笑する人、喫煙スペースで延々開発談義をしている方とかもいました。

遅い時間になるとあちこちで「プシュ!」とビールの空く音が....!お酒が飲める人も飲めない人もあちこちで会話に花が咲いていると思います。興味のありそうな話が聞こえたらがんがん捕まえて交流する事をお勧めします。

英語は怖くない!?

f:id:kaz_29:20101002205231j:image

英語は思っているほど怖くありません。中学生レベルの英語で十分コミュニケーションはとれます。別にとって食われる事はないので、海外ゲストにもガンガン話しかけてみましょう。世界が広がるはずです。

と、英語をしゃべれる人にいつも言われているので、私も今回はがんばろうと思います(^^;。

やった事を発表する

f:id:kaz_29:20111003194009j:image

photo by @ichikaway

2日目の午後は参加者それぞれの成果をLT形式で発表する時間になります。「自分が作ったものなんてたいした事無いし...」とか「まだ未完成だから...」とか色々あって躊躇する人も多いとおもいますがそんな人は、@shin1x1さんの勉強会を楽しむなら発表しよう!を読んでみましょう!ここに書かれている、

「君の当たり前に僕らは感嘆させられるんだ」

は本当にその通りだと思います。発表する事で広がるものが絶対にあります!すてきな商品もある様なので、是非!

まとめ

という事でつらつらと書いてきましたが、PHP Matsuriは楽しいので是非参加してみんなでハックして交流しましょう!という事です。さあ、皆さん申し込みましょう!

明日は、上でも紹介した@shin1x1さんです、よろしくお願いしますー!

2011-08-17

candycaneをPostgreSQLにも対応させたい!

| 00:19 |  candycaneをPostgreSQLにも対応させたい!を含むブックマーク

昨日の夜に社内用 redmineアップデートしていたのですが、まだCakePHPgitも覚えたての頃に、CakePHP開発合宿に参加して開発したのを思いだしたのか、急に candycane が気になったので、ちょっといじってみる事にしました。

まずは手始めに、手持ちのMacPHP+MySQL環境にインストールしてみたのですが、まぁこれが超絶簡単。@yandoさんも書いていますが、本当に3分程度でインストールが完了してしまいました。


f:id:kaz_29:20110817232500p:image


いよいよPostgreSQLに対応する作業ですが、実際にやった作業は以下のような感じ。

とこんな感じです。途中、schema生成時にエラーが出てはまったのですがこれはcandycane開発当初にはまだリリースされていなかったPostgreSQL9.xに依存する問題だったので、CakePHP1.3.10CakePHP1.3.5で対応されたもの組み込んで対応しました。

以下が実際のインストーラスクリーンショットです。

f:id:kaz_29:20110817235238p:image

インストール完了後に Administration -> informationをみるとこんな感じ。

f:id:kaz_29:20110817235239p:image

ひとまず、無事PostgreSQLで動作させる事ができました。

実際にはいくつかの機能で正常に動作しない部分や、テストが通らない所があるので今後ちょっとづつ手を入れていこうと思ってます。

ソースはgithubにあげてあります

トラックバック - http://d.hatena.ne.jp/kaz_29/20110817

2011-04-11

電力使用量を表示するアプリを作りました

| 10:48 |  電力使用量を表示するアプリを作りましたを含むブックマーク

先週金曜日(4/8)、計画停電の「原則不実施」の発表日という絶妙のタイミング(^^; でしたが東京電力管内の電力使用量を表示する「電力グラフ」というアプリをリリースしました。

電力使用量を取得するAPIが続々リリースされ始めた3/24頃に、こんな事をつぶやいていたら@basukeにケツ叩かれたので作ってみました(^^;

グラフの描画は s7graphview を使わせてもらっています。また、通信関係の処理は three20 を使っています。

この2つのライブラリのおかげで比較的サクッと作れました。

f:id:kaz_29:20110411102352p:image

主な機能はこんな感じです。

  • 過去7日分の電力使用状況の表示
  • 計画停電の実施状況の閲覧(当日から3日間)
  • 電力/節電に関連する情報の表示
  • 電力/節電に関連するリンク集

使用している情報は下記のAPIを使用しています。

計画停電のスケジュールは東京電力の発表しているデータを元に独自で作成したデータを使っています。この情報はAmazon S3上においてあったりします。

原則的に計画停電は実施されない事になった様ですが、これから夏にかけて電力が不足する事は変わらないと思うので、節電のお供に使って頂ければと思います。

ダウンロードこちら

*「電力グラフ」で使用している情報は、東京電力の発表に基づき情報を更新しておりますが、反映には時間差が生じます。 最新の情報は東京電力のサイト等でご確認ください。

トラックバック - http://d.hatena.ne.jp/kaz_29/20110411

2011-03-26

iPhone用のスタティックライブラリを統合

| 10:36 |  iPhone用のスタティックライブラリを統合を含むブックマーク

頻繁にやる作業ではないからかいつも忘れてしまうのでメモ。

iPhoneで外部ライブラリを使う場合、シミュレータ用とデバイス用と2種類用意しないといけないのですが、lipoコマンドを使って両方に対応したライブラリを用意します。

下記が使用方法です。

lipo -create \
    foo/Build/Debug-iphonesimulator/libBar.a \
    foo/Build/Release-iphoneos/libBar.a \
    -output \
    foo/lib/libBar.a
トラックバック - http://d.hatena.ne.jp/kaz_29/20110326