みなさん、こんにちは。
アルゴリズムが好きな小井です。
昨年の事になるのですが、東京メトロ オープンデータ活用コンテストというものに、個人的にいくつかの作品を応募したのでその中から社内外に好評だった「metrogram」をご紹介させていただきます。
すごく簡単に紹介させてもらうと、「普段見る事のできない地下鉄の流れを視覚的に見えるように」という、いわゆる「みえる化」の作品になります。
使った技術的にはそう多くはありませんし、ここ数年流行の「ライブラリを利用してできました」という流れの逆をいく「基本的なアルゴリズムを考え抜いた」というものになります。扱った情報としては
- 駅座標の配置と、それらを繋ぐ曲線
- 時刻表管理
- 乗り換え情報の管理(未使用
- 処理の高速化
- 各種最適化
という予想を裏切らない内容なのですが、今回はこの中からいくつかの部分をピックアップしました。
駅座標とそれらを繋ぐ曲線
今回、駅と駅を繋ぐ線(=線路)を曲線で描く事にしました。曲線と言っても厳密には短い直線を複数組み合わせる事で曲線に見せています。
その曲線を描く方法ですが、以下の方法が考えられました。(以下の方法しか現状知らないとも言えますが。。。。)
- 2次ペジェ曲線
- 3次ペジェ曲線
- スプライン曲線
- エルミート曲線
連続した点という事で、2次ペジェ曲線を最初扱っていたのですが、結局スプライン曲線を採用。
理由としては、複数の点を結んだ曲線を算出する式ということで、駅と駅の間を繋ぐ線の\目的にぴったりはまったという点。
さらに、利用した関数では、点と点の間を任意の分割数に割る事ができるものだったのも理由の一つです。
【DEMO】
スプライン曲線
スプライン曲線 + 動的な描画
処理の高速化
複数層になるcanvasレイヤー
metrogramでは多くの描画を行う必要がありました。
そのなかでも特に、路線を描く処理が多くを占め、そこを以下に効率化するか?が処理速度を調整する上で大きな課題でした。
そこで、レイヤーの考え方を導入し、描画される対象ごとにcanvasを使い分ける方法を採用しました。
具体的には以下の層に分けられています。
- 背景レイヤー (背景色描画)
- 路線レイヤー (各駅を繋ぐ線路の描画)
- 駅 + 文字レイヤー (駅相当の箇所に、駅マークと、駅名を描画)
- 電車レイヤー (運行中の電車の位置に電車アイコンを描画)
【DEMO】
CANVASによるレイヤー処理
各種最適化
各種最適化と言いつつも、広告系のお仕事ではなかなかやる事の少ない処理
- 画像圧縮
- コード圧縮
- gzip
以下3項目を実施。
この中でも特に、gzipによるデータ圧縮は非常に効果が高く、特にモバイル環境であればあるほど実施するメリットが高くなると思われます。
metrogramの中心処理を記述したJSをgzipで圧縮したところ、75%の容量圧縮に成功。
同様に、駅情報を記載したXMLファイルをgzipで圧縮したところ、86%の容量圧縮に成功。
gzipのやり方ですが、私はMAC環境でおこなっており、ターナルから以下の処理を行う事で実行しています。
1 |
h-koi-air:~ h_koi$ gzip [zipしたいファイルパス、もしくは対象となるファイルをドラッグアンドドロップ] |
最後に、htaccessを記述してgzip対応が完了します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
RewriteEngine on RewriteCond %{HTTP:Accept-Encoding} gzip RewriteCond %{REQUEST_FILENAME}\.gz -s RewriteRule .+ %{REQUEST_URI}.gz <FilesMatch "\.css\.gz$"> ForceType text/css AddEncoding x-gzip .gz </FilesMatch> <FilesMatch "\.js\.gz$"> ForceType application/x-javascript AddEncoding x-gzip .gz </FilesMatch> <Files ~ ".(gif|jpe?g|png|ico|js|css|gz|woff)$"> Header set Cache-Control "max-age=604800" </Files> |
比較的少ない手数で得られる効果は高いので、制作物によっては非常に強力な手段と言えるでしょう。
今回の記事では主に描画面と、その為のパフォーマンスチューニングの部分について触れてみました。
次はmetrogram3Dとかやってみると面白いかな?と思いつつ、年度末を駆け抜けようと思います。
※ 今回デモ等で参照できるコードをご利用の際は、自己責任のもとでのご利用をお願いします。