爆発コマンド

f:id:y_d:20140212022307g:plain

爆発しろ!という気持ちを鎮める為のシェルを書きました。
このシェルを叩くとランダムで生成された爆発のアニメーションが描画されます。
※パーティクルが密集しているところは「@」など大きめの文字で描画するなど、ちょっと凝ってます

シェルスクリプトに関する知識がなかった事もありググりながら書いたソースなので汚いですが、ソースはこちらにて公開してありますのでダウンロードして使ってみてください。
https://gist.github.com/demouth/8939731
設定値は一カ所にまとめてありますので爆発具合の調整もできます。
MacOSMacOSのターミナル.appでしか動作確認していないので他では動かないかもしれません。

個人的メモ

  • 最初キャリッジリターン(\r)を使おうかと思ったけど、文字数が増え複数行にまたがった場合上に戻れないようなのでtputを使う事にした。
  • exprを使って実装したら遅かったので$(())に書き換えたら早くなった(計測はしてない)。
  • 小数点の計算が面倒だったのでやめた。
  • エスケープシーケンスは[Ctrl]+[v]→[ESC]で入力するらしい。

iOS7なiPadのユーザーエージェントについて調べてみた

f:id:y_d:20140209221129p:plain

ある日、Chromeデベロッパーツールで Device「Apple iPad 3 / 4」にするとユーザーエージェントが「iPhone」となっている事に気がつきました。

Mozilla/5.0 (iPhone; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53

んー、本当かなー。

ググってみる

という事で、iPadのユーザーエージェントについてググっていると次の情報が出てきました。

Mozilla/5.0 (iPad; CPU iPhone OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53

http://tetsuwo.tumblr.com/post/62159303953/ios-7-safari-iphone-ipad-ipod-touch

Mozilla/5.0 (iPad; CPU iPhone OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B511 Safari/9537.53

http://www.miuxmiu.com/archives/2013/10/27/ipad_ios7_safari_user_agent.html

やっぱり「iPhone」ではなく「iPad」でしたが、何でしょう、ユーザーエージェントの中に「iPhone」が含まれています。しかもググって出てきたページではすべて「iPhone」が含まれていました。

実機確認してみる

私が所持している実機iPad2(iOS7.0.4)では下記のように「iPhone」という文字列は入っていませんでした。

Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53


私のサーバーへの最近のアクセスログでは、「iPad」が含まれるユーザーエージェントは下記のようになっています。
こちらも「iPhone」という文字列が入っている物はありません。

"Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3"
"Mozilla/5.0 (iPad; CPU OS 5_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B176 Safari/7534.48.3"
"Mozilla/5.0 (iPad; CPU OS 5_1_1 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3"
"Mozilla/5.0 (iPad; CPU OS 6_0 like Mac OS X) AppleWebKit/536.26(KHTML, like Gecko) Version/6.0 Mobile/10A5355d Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_0_1 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A523 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_0_2 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10A550 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_1_2 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B146 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_1_2 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B147 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) CriOS/32.0.1700.20 Mobile/10B329 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B329"
"Mozilla/5.0 (iPad; CPU OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Version/6.0 Mobile/10B329 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A465 Safari/9537.53"
"Mozilla/5.0 (iPad; CPU OS 7_0_2 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11A501 Safari/9537.53"
"Mozilla/5.0 (iPad; CPU OS 7_0_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) GSA/3.1.0.23513 Mobile/11B511 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/31.0.1650.18 Mobile/11B511 Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/11B511"
"Mozilla/5.0 (iPad; CPU OS 7_0_3 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B511 Safari/9537.53"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) GSA/3.1.0.23513 Mobile/11B554a Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) GSA/3.2.0.25255 Mobile/11B554a Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) GSA/3.2.1.25875 Mobile/11B554a Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) CriOS/31.0.1650.18 Mobile/11B554a Safari/8536.25"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Mobile/11B554a"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/5.1 Mobile/9B206 Safari/7534.48.3"
"Mozilla/5.0 (iPad; CPU OS 7_0_4 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11B554a Safari/9537.53"
"Mozilla/5.0 (iPad; CPU OS 7_1 like Mac OS X) AppleWebKit/537.51.1 (KHTML, like Gecko) Version/7.0 Mobile/11D5127c Safari/9537.53"
"Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; en-us) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"
"Mozilla/5.0 (iPad; U; CPU OS 4_3_3 like Mac OS X; ja-jp) AppleWebKit/533.17.9 (KHTML, like Gecko) Version/5.0.2 Mobile/8J2 Safari/6533.18.5"

