PostGISを触ってみた

ここしばらく就職活動していて色々と余裕が無かったのですが、先日無事に仕事を頂く事ができまして、7月から働き始める事と相成りました。*1 そんな訳で、またぼちぼちとブログも書いていこうと思います。

今回のネタは、先月発売のWEB+DB PRESS Vol.57を読んでいて、ちょっと興味をそそられたPostGISについてです。

WEB+DB PRESS Vol.57

WEB+DB PRESS Vol.57

PostGISのインストールと市区町村境界データのインポートに関しては、"PostGISRailsによる位置情報iPhoneサイト"という記事をそのまま遂行しただけなので、ここでは省略…。

今回は、2つの地点の緯度と経度を与えると、2点間の距離を返すBEARリソースを作ってみました。

<?php
class App_Ro_Distance extends App_Ro
{
    protected $_table = 'areas';

    public function onInject (  )
    {
        parent::onInject();
    }

    /**
     * リソース読み込み
     *
     * @required lat1
     * @required lon1
     * @required lat2
     * @required lon2
     */
    public function onRead($values)
    {
        assert(isset($values['lat1']));
        assert(isset($values['lon1']));
        assert(isset($values['lat2']));
        assert(isset($values['lon2']));
        $sql = "SELECT ST_Distance (";
        $sql.= " ST_Transform(ST_GeomFromText(";
        $sql.= "  'POINT({$values['lat1']} {$values['lon1']})', 4326) ,2451),";
        $sql.= " ST_Transform(ST_GeomFromText(";
        $sql.= "  'POINT({$values['lat2']} {$values['lon2']})', 4326), 2451)";
        $sql.= " ) AS distance";
        $distance = $this->_db->queryOne($sql);
        $result = array('distance' => $distance);
        return $result;
    }
}
?>

これを使って、記事の中でサンプルとして挙げられていた、渋谷と札幌の距離を求めてみます。

$ bear read "Distance?lat1=139.716911&lon1=35.647401&lat2=141.35358861111&lon2=43.062555"
code
200
header
n/a
body
array (
  'distance' => '835162.846670699',
)

ちゃんと算出できました! 実にさっくりとこんな計算ができて面白いですね。

地図情報って何かと面白い事に使えそうな予感もするので、もうちょっと研究してみようかなと思います。

今回はとりあえずPostGISに触ってみたところまで…。次回は別の情報と組み合わせたりして、何かやってみようかなと思っています。

*1:就職活動中、面接などでお世話になった方々に御礼申し上げます。

ひらがなをTAS語画像に変換するWebサービスを作ってみた

何だかTAS語っていうのが面白そうだったので、画像変換のWebサービスを作ってみました。

TAS語ジェネレーター

TAS語については、以下の動画を見てもらうと分かって頂けるかと思います。
D

試しにという事で、「たすごじぇねれぇたぁ」だと以下のような感じに…。

何ともカオスっぷりが素敵な感じです。(笑)

あいかわらず、いったい何の役に立つWebサービスなのか不明ではありますが、ぜひ遊んでみて下さいね〜。

Webサイトやブログの文章を元に四字熟語を自動生成するサービスを作ってみた

今回は、今北シリーズ(?)の第2弾として四字熟語バージョンを作ってみました。

今北四字熟語

これは何?

「今来た私にサイトの内容を四字熟語で教えて下さい」的なサービスです。

URLを入力して"作成する"ボタンを押すと、該当サイトの内容を元に四字熟語を自動生成してくれます。

試しにこのブログで試してみたところ、こんな四字熟語になりました。
作事思表
これは、「作る事は思想を表す事だ」という意味です。(勝手に解釈) 自分の中で、Webエンジニアとして何かを作って公開する事は、そのまま自身の実力だったり考え方だったりを表現する事だと思っているので、この四字熟語は適当にできたにしては案外良くできている感じがして気に入っています。

ちなみに、今北川柳では色紙に書いたっぽい画像を生成するようにしていたんですが、今回は家訓的なモノをイメージして、巻物に書いた感じの画像にしてみました。

「○○のブログ訓」みたいな感じでブログパーツとして画像を貼ってもらったりすると結構面白いかもしれないですね。

どんな仕組みなの?

コア部分の仕組みとしては、該当URLのサイト内容を読み込んで、漢字だけを抜き出して数をカウントして、多く使われている順に4つ並べているだけです。

一番最初にテストで書いたコードは以下の通り。

<?php
$body = file_get_contents('http://d.hatena.ne.jp/stellaqua/');
$body = mb_convert_encoding($body, 'utf-8', 'euc-jp');
preg_match_all('/[一-龠]/u', $body, $matches);
$results = $matches[0];
$results = array_count_values($results);
natsort($results);
$results = array_reverse($results);
$results = array_slice($results, 0, 4);
var_dump($results);
?>

