2011年5月 7日
Remove '@Override' annotation
Eclipseで、そこらへんのコードをコピペすると、
Remove '@Override' annotation
と怒られることがある。言われた通り消せば良いのだが、サンプル丸ごとビルドしてみたい時などは面倒だ。
Errors/Warningsのオプションをいじれば直るのかと思ったが、なかなかそれっぽい項目が見つからない。
いろいろ調べた結果、Compiler compliance level を 1.6 に変更すればよいことが分かった。(プロジェクトのプロパティを開いて、Java Compiler の中にある)
理想と現実の乖離にぶつかる度に、Javaが嫌いになる。理想とはもちろん"Write once, run anywhere"のことで、現実とはもちろん"Write once, debug anywhere"のことだ。
2011年5月 1日
JJYエミュ
先日作成したJJYシミュレータ for Androidを改良してAndroid Marketに登録した。・・のは20日頃だっただろうか。
名前についてちょっと悩んだんだが、「JJYエミュ」とした。
シミュレータとエミュレータの違いについては微妙なんだが、ここでの目的としては実験環境の用意ではなく、本物の模倣である。
どっちかと言えばエミュレータかなと思った次第。
本家の方は送出する時刻を変更することが可能なあたりがシミュレータの要素を含んでいると思う。
まあ、名前なんかはどうでもいい。
それにしてもインストール数が伸びない。
リーチの想定は「マーケット内にて"JJY"で検索する」というものであるが、そんなことをする人は少ないのだろうか。
2chで宣伝して、20インストール。それから伸びない伸びない。1個も増えない。
しばらくすると、突如89になった。おそらく、Make:Japan で iPhone版が紹介されたことをキッカケに、マーケットでJJYを検索したのだろう。
その後、また伸びなくなった。
福島が復帰して、再度停波したときに伸びなかったのは残念だ。
本ソフトの特徴としては、タイムコードが視覚的に分かる点があげられる。見れたからといってどうなるものでもないのだが、もしかしたらコレで理解できて別プラットホームに移植する人が出てくるかもしれない。そんな期待を込めて、画面を作ってみた。
バグがいくつかある。画面更新が59秒の時に行われてしまう。気づくと気になるが、知らなければ気付かないかもしれない。
機能的にももうちょっと配慮があってもいい。まず、開始・停止ボタンが無い。音量コントロールを全く考慮してない。バックライト制御(暗転抑制)も入れた方がいいだろう。バッファが無駄に長めで、終了しても1秒ぐらいお漏らしする。
それと、実用的にはNTPとの同期もやった方がいいだろう。SIMが差さっていれば、多くの場合に内蔵時計が信頼できるが、そうでない場合もある。
長時間運用時にズレていく点も、問題になる運用例は少ないかもしれないが、対応したいところだ。
自分的に納得いくものになる日は来るのだろうか。
2011年4月11日
JJYシミュレータ for Android
電波時計用JJYシミュレータを見て、Android版があったら便利かもなと思って作ってみた。
とりあえず作ってみました的な感じですが。
※長時間動作させっぱなしにすることは想定していません。微妙にずれていく内蔵時計をNTPなどで補正しても、無視して時刻を刻み続けます。一度同期が終わったら終了させるような使い方を推奨します。
2008年5月 6日
業務システムにおける祝日の扱いについて
某システムで、休日の設定をテキストファイルでチマチマ設定しなければならないものがあった。
ボクはそれを見て、「ダサイ」と思った。
振り替え休日とかハッピーマンデー法とかもロジックで組みやがれ! と。
技術ヲタにありがちな発想である。
最近になって、その考えは間違いだと気づいた。
祝日などは、「国民の祝日に関する法律」で定められている。これが意外とコロコロ変わって行くのだ。カレンダー屋さえも困るぐらい変わりやがってコノヤロー。
ロジックで組んでいた場合、法律改正とともにロジック変更が必要になる。設定ファイルで設定する場合も、その設定ファイルのメンテナンスが必要となるが、プログラマ未満のスキルの人でもメンテナンス可能であり、そーゆーことを考えると、設定ファイル案が有利だろう。
設定ファイルのメンテ方針も意外とハマルところである。
冒頭の某システムは設定ファイルを変更したら再起動が必要だった。
まあ、休日を参照する処理が大量にある場合、起動時に読み込んでおきたいのは分かる。しかし、おいそれと再起動できないシステムにおいて再起動を要するのはいかがなものか。
対処の運用におけるアプローチとしては、休日ファイルを書き換える日付を決めておくべきだろう。カレンダーが配布される時期になったら設定ファイルを書き換えて再起動すべしとドキュメントに書いておく。書いておくだけでなく、実行する。
冒頭の某システムは、ドキュメントに書いてあったが、引継ぎでちゃんと伝わっていなかった。年次処理は抜け落ちやすい。類似のものにドメイン更新や、SSL証明書更新がある。
対処のプログラムからのアプローチとしては、休日ファイルのキャッシュが考えられる。タイムスタンプが違っていたら読み込むとか、タイムスタンプを読み込むのもそこそこ時間のかかる処理なのでタイムアウト時間を設定して、タイムアウトしたらタイムスタンプを読み、新しかったらファイル読み込みとか。
だが、例えば予約システムなどにおいて休日は予約できないとか料金が高くなるとか、そういったものがある場合に、予約済みの日付に対して休日平日が変わってしまうことが起こると面倒だ。そこらへんのガードも考えると結構面倒くさい。
2008年4月26日
プログレスバーの更新を必要最小限の間隔で行う
表題のことを考えていたら、ブレゼンハム(Bresenham)の線分描画アルゴリズムが適用できそうなことに気づいた。
以下、C言語風の擬似コード。
e=0
while ( !EOF ) {
1行読み込み
なにかの処理
e+=1行の長さ*100
if ( ファイル長 < e ) {
プログレスバー更新
e-=ファイル長
}
}
いまどき、線分描画アルゴリズムを用いて線分を描画するシチュエーションは稀だと思う。
しかし、知っていると思わぬところで応用が利くなと思った。
前提条件として、プログレスバー1%分が1行より大きい必要がある。が、プログレスバーを表示したいのだから、その条件は満たすだろう。
満たさない場合は100%に到達せずに終わってしまうが、最後に100まで移動するコードを書いておけば、見た目はOKだと思われる。
2008年4月 1日
モバイルSOS
というわけでエープリルフールなわけですが、例によって impress がやらかしています。
ノートPCのディスプレイを点滅させて遭難信号を発信「モバイルSOS」
GIFアニメはあるが、ソフトはない。
このぐらいのソフトは作っとけよ!
っていうか俺が作ってやる!
完成↓
mobileSOS.exe
WIN32apiだけで作った軽量アプリ。ALT+F4 または ESC で終了します。
2008年1月14日
SIPで遊んでみる
12月初旬にBフレッツ&ひかり電話を入れた話は書いてなかったか。
ひかり電話を入れたら、RV-230SE というルータが来た。VDSLモデムとルータとひかり電話が一体になったモノである。
これにアナログ電話を接続できるのはもちろんなのだが、SIPクライアント(VoIP端末)を接続することも可能のようだ。
これは試すしか! と思い、フリーのSIPクライアントを探したら X-Lite というのがあったのでVistaマシンにインスコして設定してみた。
設定項目が意味不明なものが多いが、いろいろググりながら適当に項目を埋めたら設定できた。
しかし、パソコンを電話端末にするのは非常にまどろっこしい。
多くの人が、パソコンを目の前にしながら横で電卓を使っているのと同様、電話は電話機で話したほうが65536倍使いやすいと思う。
だが、ウチの電話にはナンバーディスプレイが無い。
「着信お知らせメール」のオプションをつけているので、着呼後にメールで確認できるし、RV-230SE のログでも確認できるのだが、そんな未来に知ってもしょうがない。
やはり、着呼したその瞬間に番号通知を見たい。
これはナンバーディスプレイ専用SIPクライアントを作るしか!!!
というのはひかり電話を入れた12月初旬から考えていた。
で、突然プログラミングする気になり、実装してみた。
使用言語(開発環境)は Visual C# 2008 Express Edition。
SIP はよく分からんので、X-Lite と RV-230SE の通信を Wireshark(旧Ethereal) で盗聴して解析。
通信には UdpClient クラスを利用。非同期メソッド使いまくりでマルチスレッドにはせず。
着信イベントを通信クラスからUIクラスに渡す方法(イベントとかデリゲートとか)で苦労したがなんとか実装。
ダイジェスト認証がさっぱり分からず、でもググりまくってなんとか実装。
1日で、登録(REGISTER)→着信受信(INVITE) の動作を確認するところまで行った。
あとはもうUIの世界で使いやすくしていくのみ!
といいたいところだが、SIPは謎仕様が多い。RFC全然読んでないので謎なのは当然だが、なんか Uniq ID の類が多いあたりがわけわかめ。
特に branch のマジッククッキーって何ですか? って全然調べてない。
が、個人的には RV-230SE とだけ喋れればよいので、細かいことは気にせず、先に UI を実装しようと思う。
今はまだいかにもサンプルなフォーム1個のUIなので、タスクトレイ常駐とか、電話帳逆引きで名前表示とか、そこらへんから手をつけようかなと。
2007年12月30日
Vista に Windiff
Vista に Windiff を入れようと思った。
Windiff は VC++6.0時代に重宝された、ファイル比較ツールである。UNIX の diff コマンドの GUI 版と思っていただけるとよいと思う(これで理解できる人がどれだけの割合で存在するか疑問だが)
いまさら VC++ 6.0 を入れるのもアレなので、 Visual Studio 2008 Express Edition (Visual C++ 2008 Express Edition) をインストールしてみた。
そしたら入ってなかった。
いろいろググって見ると、Windows XP Service Pack 2 サポート ツールの中に Windiff が入っているっぽい。
しかし、WGAを無事通過してダウンロードしたバイナリを実行しても、対応OSじゃない旨が表示されてインストールできない。たぶん、XPマシンにインストールして、exe だけコピってくれば動くとは思うのだが・・・。
で、またまたいろいろググって見たら、.NET時代のソース・コード差分ツールとは? [@IT] を見つけた。
WinMerge というのが .NET時代のツールらしい。
日本語版もあるようだが、本家のインストーラーから入れても日本語表示できた。EUCなファイルが文字化けしたが、設定で「.html, .rc, .xmlファイルのコードページ情報を検出する」をオンにしたら文字化けしなくなった。
それと多分 .NET時代 とはいえ、.NET Frameworkは不要だと思う。それと、タイトルに Vista を入れたが、Vista はあまり関係ない。
2007年8月 9日
GridViewのDataSourceが空の場合にヘッダが表示されない件
ASP.NET 2.0 でメニーユーズされるGridViewはハイファンクショナリでコンビニエンスだ。
・・・ルー語は面倒くさいな。
便利なのだが、機能が豊富すぎて何をどうしたらよいのか分からなくなることがある。
今日困ったのは、データが空っぽの場合に何も表示されなくなる点。ヘッダだけ表示してほしい場面は多々あるだろう。
一応、EmptyDataText というプロパティがある。これを設定しておくと、この文字列だけが表示される。だがボクはHeaderを表示してほしいのだ。
EmptyDataTemplate というのもある。ここにヘッダ相当の記述を書けば一応は解決する。
だが、同じことを2回書くのはイヤだ。作成時は問題ないと思うが、修正時にミスる可能性がある。
失敗する可能性のあるものは、失敗する。
失敗する可能性は排除しなければならない。
ググりまくったが「日本語のページを検索」をONにすると解決策が見つからない。外してググったら、複数の掲示板からリンクされているブログを見つけた。どうやらこれが最善策らしい。
Displaying GridView When No Data Exists
これはGridViewを継承して、新しくEmptyGridViewという名のコンポーネントを作っている。.aspx での記述例が無いが、 新しくコンポーネントを作る大げさ感と、EmptyDataTemplate を使って失敗する可能性を盛り込むのとを天秤に掛けて、どちらかを採用しましょう。 ShowEmptyTable は、データが無いときにヘッダだけのTABLEを表示するかのブール値。デフォルトは True なので、通常は指定しなくても問題ない。 EmptyTableRowText は、空テーブルのヘッダの下に表示するテキスト。 個人的に不満なのは、フッタに対応していない点。なので対応させた。それとC#からVB.NETに移植した。 信頼性工学の入門書としてお勧めしたい(w
仕様としては、プロパティが2つ増えている。
ところで、「失敗する可能性のあるものは、失敗する」で始まるマーフィーの法則の最新刊、21世紀版 マーフィーの法則が先月発売された。
2007年8月 8日
ASP.NET 2.0 でトランザクション
Webアプリにおけるトランザクションってのは、リクエストされたときに開始して、ページがつつがなく生成できたレスポンス時にコミットするのがほとんどであろう。
その途中でなにかエラーがあれば、もちろんロールバックする。
というわけで、意識的に書かなきゃならんのはエラー時のロールバックだけなんじゃねぇの? と思う。
Web全盛から10年は経っているので、なんか便利な機能があるはずだ! と思って調べたら、ちゃんとあった。
まず、.aspx ファイルの先頭に
<%@ Transaction="Required" %>
を書く。
これだけで、ページ全体が1つのトランザクションになる。
あとは、エラー時に ContextUtil.SetAbort() を呼び出してロールバックさせるだけ。
2007年7月27日
ORA-12571: TNS: パケット・ライターに障害が発生しました
某所でOracleを使っていると、たまに表題のエラーが出る。「ORA-12571」でググって見ると、謎の現象で解決しない例が多く見られる。
原因がさまざまであり、対策もさまざまなのだろう。
ここの環境では、一定時間通信しなかったあとでクエリを投げると出るようだ。
これはどうも、DBサーバまでの間にあるファイアウォールがTCPコネクションを切断してしまうため出ているようだ。
ファイアウォールではNATしているので、NATテーブルの飽和を防ぐために、一定時間アイドルだったTCPコネクションをNATテーブルから消してしまう。
また、NATしていなくても、TCPセッションハイジャックなどのリスクから回避するために、SPIでフィルタしてしまっているなんていう環境もあったりするだろう。
ネットワーク環境的な回避方法だと、キャッシュ時間を延ばす方法が考えられるが、むやみやたらと長時間にするわけにもいかない。
そこでクライアント側の設定での回避策。(3階層アプリならWebサーバでの設定)
TNSNAMES.ORA に (ENABLE = BROKEN) を追加する。追加する場所は以下のとおり。
HOGE =
(DESCRIPTION =
(ENABLE = BROKEN)
(ADDRESS_LIST = 〜
それに加えて、レジストリをいじってTCP KeepAlive パケットの送出間隔を短くする。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters
KeepAliveTime DWORD:0x493E0
ここで設定する値の単位は ms.
上記の 0x493E0 の場合は 300000msで 300秒で、すなわち5分。これは間にあるファイアウォールのNATテーブルタイムアウト時間より短い値に設定する。
利用者(ファイアウォール配下の端末数)が少なければ、1分とかでも問題ないだろう。それ以下にするのはちと勿体無い感じがする。
ちなみにデフォルト値は2時間だ。長すぎる。
これらの設定を組み合わせることにより、設定した間隔でKeepAliveパケットが流れるので、ファイアウォールがタイムアウトで切断してしまう現象が出なくなる。
さて、例によって定型文。レジストリの書き換えは自己責任で。書き換え後は再起動が必要。
2007年7月 7日
SQLインジェクション対策
今更だが、SQLインジェクション対策の話。
対策方法はただひとつ。SQL文を生成(文字列連結)するときに入力文字列をエスケープすること。
SQL文を生成した後でエスケープしようとしても、そこにある文字がエスケープすべき文字なのかどうかは判別不可能だ。また、SQLインジェクションが発生しているかどうかを検知するのも不可能だ。構文エラーになっていたら検知できるが、それは仮に実行してしまってもエラー終了するだけで大きな副作用は発生しない。また、実行できるSQL文になっていたら、それがSQLインジェクションなのかどうかは機械的には分からない。
「マルチステートメントなら実行できない」といった程度の対策なら可能だ。しかし、SQLインジェクションが成立するにはマルチステートメントが必須なわけではないので、それで対策完了というわけには行かない。
で、連結時にエスケープしようと思うのだが、これも結構厄介だ。調べれば調べるほど、危険な文字の存在に気づかされる。UTF-8などのわけわからない空間から攻撃されると困ってしまう。
そこで、普通は prepared statement (プリペアドステートメント:準備された文) あるいは parameterized query (パラメタライズドクエリ)を用いる。
これなら、何をブチ込んでもそれなりに解釈されて、そのままDBのフィールドにブチ込んでくれる。
もちろん、' (シングルクオーテーション)などもそのまま格納可能だ。
大量の音楽に対して 「80's J-POP」みたいなカテゴリをつけたいときなどには非常に重宝する。
それでも例外がひとつあり、LIKE句の時だけは % と _ を変換しなければならない。
2007年1月22日
Webスクリーンショット取得
Webスクリーンショットは簡単そうで難しい。特にクローラで収集したような雑多なサイトに対して取ろうと思った場合に様々な地雷が・・・。
画面サイズはどうするのか、縦長の場合にどうするか、アニメーションGIFやフラッシュなどはどのタイミングの画像を採用するか、などなど。
ポップアップも邪魔なものであり、JavaScriptで出てくるものや、IE自身がセキュリティ警告で出してくるものなど、さまざまなケースに対応しなければならない。JavaScript OFF にすれば緩和されるかもしれないが、最近はAjaxサイトで困ることが多いだろう。
それと、レンダリングエンジンはIEを採用しないと意図どおりにレイアウトされないサイトがあるので、Windowsが必須である。
という苦労は過去の話なので今は全然必要ないのだが、30分で作れるWebキャプチャ作成phpを読んだのでメモしとく。
つまりはCrenaHtml2jpgを呼び出すだけですな。
2006年12月19日
Visual Studio 2005 Professional Edition をインストールした
ものすごく久しぶりにマイクロソフトの開発環境をインストールした。
ボクの実地体験は VS6.0 で止まっており、すなわち .NET での開発をしたことがない。それでも .NET の概要は各種記事から知っているつもりだ。
で、インストールなのだが、まず、どのメディアを使えばいいのか悩んだ。
MSDN サブスクリプションのディスクを見ると、「Visual Studio 2005 Professional Edition」と「Visual Studio 2005 Professional Edition Disc 1」と「Visual Studio 2005 Professional Edition Disc 2」がある。なぜDisc番号の付いていないのがあるのだ!?
相当悩んで、とりあえず番号の付いてないのをPCのドライブに入れてから気づいた。それはDVDだった。DVDなので1枚に収まっていた。
CDとDVDは大きさが同じで困る。ラベルに透過部分が多ければ記録層の位置でDVDの区別が付きやすいんだけど、今のMSDNのディスクはベタ塗りなので気づかなかった。CDとかDVDを意味するロゴを見ればいいのだが。
インストールは適当に次へ次へで終了。ちなみに「標準」ではなく「全て」を選んだ。「全て」だと、C++ に 64bit 対応が付くのと、なんかのサンプルが付いてくる点だけ違った。容量で1割up程度なので気持ちよく全てを選んでしまえ、と。
次に、SP1を当てるかどうかで悩んだ。リリースが昨日じゃねぇか。とりあえず保留。
さて、今回の仕事は VB.NET を使うらしいので、いじってみた。VBの経験は業務でやったようなやらないような、記憶が無いのだが、プログラムを書いている途中でコピペしようとして行を移動すると文法エラーのダイアログが出てOKボタンを押すのがウザイという記憶はある。なんで使ってたんだっけかな。思い出せない。
VB.NET ではそんなにウザく無い感じでいろいろ支援してくれる。なんか Eclipse を使っているような錯覚を覚えるんですが。Eclipse を使っているのに VB 風味の文法で、ライブラリは .NET で、非常にキモチ悪い。
文法もライブラリも知らないので、ちょっとしたことでもググってサンプルを見ないと書けないのでイライラしてくる。
でも、適当に Hashtable あるかなと思ってタイプするとインテリセンスが補完してくれて、ああ、あるんだなと思ったりして、やっぱインテリセンス最高。[F1]キーでヘルプ連動とか、懐かしすぎて涙が出てくる。
あと、Professional Edition は CE 向けの開発も出来るようなので、何か作りてー!っつーか、無意味にCEマシンが欲しくなっちゃうぞ!! ・・・見なかったことにしよう。
2006年12月 8日
ココログがタイヘンなことに
そもそもココログのベースであるTypePadのベースであるMovableTypeを開発したSix Apartに、計算機概論みたいな知識が無いのが原因のような気がする。
エントリ数とかコメント数とかトラックバック数が増えたときに対数オーダーで処理時間が増えるのなら良いのだが、指数関数的に増えてないか!?と思うのだ。ベンチしてないけど。
Six Apartの中の人は情報処理工学科に入学して、時間計算量とか空間計算量とかランダウの記号とかを勉強しなおしたほうが良いと思う。
ボクは勉強してないけど。
2006年12月 1日
オルソ化空中写真ダウンロードシステムとGoogle Maps APIのマッシュアップ
でっかいJPEGを扱う で書いた、国土交通省のカラー空中写真を Google Maps API で重ねてみようとした話の続き。
いろいろググっていたらオルソ化空中写真ダウンロードシステム(試作版)ってのを見つけた。オルソ化とは、緯度経度をピッシリ合わせてGIS的に利用しやすくすることらしい。
オルソ化空中写真ダウンロードシステムとはを読むと、ISO19128のWMSインターフェイス云々書いてある。
WMSって良く分からんが、Google Maps に貼りやすそうな予感。
で、これを作った。↓
オルソ化空中写真ダウンロードシステムとGoogle Maps APIのマッシュアップ
使い方のコツとしては、広域方面に縮小できないので、他の場所に移動するときは表示モードを「地図」などに変えて移動して拡大して「国交省」モードに戻すと良いでしょう。
楽しみ方としては2つ。
国土交通省の写真は平成初期あたりなので、ちょっと古い町並みを体験できる。例えば東京都庁新庁舎やレインボーブリッジは工事中だし、フジテレビ新社屋周辺は更地だし、パレットタウン(トヨタメガウェブなど)に至っては海である。
あとは、月並みですが、Google Mapで詳細な航空写真が無い地域を見て楽しみましょう。(どちらにも無い場合もありますが)
万が一、人気コンテンツになってしまうとサーバーが大変そうだが、ウチのサーバーにはあまり影響が無い。ウチのサーバーは index.html を吐くだけで済む。タイヘンなのは Google 様と、国土交通省様。
本当は画像をキャッシュしてユーザビリティの向上と国土交通省サーバの負荷軽減を図りたいのだが、規約上コピるとマズそうなのでキャッシュは止めた。
2006年11月16日
でっかいJPEGを扱う
Google Maps API をいじっていると楽しくてしょうがないので コレを貼り付けて遊んでみようかと思った。
しかし、3800x3800ピクセルぐらいのデッカイ画像なので読込展開にスゲー時間がかかる。1枚当たり1.7秒ぐらい。Google Maps API のタイル単位に PHP で処理しようとすると、タイル生成要求ごとに読込展開してしまう。初回アクセス時に25枚ぐらい読み込まなきゃならんので、25×1.7秒という長大な時間が掛かってしまってダメダメだ。
Java Servlet なら、JPEG展開済み画像オブジェクトを管理するクラスを作ってメモリに常駐させてどうにかするのだが、PHPだとそーゆーのって無理だよな。(ボクが知らないだけかもしれないが)
Perl だと mod_perl を使えばなんとかなるかもしれないが、ちょっとトリッキーな感じがする。そこまでするならJavaれよ、みたいな。
しかし、Javaるには、環境のセットアップとかがあって面倒なので、PHPでなんとかしたい。
JPEGの指定した一部分だけを読込展開できれば、高速化できるんじゃないかと思った。今までのプログラムは、全体を展開してから、その一部分だけを採用しており、要らない部分まで展開処理をしていて無駄である。
JPEGは8x8ピクセルのブロックごとに圧縮して格納されているので、要らない部分の展開をサボっても一部分だけ取り出せるはずだ。
そして、さんざん調べた結果見つけたのが jpegtran コマンドの -crop オプション。Loss less で部分取り出し!
で、使ってみたら 0.8秒ぐらいになった。2倍の高速化!
でも、それでも遅いよなぁ。
やはり、Javaとかでオブジェクトプーリングを実装しないと実用にならん。
つーか、タイル画像を全部プレ変換してディスクに置いとくのが一番速い。
2006年11月13日
GTileLayer.isPng() の使い方
Google Maps API で GTileLayer を使おうとしたとき、実装に悩むのが isPng() である。悩まずに PNG ならtrueを返せば良いような気もするが、どうも値を見ているのか見てないのか良く分からない挙動をする。
イロイロ実験してみた結果、PNG の alpha blending(半透明)を使いたいときに ture を返すよう実装するものらしい。
なぜこのメソッドが存在するのか。
IE6は、PNGに対応しているが、アルファブレンディング付きのPNGにはちゃんと対応していない。重ねて表示したときに、半透明してくれない。だがコレには回避策があって、AlphaImageLoaderフィルタを使えば良いらしい。
ということでおそらく、isPng() は IE6 の時にAlphaImageLoaderを使うか使わないかを指定するものなのではないだろうか。
だがしかし、isPng() を true にすると、なんか挙動がおかしくなる。初回表示はいいのだが、ブラウザのキャッシュに乗っている画像(地図)を表示しようとすると画像が抜けてしまうことが頻発する。
回避策が分からず困っているんですが、どうにかならないですかね。
IE7では試していないが、AlphaImageLoaderを使わなくても正しく扱えるようになっているらしいので、この問題も起きないだろう。Windows Update でIE7が強制配布される半年後からはIE6を無視して半透明を使いたい気分。
ちなみに、透過GIFなら isPng() とか getOpacity() を実装しないでも(getTileUrl()のみ実装するだけで)フツーに重ね合わせて、透過部分は透過されて表示できる。あ、もちろんGIFだから半透明は出来ないケド。
IE7が普及するまでは、GTileLayerには透過GIFを使うのが良いような気がするのでした。
2006年11月 7日
2006年11月 5日
Ajaxはサーバー負荷が軽い
Ajaxはサーバー負荷が軽いってことに、今さらながら気づいた。
例えばGoogle Mapsは、地図をマウスでグリグリ動かしてもサーバーへのリクエストは256x256pxの静的画像の取得のみであり、サーバーは動的なページ生成を行う必要が無い。
近くのラーメン屋とかを検索すれば、動的なクエリが発生するが、それでもサーバー側はテキトーなXMLを吐くだけで良く、レイアウト込みのHTMLを作る必要が無い。
Ajaxじゃない地図だと、クライアント側で表示させたい画像やHTMLを全てサーバー側で生成する必要がある。画像の切り貼り処理と、マーカーのプロット処理をし、さらにHTMLも作って、と大忙しだ。
Ajaxにおけるパフォーマンスチューニングのツボは、「クライアント側で出来ることは極力クライアントに任せる」というところにあるのかも。
クライアントサイドスクリプトが多少遅くても、ユーザー数が増えたところで速度に変わりはないが、サーバーサイドプログラムが遅いとユーザー数に比例して遅くなってしまう。
クライアント処理を増やすのは、究極の負荷分散だなと思った。
2006年10月29日
GTileLayerとメルカトル図法
Google Maps API の話。
GTileLayerを利用すると画像の重ね合わせをすることが出来る。
詳細は端折るが、ここで引数として渡されてくる値が、緯度経度でなく、平面座標の x,y になっている。
この値を JavaScript の中(クライアント側)で緯度経度に変換するのはカンタンだ。Google Maps API に任せてしまえばよい。
しかし、サーバー側でプロットとかしたいなら、サーバー側が変換式を知っていなければならない。
Google Maps はメルカトル図法を用いているので、それの変換が必要だ。
ググってみると、緯度→Y座標 の式は見つけることが出来た。(経度→X座標はそのまんまなので問題ない。)
しかし、Y座標→緯度 の式がなかなか見つからない。緯度→Y座標 から逆関数を求められるほどボクは頭よくない。
さあ困った困ったとググリ続けて数時間。メルカトルとかMercatorとか投影とか逆投影とか逆変換とかtanとかatanとかイロイロ思いつく言葉を入れたが見つからない。
ふと発想を変えて、英語のWikipedia を見てみた。
そしたらあった。
最初からココ見りゃ良かった・・・。
2006年10月20日
測地系変換で悩む(2)
昨日の続き。
だんだん頭の中が整理されてきた。
■世界測地系
・ITRF2000
超高精度。緯度経度のほかに時刻情報(年)が必要。
何で年が必要なのかと言うと、プレートテクトニクス理論の補正のため。
すなわちcm単位の精度。
・JG2000=ITRF94=ITRF96=ITRF97
単に世界測地系と言ったらコレなのかな。
・ITRF90・ITRF91・ITRF92
よく分からんが、微妙な誤差があったのかな? 1990年代前半の規格と思われるので無視
・WGS84
GPS用。WGS84といっても微妙なバリエーションがある。
しかし、そもそもGPSの精度が微妙なのでバリエーションはキニシナイ。
精度数mの観点なら、JGD2000とかと一緒。
・まとめ
精度数mの観点なら、全部一緒。
■日本測地系
・Tokyo97
厳密な意味での日本測地系。
測量網の誤差が含まれているので、世界測地系への変換には「地域毎の座標変換パラメータ」なるものが必要。
誤差は場所によっては100m単位。特に離島。
GPS普及以前に、明治時代の基準点を使って3点測量した座標だと、コレになる。
地図に多く見られる。
・Tokyo3p
測量網誤差がないモノ。
GPSで計測して、幾何変換で日本測地系にした座標だと、コレになる。
最近作られたデータに多く見られる。
正式名称は無い。Tokyo3p の命名は コチラ
■で、どうすれば?
ここでは精度数mのレベルで考えます。
そうすると、世界測地系は全部一緒と考えられる。日本測地系は世界測地系から単純変換したTokyo3pと、測量網誤差入りのTokyo97がある。つまり、3種類の測地系が存在すると。
で、文字コード変換におけるチルダ的存在に相当するは石垣島とか与那国島。
WILLCOMのエリア確認ツールで石垣島(の隣の竹富島)を見ると、アンテナが海上にある。これは、アンテナ位置はTokyo3pで、地図はTokyo97を採用しているためにズレているのではないかと思う。
2006年10月19日
測地系変換で悩む
こんなのを作ってみた。
WILLCOMのアンテナの位置を Google Maps API でプロットするものである。
で、本題。
WILLCOMの位置情報は日本測地系を採用しているらしく、世界測地系のGoogle Mapsにプロットすると位置がずれる。なので測地系変換をしなければならない。
測地系変換が必要なのは以前から知っていた。少なくとも測量法改正の2002年の時には知っていた。
だが、いざ変換してみようと思って調べたら奥が深すぎる。
日本測地系と言っても微妙なバリエーションがある。世界測地系もバリエーションがある。準拠楕円体が微妙に違うとか。
それだけならいいが、測地網の誤差ってのもある。明治時代に決めた全国各地の基準点がずれていて、ずれたまま地図が作られてしまっているのだ。
いろいろあるので、そもそもWILLCOMが日本測地系の微妙なバリエーションの中のどれを使っているのか分からず、どんな変換をすればよいのか分からなくなった。
Google MapsもWGS84でいいのかよくわからんし。
文字コード変換の世界でも、微妙なバリエーションがある。単純な機械的計算だけで済む変換とか、テーブルが必要な変換とか。
そっちの世界であれば、機種依存文字を正しく変換できるかとか、チルダを正しく変換できるかとか、検証すべき地雷源を知っている。
しかし、測地系変換だとそのようなノウハウが無い。ウチの近所がズレずに変換出来てればOKかなとか思ってしまう。
測地系変換しまくりの人だと、北海道とか九州とかのズレを見て、採用測地系が分かってしまうような能力をつけてしまっているんじゃないかと想像する。また、測地網の誤差に関しても、「この島はスゲーずれるんだよな」とか、そんなポイントを知っているんじゃないかと思う。文字コード変換におけるチルダのように。
そんなことを考えつつ、幾何変換すら面倒で単純な平行移動だけでごまかしたらやっぱり稚内でズレている。東京・大阪あたりはズレていない模様。
しかし、ウチの最寄のアンテナ位置が現物目視確認の位置からズレている。と思ったらWILLCOMの地図でも同じようにズレていた。
頭混乱中。
2006年9月22日
ブラウザのサイズ
ユーザーはブラウザをどんなサイズで使っているのか。
いい加減、画面サイズ800x600を意識する必要は無いだろう。しかし、幅800でも横スクロールなしで表示できるようにはしておきたい。1024x768の画面で、800幅のウィンドウを開くのが、マルチウィンドウシステムとしては最適なような気がするからだ。
幅800は業界スタンダードでもある。たとえば Yahoo! のトップページは幅800になっている。
800が基準なのだが、800固定と言うのもキライだ。ユーザーがウィンドウ幅を広げたら、広げたなりにウィンドウいっぱいにコンテンツを表示させたい。
もちろん、このブログはそういう仕様になっている。
ウェブページをデザインするときは、いろんな幅を試してみることが多い。いや、ウェブページに限らず、GUIモノを作るときは適切なサイズを意識しなければならない。メインで使用している画面は1400x1050なのだが、1024x768で表示すると狭すぎないだろうかとか、800x600でも最低限機能するだろうかとか考える。
それを試す際、ボクはWindows付属アプリのペイントブラシを使っていた。具体的には次のような感じ。
[WIN]+[R] pbrush [ENTER] でペイントブラシ起動 → キャンパスサイズを 1024x768 に指定 → テスト画面をそれに合わせる
だがそれが面倒くさい。
いろいろ考えて、液晶の縁にエンピツで線を書いた。左上基準だけの線を引くとバランスが悪くカッコ悪いので、全方向から上下左右対称に線を引いた。
うぉースゲー便利だぜ。
線を引いて思ったのだが、コレを基準に液晶の背面まで黒い線を引いたら仮面ライダーカブトのゼクトが持っているPCっぽくなるかも。
ゼクトデザインだけど実用の意味もある線。
カッティングシート買ってきて貼り付けるかな。
いや、でも、VAIOロゴが中途半端に半分隠れてカッコ悪くなるなぁ。
2006年9月19日
GPolyline.fromEncoded
Google Maps API を使って経路を書く話。
先日コンナモノを作ったわけだが、車輪の再発明だった。
APIドキュメントを読んでいたところ、GPolyline.fromEncoded が目に留まった。
Google謹製Polylineフォーマットですか!!!
ボクが考えたのは64進数でデータ長ヘッダを持たせる戦略なんですが、Google謹製では32進数にデータエンドビットを加えて64キャラクタ使ってます。
そしてGoogle謹製の方が短い文字数で表現できてしまう!
さすがGoogleの中の人は頭良いな。
ということで今後は fromEncoded のフォーマットを使うことにしよう。
一応、旧フォーマットを読み込ませることも出来る。その場合も、下に表示される完成URLはGoogle謹製フォーマットになっている。
それと、経路に沿ってスクロールする機能を付けてみた。しかし、スクロールが速過ぎて見にくい。酔う。改善の余地あり。
参考例として、ウチのナビで、よみうりランドから港北ICへルート検索した結果を示してみよう。
ゆりがおか駅付近で左折した道は狭かった。なぜそこを選んだ?
あざみ野駅付近で混雑した。VICSで駅東側道路が渋滞していることから西側を走らされたが、そっちも混んでいた。
2006年9月15日
ルートデルタ
きのうの続き。
数字を単に10進数で表現するのは勿体無い。かといってバイナリの表現はURLパラメータにできない。%xxで表現できるが、余計に伸びてしまう。
BASE64のように、使えるキャラクタだけ用いて64進数で表現したらどうだろうか。BASE64にはURLパラメータとして使えない文字があるからそれは別の文字に置き換えよう。
これで、5桁+5桁ぐらいで表現できるかな。しかし、これでも大きい。
緯度経度は、前回の地点からの差分を取ると、小さい数字になるだろう。それを可変長フォーマットでつなげていくとかなり圧縮できるのではないだろうか。
可変長だと、データ長を示すヘッダが必要になる。ヘッダには緯度経度それぞれのデータ長が必要だ。それに2ビットずつ使おう。2ビットなので0〜3になる。3桁だとオーバーフローしそうなので、3のときは4桁と定義しよう。0桁は意味無いからな。0は1桁だ。さらに、符号も必要だ。初めは補数で表現しようかと思ったが、可変長データの補数は面倒だ。符号用のビットもちょうど余っているので使おう。
ということで、ヘッダは 緯度符号(1bit)・緯度データ長(2bit)・経度符号(1bit)・経度データ長(2bit) の計6ビット。ちょうど64進数の一桁を使うことになる。
そのあと、緯度経度の差分値を並べる。
これで1つの点の表現が完成。ヘッダ1文字+緯度1〜4文字+経度1〜4文字=3〜9文字で1つの点。
最初の点だけ困るな。4桁だと全世界を網羅できない。日本のどこか適当な場所を基準点として、そこからの差分にしようか。
などなど考えて作ったのがコレ。
2006年9月14日
ルートマップ
Google Maps API って、地図上に線を引けたりするんで、道順を線で引けたら便利だよな。と思った。
APIが公開されてしばらく経つので、同じことを考えている人は多くいるだろう。
ということでググッて見たら、そんなサイトを2つほど見つけた。
尚、前回書いた実用ジオコーディングの存在は、これらを見て知った。
さて、これらは両方とも、経路データをサーバー側に持つようになっている。違いは、DBのキーの取り扱いについての思想だ。
経路マップの場合はランダムな値(多分GUID)を用い、作成者だけが知ることになる(もちろん、作成者が他人に教えても良い)。
地図Zの場合はシリアル値を用い、作成されたルートは全てリストに掲載されてしまう。
「俺んちへの道順はコレだぜ!」などという私的な地図を作成する場合、地図Zは都合が悪い。また、経路マップの場合も、第三者のサーバーに経路データを置くわけで、気になる人は気になるだろう。
サーバー側に経路データを置かないとすると、URLパラメータに全てのデータを入れなければならない。しかし、仮に緯度経度をフツーに表現すると、1つの地点だけで20文字になってしまう。10地点で200文字。多すぎるよな。
つづく
2006年9月13日
ジオコーディング
ジオコーディングとは、住所などの情報から緯度経度を求めることである。それをやるモノをジオコーダという。
というのは最近知った話。気づいたキッカケは Google Maps API のドキュメントを読んでいたところ、Geocode に関する記述があったから。
しかし、日本国内では、このAPIを呼んでもエラーが返るだけ。使えないのかよぉ。残念。
でも、別のソリューションがあった。
■Google Maps APIで日本の住所から緯度・経度を求める方法
なぜ、こっちでは利用できるのか不明。有名になっちゃうと使えなくなっちゃったりして?
■日本版 Yahoo! Widgets の地図情報ウィジェットの裏側にジオコーダが!
いいっすね。コレ。でもこれも地図情報ウィジェットのアップデートとともに対策されそうな予感。
これは、東京大学空間情報科学研究センターがやっているRESTサービス。実験なので利用制限が厳しそうと思ったが、商用利用も可能なようで。
他にも商用製品があったりするが、よく分からんので省略。やる気のある製品なら 周りの AdSense に表示されているかも。
2006年9月 7日
うるう秒廃止?
1秒の定義は、昔は地球の自転から決めていたが、今は原子時計が決めている。自転の方が揺らぎがあって正確ではないからだ。
だが、原子時計が決めた時間で刻んでいったら、自転と合わなくなり、太陽の動きと時刻がリンクしなくなって不都合がある。
ということで、うるう秒で補正する。
だが、うるう秒の補正は面倒くさい。面倒なので1時間単位で補正してやれ! という話がITUの中にある。
事実上の先送りだ。1年に1秒ずれたとしても、3600年は補正の必要が無い。100世代後の子孫も安心!
個人的には、日常生活用の時計は秒の長さを可変にして、常に補正しつつ、うるう秒は必要としない運用が良いかなぁと思う。秒の長さの厳密性が重要な分野だけ、原子時計な時間を使えば良いんじゃないの? と。
しかし、よく調べたら、1958年から1972年までは、そうしていたらしい。→協定世界時
閏秒によってずれを補正するようになったのは1972年からである。それまでは、地球の自転の変動にあわせて原子時計の周波数を一定値オフセットして世界時の進行に近似させ、必要に応じて0.1秒のステップ調整を行うことで、世界時とのずれが常に0.1秒以内になるようにしていた。しかし、周波数のオフセット値を毎年調整する必要があり、これは困難なものであった。そのため、1972年から1秒の閏秒による現在の方式に変更された。
高度情報化社会の今なら、オフセット調整も面倒じゃないと思うけどな。
ところで、時刻の表現方法に、ISO 8601というものがある。これを知らないプログラマはモグリだ!
というのはウソで、ボクも使っているところを1度しか目にしたことが無い。XMLやってるときだったかな?
2006年8月29日
サーバーサイドで画像回転
サーバーサイドで画像を回転させたくなった。
system 関数で convert コマンドを呼べば一発だろう。しかし、system 関数はあまり使用したくない。コマンドの起動、すなわちプロセスの生成はコストの高い処理だ。
できたらモジュールを使って回転させたい。
最初、PHPで作ってみた。PHPで画像処理というと、GDを使ったImage関数群がよいだろう。で、回転関数を調べたら imagerotate が見つかった。しかし、この関数だけ、呼び出したときに undefined とか言われる。スペルミスか? ドキュメントからコピペだ! それでもダメ。
ドキュメントにはこう書いてある。
注意: この関数は、PHP がバンドル版の GD ライブラリでコンパイルされている場合のみ使用可能です。
意味分からん。Debian で aptitude install php4-gd してインスコした環境ではダメなのか。これだけのためにPHPを make すんのは面倒だよなぁ。
PHP がダメなら Perl を使ってやる!
ということで Perl のモジュールを調べ始める。
Perl GD で、同じ地雷踏んだらイヤだな。PerlMagick を使ってみよう。aptitude install perlmagick でインスコ。
しかし、Rotate関数を使ってみたら遅かった。角度指定が任意角度なので、90度回転であっても真面目に一次変換とかしているのだろう。ボクは90度回転に特化した高速処理をしたいのだ!
Transpose がそれなのか? いや、これは縦横入れ替えだ。x軸 y軸 を単に入れ替えるので、画像が鏡像になってしまう。
PerlMagick 捨て。次は Perl GD だ。PHP GD で制約があったのでちょっと不安だが、aptitude install libgd-gd2-perl でインスコ。
その結果、copyRotate90 で高速回転できた。
2006年6月28日
窪塚電卓
ちょっと思うことがあって、作ってみた。水平方向に物を投げて、高さ h, 水平距離 d の地点に落ちた場合、初速度は? という計算機。(ただし、空気抵抗は無視できるものとする。)
名前の由来は言うまでも無い。何故今日作ったかというのも言うまでも無いかな?