まとめ

  • iOS7のiPadでもユーザーエージェントは「iPhone」ではなく「iPad」のはず
  • iOS7のiPadでユーザーエージェントの中に「iPhone」が含まれている記事はあるが、私が確認できる範囲ではiOS7のiPadのユーザーエージェントには「iPhone」という文字列は入っていない

結局どういったケースで、iPadのユーザーエージェントにiPhoneが含まれるのか分かりませんでしたが、きっとレアケースなんだと思います(なげやり)。

PHPのジオコーディングライブラリ作りました

f:id:y_d:20140203015926p:plain
DmGeocorderというPHPで実装された日本国内用ジオコーディングライブラリを作りました。
住所から緯度経度を調べたり(ジオコーディング)、緯度経度から住所を調べたりすること(逆ジオコーディング)が出来ます。

https://github.com/demouth/DmGeocoder

特徴

  • 一般的にプログラムからジオコーディングをする時、Google Geocording APIのようなジオコーディングAPIを利用しますが、当ライブラリは地理情報をライブラリ内に持ちジオコーディングAPIを利用しません。これによりジオコーディングAPIを利用した実装とは違い、回数制限など気にせず利用することが可能です。これがこのライブラリ最大の特徴です。
  • 当ライブラリのソースをサーバーに配置するだけで利用可能です(ジオコーディングAPIやDBを使っていない為特にライブラリを利用するための準備、サーバー設定は不要)。
  • 丁番号程度の多少の表記の揺らぎについては対応しています(詳しくは使い方を参照)。
  • 日本国内のみに対応していて、国外のジオコーディングは出来ません。
  • 緯度経度は世界測地系です。
  • 精度は大字・町丁目レベルで、街区情報は持ちません。
  • 位置情報は平成24年度版のデータを利用しています。翌年版のデータが公開されたらcsvディレクトリに配置されているcsvファイルを差し替えれば利用可能です。
  • PHP5.0以上で利用可能で、PHP5.3以下でも使えるようにnamespaceは使用していません。

使い方

使い方1 住所名から緯度経度を取得する

住所文字列をDm_Geocoder::geocode()の第一引数に渡すと、引数を元に住所検索を行い、詳細な住所情報を返します。 この住所情報には緯度経度情報を含みます。
可能性の高い位置情報が複数存在した場合は、それらの住所をすべて返します。

<?php
$addresses = Dm_Geocoder::geocode('沖縄県八重山郡与那国町与那国');

echo count($addresses); // 1 (この場合は1)
$address = $addresses[0];

echo get_class($address); // Dm_Geocoder_Address
echo $address->lat; // 24.468119 (緯度)
echo $address->lng; // 123.004341 (経度)
echo $address->prefectureName; // 沖縄県 (都道府県名)
echo $address->municipalityName; // 八重山郡与那国町 (市区町村名)
echo $address->localName; // 与那国 (大字町丁目名)
echo $address->prefectureCode; // 47 (都道府県コード)
echo $address->municipalityCode; // 47382 (市区町村コード)
echo $address->localCode; // 473820001000 (大字町丁目コード)

検索結果が複数件存在した場合、より可能性の高い住所を複数返します。

<?php
//検索結果が複数存在する場合
$addresses = Dm_Geocoder::geocode('東京都港区芝公園');
echo count($addresses); // 4 (検索結果に一〜四丁目と、複数存在する)
echo $addresses[0]->localName; // 芝公園一丁目
echo $addresses[1]->localName; // 芝公園二丁目
echo $addresses[2]->localName; // 芝公園三丁目
echo $addresses[3]->localName; // 芝公園四丁目

//住所の絞り込みが十分で、検索結果が1つまで絞りこまれている場合
$addresses = Dm_Geocoder::geocode('東京都港区芝公園一丁目');
echo count($addresses); // 1

