Gauche から wkb (well-known binary) を読み込めるライブラリを書きました

wkb とは

GIS 分野において、点や線分、多角形を扱うフォーマットです。
binary の名の示すとおり、バイナリフォーマットです。

wkb と wkbhex

wkbhex は wkb を hex 表記したもので、0x00 0x80 0xff 0x00 というバイト列ならば、"0080FF00" といった文字列表記になります。

みどころ

本題です。
wkb パーサは実のどころどうでもよくて、wkbhex をバイナリポートに変換するルーチンです。

(define (read-hex-string :optional (iport (current-input-port)))
  (glet* ([higher (read-char iport)]
          [lower (read-char iport)])
    (string->number (string higher lower) 16)))

(define (open-input-hex-string str)
  (make <virtual-input-port> :getb (cute read-hex-string (open-input-string str))))

read-hex-string はポートを引数に取ります。
glet* は and-let* のジェネレータ版です (要 gauche.generator)。
and-let* は #f が評価された時点で停止し、#f が返りますが、glet* は (eof-object) が評価された時点で停止し、(eof-object) が返ります。
read-hex-string は2バイト(正確には2文字)をポートから読み込み、読み込まれた文字列を数値に変換して返します。
つまり、ポートに "FFFE" という文字列が残っている場合、255, 254 という数値を順番に返します。
ポートの終端までたどり着いた場合は glet* により (eof-object) が返ります。
つまり、read-hex-string はジェネレータです。

open-input-hex-string は、文字列を受け取り、バイナリとして読み込めるポートを返します。
wkbhex to wkbトランスレータです。
read-hex-string は 0-255 の数値、もしくは (eof-object) を返すので、virtual-input-port の :getb に突っ込むだけでバイナリデータを読み込むことができるポートを作成できます。

ちなみにエラーチェックがないのでつけるべきですね ;-)

そのうち

Gauche のジェネレータは面白いのでなんか書きたい

課題

  • 2次元座標にしか対応していないので、多次元座標に対応させたい
  • wkb/wkbhex の出力もしたい