MySQLに新たなGIS(Spatial)関数 ST_Perimeter()を実装する

MySQLには (特にPostGISと比べて) 対応している空間関数がとても少ない」と、この7年間言い続けてきました。
一方で、MySQL 8.0 以降(正確には5.7以降)のGIS関数は Boost::Geometryという専門家のようなライブラリを活用して、独自実装を避けるようになった、ということもお伝えし続けてきました。

・・・この2つの情報を組み合わせると、
「 Boost::Geometryライブラリの関数を呼び出すコードを書けば、MySQLにもどんどんGIS関数を追加できるのではないか」
という必然に行き着きます。

・・・これに気づくまでに7年かかった。。。


ということで、Polygonの周長を返す ST_Perimeter() 関数を実装してみました。
Spatial機能に関する背景情報や実装のお話などは、先日のMyNA望年LT大会で結構言い尽くしたので、発表資料をここに上げておきます。ご参照ください。

speakerdeck.com


 実装の方法は、「まねっこ作戦」です。実装済の似たような関数を探して、自分が実装したい関数との差異を把握し、活かせるところを活かし異なるところは修正したり実装したりするという流れです。今回 ST_Perimeter()関数をターゲットにしたのは、

  • Polygonのみに対応している関数である(pointやlinestringが渡されたらエラーにするだけなのでシンプル)
  • 戻り型も「長さ」というわかりやすい1つの数値を返すだけである

といったシンプルな関数であるからです。まずこのやりかたで動くものが作れるのか、という「おためし」みたいなものですね。

 当初、まねっこの参照元にした関数が測地系に対応していない関数で、実装してみたら一見ちゃんと動いたように見えたものの(デカルト座標)、測地系を指定したらエラーになってしまいました。改めて ST_Area() という、まさに「ポリゴンを受け取って数値を返す」というピッタリの関数を見つけ出し、今回の実装に到ったのでありました。
 Boostに頼りっきりの関数、測地系に対応していない関数、MySQL側で結構たくさん処理をする必要がある関数、などなど色々な実装が混在しているのだなぁと、ソースコードを見て思いました。



 実装方法はわかったので、全ての関数をこのようなシンプルな方法で作れるとは思いませんが、できる関数はどんどん増やしていけたらいいなぁと考えています。

MySQL本家にもコントリビュート出してみました。Affects me (Impact on me) ボタンを押していただけると、中の人の注目度も少し上がって受け入れてもらいやすいかもしれないので、よかったらよろしくお願いします。(スライドにも書いた通り色々タイミングが悪いようで、なかなか受け入れてもらえそうな気配を感じることができていません。。。)
bugs.mysql.com






※本記事はRDBMS-GIS(地理情報・位置情報) Advent Calendar 2025の23日目の記事としても登録しました
qiita.com
※本記事はMySQL Advent Calendar 2025の2枚目23日目の記事としても登録しました
qiita.com