//存在しない住所名での検索で、マッチする検索結果が1件も存在しない場合
$addresses = Dm_Geocoder::geocode('ほげほげ');
echo count($addresses); // 0

住所の表記ゆらぎをある程度サポートしていますので、下記例のような検索が可能です。
ただし下記の例に出てこないような検索、例えば「新宿区」を「しんじゅくく」といったものには対応していません。

<?php
//検索文字列の数字表記のゆらぎを吸収しているため、
//下記の3つはどれも同じ結果を返します
$addresses = Dm_Geocoder::geocode('北海道札幌市中央区大通西17丁目');
$addresses = Dm_Geocoder::geocode('北海道札幌市中央区大通西17丁目');
$addresses = Dm_Geocoder::geocode('北海道札幌市中央区大通西十七丁目');

//郵便番号が含まれていたり、スペースが含まれていたり、
//大字町丁目以降の住所が含まれていても検索可能です
//この場合郵便番号と大字町丁目以降の住所は無視されます
//例: 中華Dining 東海飯店 大門本店 http://r.gnavi.co.jp/a136700/map/
$addresses = Dm_Geocoder::geocode('〒105-0012 東京都港区芝大門2-4-18');
echo $addresses[0]->localName; // 芝大門二丁目

//県名の省略も可能です
//ただしこの場合、多少検索処理に時間がかかります
$addresses = Dm_Geocoder::geocode('塩竈市千賀の台二丁目');

//県名だけの検索も可能です
//この場合、この県に所属する「大字町丁目」分の結果が返ります
$addresses = Dm_Geocoder::geocode('愛媛県');
echo count($addresses); // 2439
使い方2 緯度経度から該当する住所を検索する

Dm_Geocoder::reverseGeocode(緯度,軽度)と渡すと、その緯度経度から近い順に住所情報を複数返します。

<?php
$addresses = Dm_Geocoder::reverseGeocode(39.761437, 140.089602);
$addresses[0]->prefectureName; // 秋田県
$addresses[0]->municipalityName; // 秋田市
$addresses[0]->localName; // 将軍野青山町
$addresses[1]->localName; // 将軍野堰越
$addresses[2]->localName; // 寺内字通穴
$addresses[3]->localName; // 将軍野東四丁目
    :
    :

//該当する住所が日本国内に存在しな場合は結果を返しません
$addresses = Dm_Geocoder::reverseGeocode(10.0, 100.0);
echo count($addresses); // 0

第三引数に検索結果の返却数を指定できます

<?php
//第三引数に渡した数分の住所を返します
$addresses = Dm_Geocoder::reverseGeocode(35.6882074,139.7001416, 3);
echo count($addresses); // 3

//第三引数を省略した場合、デフォルトで10件返します
$addresses = Dm_Geocoder::reverseGeocode(35.6882074,139.7001416);
echo count($addresses); // 10

include/reqiure方法

下記のいずれかの方法でライブラリを読み込んでください。
読み込みができていればクラスを使える状態になっています。

composerを利用する場合

下記のcomposer.jsonを書いてinstallしてください。

<?php
{
    "require": {
        "demouth/dmgeocoder": "1.0.0"
    }
}
手動でファイルをrequireする場合

こちらからソースをダウンロードして、下記のようにsrcディレクトリ以下のソースを読み込んでください。

<?php
//autoloaderを使わず、Classファイルを手動で読み込む場合は下記ファイルをすべて読み込んでください
$LIB_DIR = realpath(dirname(__FILE__).'/../src/').'/';
require_once $LIB_DIR.'Dm/Geocoder.php';
require_once $LIB_DIR.'Dm/Geocoder/Address.php';
require_once $LIB_DIR.'Dm/Geocoder/Prefecture.php';
require_once $LIB_DIR.'Dm/Geocoder/Query.php';
require_once $LIB_DIR.'Dm/Geocoder/GISCSV.php';
require_once $LIB_DIR.'Dm/Geocoder/GISCSV/Finder.php';
require_once $LIB_DIR.'Dm/Geocoder/GISCSV/Reader.php';

注意点

  • UTF-8以外はサポートしません。mb_internal_encoding('UTF-8');にした状態で、検索文字列にはUTF-8の文字列を渡してください。検索結果もUTF-8で返します。
続きを読む