ちょっとしたメモ

RAPを使ったRDFグラフの視覚化と日本語処理

新サーバーになって(今ごろ)ようやくRAP - RDF API for PHPを使う環境が整ったので、何か面白いことはないかと考えていたら、この4月にvisualizeメソッドが追加されていたことに気付いた。手元でRDFグラフを視覚化できれば便利だと、テストツール「RAPによるRDF/XMLのチェックと視覚化」を作成してみる。メソッド自体は難なく使えたが、日本語を扱うのはなかなかやっかいだったので、関連事項をいくつかメモしておく。

このvisualizeメソッドは、RAPパーサで生成したRDFモデルからdotファイルを作り、それをGraphvizで処理してグラフ図を描くというもの。したがってGraphvizとそれに付随するいくつかのライブラリが必要だが、これらはごく標準的なconfigure, make, make installでインストールできるので、問題はない。あとはRAPのファイルをいくつか新しいものに入れ替えたら、あっさりとグラフが描画できた。

しかし、RAPで日本語を扱うのは少々ややこしい。せっかくのツールをスムーズに利用できるよう、いくつかポイントを挙げておこう。

パーサーが日本語をエスケープする処理を止める

親切というかお節介というか、RAPのパーサはモデルを生成する時にユニコード文字列をNFCに変換する。そのため、マルチバイト文字は全て\uHHHHの形になってしまい、実用に堪えない。これはグラフ描画以前の、トリプルの段階の話なので、単純なRSSリーダーのようなものにも使えなくなってしまう。

この処理を無効にするには、constants.phpファイルの「Parser」セクション先頭にある定数UNIC_RDFFALSEに変更する。

グラフ図に日本語を表示させる

Graphvizは適当なフォントさえあれば日本語も表示できるはずなので、sazanamiフォントなどのTrueTypeフォントをダウンロードすればうまく行きそうなものだが、これがなかなか成功せずに苦労した。最終的には、次のような手順を取った。

  • 日本語TrueTypeフォントをダウンロードし、Graphvizの標準フォントパスのどこか(例えば/usr/share/fonts/truetype/)にインストールする
  • sazanami-mincho.ttfのようなハイフン付きの名前はうまく認識されないようなので(これが分かるまでにずいぶん試行錯誤した)、mincho.ttfなどの名前でシンボリックリンクを作る
  • constants.phpの最後「GRAPHVIZ」セクションにある$graphviz_paraという配列で、それぞれのスタイルに指定されているfontnameminchoに変更する
  • データをUTF-8としてパースする(GDの設定による。後述)

RAPのパーサ(あるいはPHPのXMLパーサ?)は、要素名や属性名に日本語があるとエラー扱いするので、日本語は属性値もしくは要素内容としてのみ使えることになる。

少し大きめの日本語データを処理すると画像が壊れる現象に対処する

RSSとかFOAFなどの身近な日本語RDFデータをグラフ描画しようとすると、ブラウザでは「この画像は壊れています」と表示されたり、壊れた画像アイコンになったりする。サイズが大きすぎるせいかと思ってデータを削ってみたところ、3KB程度まで切りつめないと描画ができないようだ。これでは、練習問題としてのRDFを視覚化してみる程度の役にしか立たず、面白くない。

試してみると、EUC-JPやShift_JISならば大きなデータでも図形は描ける(日本語は文字化けするが)。どうやらGDのバグか、UTF-8の日本語データを処理させるとき、サイズが3KB程度を越えるとsegmentation errorが出てしまう模様。しかしGDは日本語表示のためにはUTF-8を要求するのだ!

根本的な対応としては、UTF-8ではなくEUC-JPを受け付けるようなオプションを付けて、GDをコンパイルし直すしかないだろう。そこまでやる気はしないので、今回のテストでは、画像サイズを縮小して全体像を見たい時にはEUC-JP、比較的細部を見たい時はデータサイズの制約付きでUTF-8とすることにした。

RDFを視覚化する時、RSSなどの現実のデータではグラフはとてつもなく大きくなって大変なので、dotのsize属性で画像の最大サイズを制限しておくほうがいいだろう。RdfUtil.phpファイルのvisualizeGraph関数でdotデータを生成している部分($dot .= ...という式があるところ)で、size="10,20"などと書き加える。この属性値は横、縦の最大値をインチ単位で示す。標準で画面出力は96dpiとされているが、マージンを少しとるので、ほぼ100倍がピクセル数と思えばよい。size="10,20"ならばおよそ1000 x 2000 px以内の画像ということだ。

XMLなどの構文からグラフがイメージできないと、どうしてもRDFは分かりにくいと感じてしまうので、こうしたツールを利用して、疑問を持ったらすぐにRDFを視覚化してみるといいと思う。

関連メモ:
map - genre: rdf. at