F-11Dというスマホを持っている。Android端末がどういうものか触ってみたい、という目的で、新宿の中古PC屋で5000円で購入した。金のかかるSIMカードは刺さないで、オフラインのみの利用だ。オフラインでも、エクスプローラー的なアプリさえインストール済みなら、APK Downloaderを使用してアプリをいくらでも入れられる。現在は電車内で映画を見るための端末と化している。今日判明したところによると、オフラインでもGPS機能は使用できるらしい。せっかくTrainNavi2をオフラインでも使用できるように変更中なんだから、GPSと連動させる機能を作ってみてもいいかもしれない。動作確認が実機でできるというのはありがたい。
さて、必要があって、root化(システムフォルダへのアクセス権を得ること)を試してみたところ、2時間ほどでできた。
参考リンク:
むう゛の: USB Driverのインストールとadb接続 F-11D編
むう゛の: Android 4.0.3(ICS)のroot化・・・F-11D(V26R42B)の場合
root化の過程でAndroidアプリの開発環境を得ることができた。夢がひろがりんぐだが、Javaの習得が必要なので、また長い道のりになりそうだ。
しかしexploitのコードを書ける人ってすごいよな。メモリ上のアドレス直書きしてるし。憧れちゃう。いつかハードウェアハックできるような腕前になってみたい。
プログラミング
今後の予定
kickzone/TrainNavi2 · GitHub
結局、起動時の読み込み処理までしか完成できなかった。来週こそは、線路を描画したい。線路が描画できたら、次は列車の動的読み込みと表示だ。そこまでやれば、前回のTrainNaviとほぼ同機能になる。しかしながら、追加したい機能は大量に存在する。いつまでかかることやら。
当面の残り作業(優先順)
- 駅、線路の描画
- 列車の読み込み
- 列車の表示、アニメーション、発車停車時の速度変更 列車の加減速 – diary 六帖
- パッケージファイルの読み込み
- 拡大縮小
追加したい機能(優先順)
- スクロールできるようにする。
- スクロールに合わせた画面表示をする。画面にないオブジェクトを削除して動作を軽くする。スクロールして画面内に入ってきたところではじめて表示する。
- 通過点のエディット機能、ベジェ曲線で完璧な線路を引くためのGUI作成。ベジェ曲線 – diary 六帖
- GoogleMapと連携する。地図上を列車が走る。
- スキン機能。あらゆる路線図を作れるようにする。
- ターゲットとなる列車を決めて、強調表示する。今どのあたりを走っているかが分かる。
- 駅をクリックしたら情報を表示する。あと何分で電車が来るとか、目的地を決めたらそこまでかかる時間とか。
- 列車をクリックしたら情報を表示する。現在速度とか表定速度とか、次はどこに止まるかとか。
- 運賃を表示できるようにする。FareMap(自作)の機能を全部移植する。
- 時刻表を自動生成する。
- この際、NAVITIMEみたいな最短経路・最安経路生成機能も付けてしまう。
二次ベジェ曲線
ベジェ曲線 – からすの日記
げっ、さっきの↑のサンプル、3次ベジェ曲線じゃん!そんなに複雑じゃなくていいので、2次ベジェ曲線を繋いだ図形で十分だ。3次にするとテーブルのカラムも2倍になるし!
なので、2次ベジェ曲線の近似式は、自分で作らなきゃいけないことになった。。まあさっきのサンプルを参考にすればいいのかな。
ベジェ曲線
路線図を滑らかに描くには、ベジェ曲線を使う必要がある。Illustratorなどで使われてる、こういうやつ。
参考リンク:中学生でもわかるベジェ曲線 – Rui's Blog
しかしながら、canvasやCreateJSには、ベジェ曲線を描くメソッドはあるが、ベジェ曲線の関数をゲットできるわけではない。
路線図上に列車を走らせるには、ベジェ曲線から一定間隔離れた点を連続してゲットする必要がある。曲線と直交する単位ベクトルを求めて一定倍して、その軌跡を作らないと列車が走れない。そのためには、曲線の傾きが分からないと垂線が引けない。せめて近似式でもいいから関数を作れないか、と思って探していたら、あった。
ベジェ曲線 – からすの日記
なぜこの式になるのかは改めて勉強する必要があるが、これなら曲線を、直線が連続したものとして近似できる。しかもn分割できる。通過点の配列を作るので、隣り合う2点をもってこれば変換は楽勝だ。列車の軌跡が簡単な計算で作れそうだ。助かった。
さて、ベジェ曲線のためのテーブルも必要になる。次のように定義しよう。
- tnhalfway
- linename 所属する路線名
- kilo 営業キロ(必ず駅と駅の間の値にする)
- latitude 緯度
- longitude 経度
- sp1lat ベジェ曲線の制御点1 経度
- sp1lon ベジェ曲線の制御点1 緯度
- sp2lat ベジェ曲線の制御点2 経度
- sp2lon ベジェ曲線の制御点2 緯度
kiloの値は、位置関係を表すだけの便宜的なものでよさそうだ。直線の距離を足せば合計の直線の長さが計算できるから、駅と駅の間の何%の所の点なのか簡単に計算できる。読み込み後、計算しなおせばよい。
少し前に、いま絶対座標を緯度と経度の小数点以下4桁まで、で持っているけど、精度が良くないんじゃないか。。と思って、経度0.0001度の距離を計算してみたら、約10mだった(計算式は忘れた)。路線図として表示するには、まあまあ許容範囲か、と思われる。wikipediaに載ってる緯度経度情報はおおむね、小数点以下6桁まで表示されている。誤差0.1mまで計算できるなら完璧だ。入力しなおすのはちょっとうんざりだけど、仕方ない。やってみよう。
明日はせめて直線だけでも線路が描けたらいいな!
列車の加減速
昨日電車の中で考えてたこと。単に電車のシンボルを時刻表通りに動作させるだけでは前回と同じで面白くないので、出発後と到着前に加減速をするようにしてみたい。また、時刻表には病の記載がないので、記載上停車時間が0秒のことがしばしばある。例えば、山手線の時刻表データは、発時刻しか書いてないので、あたかも全駅で1秒も停車しないような動きしかできない。
試しに山手線で加速、減速のタイミングと停車時間を計ってみた。すると、加速にはたいてい30秒、減速には30〜45秒かかることがわかった。停車時間は25秒〜1分半とかなり幅があった。
簡単のため、加速したら最高速になり、その後減速するまで速度は一定と仮定すると、モデルは次のようになる。a: 加速にかかる時間、b: 減速にかかる時間、c: 発車から停車までにかかる時間、vmax: 最高速。
プログラムでは、現在時刻を与えると現在位置を返す、という関数を作ればよい。グラフのx座標の現在時刻のところにy軸に垂直な線を引いて、できた図形の面積が現在位置となる。これを計算することになる。必要な数字はすべて与えられているので、式さえわかれば計算は容易だろう。
まずvmaxを
a*vmax/2 + (c-b-a)*vmax + b*vmax/2 = 駅間距離
から算出し、それがわかればあとは三角形や台形や長方形の面積を出して足せばOKでしょう。これで発車、停車の簡単なシミュレートができそうだ。ただこのモデルだと現在位置は現在時刻の2次関数になるから、自由落下みたいな加速、ボールを上に投げたときのような減速になるのかな。ちょっと急速すぎるかなぁ。まあ、不自然かどうかはできてから考えよう。
あとは停車時間のモデルだけれど、駅ごとにパラメーターを設定するか、一律のルールを作るか(例えば発時間=着時間だったら30秒にするとか)。一律の方が楽だな。
パッケージファイル試作品
パッケージファイル仕様案 – diary 六帖 の続き
小田急小田原線平日ダイヤと直通列車のみのデータを使用し、パッケージファイルを作成した。六帖webアプリにアップロードした。省略できるところはできるだけ省略した結果、時刻表1.31MB+駅・路線・列車種類もひっくるめたファイルの容量は、292KBまで減った。
小田急全線のデータを追加してもせいぜい400KB程度、休日のデータとスキン機能を入れても1MBは超えないだろう。これなら十分使用に耐えうる。それが分かっただけでも大きな収穫だった。
来週は、画面表示に着手していこう。
今日学んだこと:MySQLには、time型のカラムを成型する機能がある。DATE_FORMAT関数を使う。
SELECT DATE_FORMAT(starttime, ‘%k:%i’) AS start, DATE_FORMAT(endtime, ‘%k:%i’) AS end FROM tnroute ;
で、starttime, endtimeを24時間制の時:分の形式で、かつ0埋めしないでゲットできる。
パッケージファイル仕様案
※私的メモです
無料サーバーは転送容量に制限がある。DBやファイルに頻繁にアクセスするプログラムを作ると、いずれ転送容量を超過してアカウントが停止されてしまう。ローカルファイルにDBをエクスポートできれば、この問題を解決できる。しかもそうすると、htmlとjs一式をアーカイブして配布すればwebなしでローカル環境だけで実行もできる。
大きく分けて2つの機能が必要だ。
- DBからローカルファイルに列車・時刻表データをエクスポートする機能
- File APIなどでローカルに読み込んで動作させるような仕組み
ファイルは単一のものでないと扱いが面倒で仕方ないので、1ファイルにすべての情報を詰め込むパッケージ方式を導入するべきだ。ローカルに保存するファイルは、できるだけ容量が小さい方が良い。例えば、路線名、駅名は文字列で与えると冗長なのでIDを振らざるを得ないだろう。
仕様案
[line] 1,小田急小田原線,#0086CE 2,小田急多摩線,#0086CE 3,小田急江ノ島線,#0086CE 4,箱根登山電車,#E84B14 (略) ※路線ID,路線名,色 [station] -1,小田急小田原線 1,新宿,0.0,35.6908,139.6996 2,南新宿,0.8,35.6835,139.6985 3,参宮橋,1.5,35.6786,139.6936 (略) ※駅ID,駅名,営業キロ,緯度,経度 [trainkind] -1,小田急小田原線 1,各停,#9C9C9C 2,区間準急,#00AFE4 3,準急,#009A61 (略) ※種類ID,種類名,色 [train] -1,小田急小田原線 1001,1,5,,,,34,5:17,35,5:20,35,5:20,36,5:24,.... 5501,1,1,3,5501,1,5:21,2,5:22,2,5:23,3,5:24,.... (略) ※列車名,平日休日,種類ID,種類名(特急列車の名前など),直通先路線ID,直通先列車名, 発駅ID,発時刻,着駅ID,着時刻,発駅ID...(以下終点まで繰り返し)
パッケージには以上のような情報があれば十分だろう。DBはだいたいできたから、このようなファイルを作成するPHPスクリプトを作成し、どのくらいのサイズになるのかまず実験してみよう。将来的にはあらゆる路線の表示に対応するため、スキン機能も必要だ。stationにxy座標を指定したり、特定の駅だけ表示を変えたり、曲線を描いてみたり。。
DBを使用する場合でも、PHPからクライアントにJSONを渡す方式ではサイズがデカくなりがちなので、上のようなテキストをPHPに作らせて、クライアント側で解釈するようにしよう。
仕様策定中2
Learning JavaScript Design Patterns をModule Patternのところまで読んだ。JavaScriptはフリーダムすぎる。制限がなさすぎるため、プログラマーの世界観が色濃く反映する。汚いプログラムはより一層汚くなってしまうだろう。
Moduleパターンは画期的だ。クロージャを使うことでprivateとpublicをJavaScriptで実現できるなんて、思いついた人はすごい。その上、関連するメソッドやプロパティがモジュール内にまとまるから、メンテナンスが飛躍的に容易になる。ただ、publicなインターフェースとして毎回オブジェクトをreturnしてるんだけれど、これはパフォーマンスに影響しそうな気がする。そこのところはどうなってるんだろう。
さてModuleは是非採用したいパターンの一つだ。Singletonとはまた違った意味で、このパターンは一個性があるように思われる。したがって多数生成するオブジェクトには使いにくそうだ。駅、列車のオブジェクトには使えまい。private変数を活用するものとしては
- 時刻表データベース用のモジュール DBやcsvの内容を格納
- 画面表示担当用のモジュール 路線や電車を格納
ここらへんに大いに活用できそうだ。今日はここまでか。ほとんどコード書いてないよ。
仕様策定中1
DB構造再編 – diary 六帖の続き
csvを作ってみると、小田急小田原線のダイヤのデータは平日上下合わせて約1MBにすぎないことがわかった。1MBくらいならメモリ中にロードしたところで大したものではない。いまやスマホでさえどの機種でもメモリはGB単位だ。全部メモリ中にDBの内容を読み込んでしまった方が、後々楽だろう。Ajax使わなくてもいいんじゃない?
しかし起動時にこの量を全部ダウンロードするのはあまり得策ではない。おそらく多摩線、江ノ島線を足して2MBといったところだろうが、ADSLで基地局から遠い場合は100KB/秒くらいだと20秒、スマホの転送量制限を超えた場合は128kbps=16KB/sなので2分もかかってしまう。これはダサい。やはりAjaxは必要か。
検証のため旧TrainNaviのサーバーとのやり取りを調べたところ、小田急全線の1時間分の列車情報をゲットするのに約5秒かかり、データ量は2-300KB程度。でかいな。サーバーからJSONを返しているのでかなりの冗長性があるようだ。
[{“LineID”:”1″,”TrainID”:”10″,”StartStationID”:”47″,”EndStationID”:”41″,”StartTime”:”05:10:00″,”EndTime”:”05:18:00″},{“LineID”:”1″,”TrainID”:”10″,”StartStationID”:”41″,”EndStationID”:”40″,”StartTime”:”05:19:00″,”EndTime”:”05:25:00″},{“LineID”:”1″,”TrainID”:”10″,”StartStationID”:”40″,”EndStationID”:”39″,”StartTime”:”05:25:00″,”EndTime”:”05:29:00″}
以下略
無駄だなぁ。。JSONはやめてcsvを返すようにして、クライアント側でパースするようにした方がよさそうだ。1,10,47,41,5:10,5:18 で十分だよね。
で、DBしか使わない場合は拡張性に乏しくなるので、csvをサーバーにアップロードしても使えるようにする。もちろんDBの方が高速だが、扱うデータが高々2MBとそれほど大きくないのでファイルアクセスしてもよいでしょう。共通のインターフェースを作って、どちらでも使えるようにする。Ajaxで路線名、取得範囲をphpに投げて、phpから該当するデータを返してもらう。
csvはヘッダも必要だな。tntrainテーブルに列車の寿命(始発時間と終着時間)を書いておけば、読み込みもスムーズになるでしょう。
GitHubを使う
今月会社に行ったとき、バイトの人がGitHubを使ったことがあると言っていた。そういえばEclipseにはGitの機能が付いていた。VSSだけしか使ったことがないんじゃ時代遅れになりそうだ。折角機能が付いてるので、せっかくだから登録してみた。
kickzone · GitHub
Gitを使うのは初めてだ。すごく動作が軽いように感じる。これで、念願のバージョン管理ができる。。しかもローカル環境でもできる。すごい。
参考リンク:じっとしてないEGit: EclipseのプロジェクトをGitにPushする。
今日は登録済みの単語検索機能を追加したので、早速GitHubにも反映した。ソースを更新することをチェックインではなく、コミット又はプッシュというらしい。コミットとプッシュの違いが判ってない。調べなきゃ。