ロジック部分は、これがベースになっていて、後は今北川柳から色々流用して作っています。

array_count_valuesとかあんまり使った事なかったんですが、なかなか便利で色々使えそうですね。

こんな感じで、サイトの内容をごにょごにょして何かしらの形として自動生成するというのは、他にも応用が利きそうなので、また"今北シリーズ"として色々考えてみたいと思います。


そんな訳で、ぜひ遊んでみて下さいね〜。

Ctrl+Aで反転すると画像が浮かび上がるジェネレータを作ってみた

何か「Ctrl+Aするとスゴイ!」ってページが話題になっていたので作ってみました。

画像が浮かび上がる文章ジェネレータ

どうせなら日本語の方がよかろうと思って、青空文庫から"吾輩は猫である"の文章を引っ張ってきました。デフォルトで猫画像が埋め込まれているので、Ctrl+Aすると猫が浮かび上がってきます。

ちなみに、もうちょっと早く作って1番乗りを目指したかったんですが、やっぱり先を越されちゃってましたね。(^^;

Select Art - 選択反転すると画像が出てくるジェネレータ

他にも既に作った人とかいるかもしれないですね〜。

ま、とりあえずサクッと作ってみたので、公開しておきたいと思います。

"オセロを1時間で作ってみた"の中の人がWEB+DB PRESSの特集の中の人と同一人物だった

以前、ニコニコ動画でプログラミング実況というのをやっている動画をご紹介しました。

1時間でオセロを作る動画が面白い - Stellaqua - TOMの技術日記

当ブログでは書かなかったんですが、その後、ITProさんでこの動画の事が取り上げられていて、作者さんのインタビューが載っているのを見つけて、「やっぱりすごい人だったんだなぁ。」とか、こっそり思ってたりしました。

「テトリスを1時間強で作ってみた」動画の投稿者にインタビュー──「プログラミングの楽しさ伝えたい」 | 日経 xTECH(クロステック)

これが昨年終わり頃のものなので、すっかり記憶から薄れていたんですが…先月発売のWEB+DB PRESS Vol.56をペラペラ眺めていたところ、何となく既視感が…。

WEB+DB PRESS Vol.56

WEB+DB PRESS Vol.56

特集2の"はじめの一歩が見えてくる プログラミング一部始終"という記事の雰囲気が何とも、ニコニコ動画でのプログラミング実況と似ている…と思っていたら、やっぱり同じ人が書いた記事でした!

紙面での記事なので、当然動画でのおしゃべり以上に、どんな事を考えながらプログラミングしているのかが分かって、非常に参考になりました。記事の中で、さらっと"砦の攻防"なんて単語が書かれているのを見て、私もベーマガで育った身として思わずニヤリとしてしまいました。(笑)

私自身、プログラマとしての原点はベーマガで、掲載されていたプログラムの写経→改造→自作というステップを踏む事で、"プログラミングがどういうものか"・"コンピュータがどういうものか"というのを学ぶ事ができたかなと思っています。

昨今は、ソースコードはダウンロードしてきて実行するだけのモノという感じだと思うので、プログラミング初心者の方が"写経→改造→自作"というステップを経験する事が少なくて、なかなかプログラミングの勘所みたいのを掴めないまま、プログラミングを好きになれない人が多かったりするんじゃないかなぁ…なんて勝手な想像をしていたりします。

そういう意味では、WEB+DB PRESSの記事で書かれているような、何でもいいからごく簡単なゲームを自分で作ってみるというのは、プログラミングを覚える上で非常に有効な手段なんじゃないかなと思います。

こういった記事や動画によって、プログラミングを楽しめる人がもっと増えるといいですね!(^-^)

TopHatenarのランキングを周期表っぽく並べたものを作ってみた

何かふいに思い付いて、TopHatenarはてなダイアリーのランキングを元素の周期表みたいに並べたもの*1を作ってみました。

ランキング周期表

何の意味があるかって? 何の意味もありません。(笑)

元々、アイデアのネタの一つとして「周期表の形式で何かを並べたら面白いものが作れないかな。」と思っていたのがあって、「ちょうど順番に並んでいるものだし、何かのランキングを周期表に見立てて並べたら面白いかも…。」ぐらいの軽い気持ちで、勢いに任せて作ってみたものです。

内部的には、必要な情報の位置をURLとXPathを使って指定して取ってくるような作りにしてあって、設定ファイルさえいじれば、色んなランキングの周期表が作れるので、徐々に対象を増やしていこうかなと思っています。*2

ちなみに、元素記号的な感じになっているアルファベット数文字は、この周期表内で被らないようにしながら、はてなIDを省略したものですが、はてなーの皆さんならその数文字だけで誰だか分かるかもしれませんね。( ̄ー ̄)

あとは、せっかく元素のメタファーを持たせたので、その絡みで何か面白い事ができないか考えたりはしていますが、このWebサービスが発展の方向に向かうかどうかは…現時点では未定です…。

とりあえず思い付いたら、すぐに作ってすぐ公開をモットーに、また色々作っていこうかなと思います。

*1:ランタノイドアクチノイドは一つの元素という扱いにしています。

*2:TopHatenarのランキングはAPIが無さそうだったので、スクレイピングして情報を取ってきている為、TopHatenar側のHTML構成変更などがあった場合、予告なく当サービスを停止する場合があるのでご了承の程を。

コメント投票機能・Twitter連携機能など付けてみました

BEAR連載のおかげで、できる事の幅も広がってきたので、今まで作ってきたWebサービスリニューアル大作戦の第一弾として、今北川柳をBEARベースに置き換えつつ、機能拡張してリニューアルしてみました。

追加した機能のご紹介

Twitter連携

作成された川柳を、@imakitasenryuでつぶやくようにしました。フォローしてもらうと、意味が分かりそうで分からない川柳がいっぱい流れてくると思います。(笑)

面白い川柳があったら返信またはRT(QT)してもらうと、その川柳への投票になります。コメント付きで返信・RTすると、ちゃんと投票コメントとして反映されるようになっています。

返信・RTする場合、以下のような書式でないと正しくコメントを抽出できない事があるので、ご注意下さい。

コメント投票機能

今まで川柳への投票は、はてなスターの機能を使っていたんですが、いかんせん敷居が高いのか全く投票に使ってもらえなかったので(^^;、自前で投票機能を実装しました。

「面白い!」と思ったら、"天晴+"ボタンを押すと、その川柳に投票する事ができます。また、"天晴+"ボタンの隣の吹き出しボタンを押してコメントフォームにコメントを入力してから投票すると、コメント付きで投票する事もできます。

コメント表示機能

川柳を色紙画像で表示する個別表示画面で、投票されたコメントを吹き出しで表示するようにしました。鬱陶しいと思ったら"コメントを非表示にする"のリンクをクリックすれば、表示を止める事ができます。表示設定はCookieに保存されるので、次回訪れた時も設定がそのまま引き継がれるようになっています。

APIの追加

ブログなんかで簡単に紹介してもらえるように、画像のAPIは前バージョンからあったのですが、今回、テキストベースのAPIも作ってみました。現在、以下のAPIが利用可能です。

画像取得API(URLを指定)
http://www.stellaqua.com/imakitasenryu/api/images.php?url={対象サイトのURL}[&size=small]
画像取得API(IDを指定)
http://www.stellaqua.com/imakitasenryu/api/images.php?id={川柳ID}[&size=small]
テキスト取得API(URLを指定)
http://www.stellaqua.com/imakitasenryu/api/texts.php?url={対象サイトのURL}[&format=(xml|json|jsonp&callback={コールバック関数})]
テキスト取得API(IDを指定)
http://www.stellaqua.com/imakitasenryu/api/texts.php?id={川柳ID}[&format=(xml|json|jsonp&callback={コールバック関数})]
コメント取得API
http://www.stellaqua.com/imakitasenryu/api/comments.php?id={川柳ID}[&format=(xml|json|jsonp&callback={コールバック関数})][&_start={表示ページ}]

テキスト取得APIのレスポンスは以下のような感じです。(XMLの場合)

<?xml version="1.0" encoding="utf-8"?>
<results>
    <senryu>
        <id>52e85875124208d7c40ff10d16d7bae0</id>
        <createdtime>2010-05-01T14:55:14+0900</createdtime>
        <sourceurl>http://news.google.co.jp/</sourceurl>
        <sourcetitle>Google ニュース</sourcetitle>
        <votecount>0</votecount>
        <commentcount>0</commentcount>
        <texts>
            <text1>出席し</text1>
            <text2>訴えている</text2>
            <text3>謝罪する</text3>
        </texts>
        <links>
            <imageurl>http://www.stellaqua.com/imakitasenryu/api/images.php?id=52e85875124208d7c40ff10d16d7bae0</imageurl>
            <entryurl>http://www.stellaqua.com/imakitasenryu/api/texts.php?id=52e85875124208d7c40ff10d16d7bae0</entryurl>
            <commenturl>http://www.stellaqua.com/imakitasenryu/api/comments.php?id=52e85875124208d7c40ff10d16d7bae0</commenturl>
            <tweeturl>http://www.twitter.com/imakitasenryu/status/13173910635</tweeturl>
        </links>
    </senryu>
</results>

コメント取得APIのレスポンスは以下のような感じです。(XMLの場合)

<?xml version="1.0" encoding="utf-8"?>
<results>
    <pager>
        <totalResults>1</totalResults>
        <startIndex>1</startIndex>
        <itemsPerPage>1</itemsPerPage>
        <firstpageurl></firstpageurl>
        <nextpageurl></nextpageurl>
        <prevpageurl></prevpageurl>
        <lastpageurl></lastpageurl>
    </pager>
    <comments>
        <comment>
            <id></id>
            <createdtime>2010-05-01T15:00:00+0900</createdtime>
            <targetid>52e85875124208d7c40ff10d16d7bae0</targetid>
            <body>コメントしてみたよ</body>
            <targeturl>http://www.stellaqua.com/imakitasenryu/api/texts.php?id=52e85875124208d7c40ff10d16d7bae0</targeturl>
            <via>http://www.stellaqua.com/imakitasenryu/api/texts.php?id=52e85875124208d7c40ff10d16d7bae0</via>
        </comment>
        <comment>
            :
        </comment>
            :
    </comments>
</results>

レスポンスコードは、200(OK)・400(呼び出し方の不正)・403(高負荷によるアクセス規制)・500(サーバエラー)のいずれかが返ってきます。

こんなAPIを公開したところで何かに使えるのかどうか全くもって不明ではありますが、まぁこれを使って何かを作ろうという奇特な方が現れた時の為に公開しておきます。(笑)

ちなみに、川柳を作成する対象URLを指定してアクセスした時に、対象サイトの内容のキャッシュが無い場合、レスポンスに数秒掛かる事があるのでご注意下さい。

その他こだわった点とか

細かい事なんですが、今回のリニューアルに伴ってタイトルからα表記を外して、ついでにfaviconも作ってみました。ドットを置いていくタイプのfavicon作成Webサービスで、5分くらいで作ったやっつけにしてはそれなりなモノができたので満足しています。

あと、コメントの表示は結構こだわってみました。ボワンと現れて、スーっと消えていく感じが結構気にいっています。最初はニコニコ動画風な流れるコメントにしようかとも思ったんですが、何か今や目新しさも無くなった感もあるし、あんまりやり過ぎても鬱陶しくなるだけかなと思って、今の形に落ち着きました。

この辺りのアニメーションと、Ajaxのデータのやり取りでjQueryをふんだんに使ってみたんですが、色々と勉強になりました。Webサービスにちょっとした彩りを添えるのにはjQueryは使い易くって非常に良いですね。

それから、川柳の元になる単語を拾ってくる時に、数字の読みをきちんと行うようにしてみました。

MeCabで普通に数字を読ませると一桁ずつでしか読んでくれないので、"123"を"イチニサン"と読んでしまうんですが、こういうのをちゃんと"ヒャクニジュウサン"と読めるように、自前で専用のクラスを作って変換をするようにしてみました。これで、数字を含む単語でもそれなりに抽出できるようになったのではないかと思います。

その他困った点とか

TwitterのOAuth対応は以前に試した事があったので、そこでの苦労はあまり無かったんですが、RTを取り込んで投票に反映させる機能が大変でした…。

以下、ハマりどころ…。

  • 公式RTは、自分のつぶやきの内のどのつぶやきがRTされたかは分かるけど、誰からRTされたのかはAPIで取得できない…。(仕方がないので、公式RTを投票に使うのは諦めた。)
  • 非公式RTだと書式が決まってないから、コメント部分だけ抜き出そうとすると、どうするのがベストか分からない…。(仕方がないので、最初に出てきた"RT"より前の部分をコメントと決め打ちしちゃう事にした。)
  • 非公式RTだと、どのつぶやきに対する返信か分からないから、どの川柳に対する投票なのか特定できない…。(仕方がないので、元のつぶやきに含ませてあるURLから川柳のIDを取得する事にした。)
  • 非公式RTで元のつぶやきのURLを短縮URLにしないで入れてもらおうとすると、コメントに使える文字数が少なくなってしまう…。(仕方がないので、短縮URLの場合は展開してからIDを取得する実装を入れた。)

Twitterも今やインフラとしての利用価値が大きいから、できるだけTwitterからもWebサービスに参加できる間口は広げたいんですが、自由度が高過ぎる故に、Webサービスとして欲しい情報を拾ってこようと思うと妥協しなきゃいけない部分が多くて悶々としますな…。

Twitter連携は突っ込むと泥沼にハマりそうな感もあるので、そこそこの線で妥協しときたいと思います…。


そんな訳で、色々と機能追加してより遊べるようになったかと思うので、「これからも 今北川柳 よろしくね♪」(一句)

*1:"RT"or"QT"が1回("RT:"とかコロン付きでもOK)、コメントが"RT"or"QT"より前にある、元のつぶやきの中のURLが含まれる(短縮URLでもOK)、という条件を満たしていれば大丈夫なはずです。