MySQLで、もっとたくさんのSpatial(地理空間情報)関数を使いたい!ということで、AIのチカラを借りてプラグインとして公開した話を、先日書きました。
sakaik.hateblo.jp
AIのチカラは素晴らしいもので、こちらがやりたいことを明確にさえしていれば、かなり良いものを短時間で作ってくれると感じます。開発者がコードの細かいところを把握していない点を含め、AIによる品質についてご意見がある方もいるかと思いますが、キャッチコピーは「ないよりもあるほうがいい」で、まずはそれっぽいものを揃えるところから入ることにしました。私のほうでこれからひとつひとつの関数を確認しながら変な動作を修正していく予定ですが、つまり「バグ報告ドリブン開発」ですので、思った動きと違う、みたいな声をいただくと、確認や修正の優先順位が上がっていきます。何卒よろしくお願いします。
私が必要と感じた関数、全57個の実装が一旦終わったので、これから動作確認と紹介がてら、ひとつひとつの関数について書いていこうと思います。
最初となる今回はシンプルな関数として STX_NPointsです。
STX_NPoints()
似た関数としてMySQL本体が持つ ST_NumPoints() があります。しかしその関数は、名前から想像しにくいですが、LineStringにしか対応していないのです。今回実装した STX_NPoints()は多くの型に対応しています。
動作紹介
- POINT型の個数を知ることには特に意味はない(だって必ずひとつだから)のですが、ちゃんと動作します。
mysql> SELECT STX_NPoints(ST_GeomFromText('POINT(1 2)')) g;
+------+
| g |
+------+
| 1 |
+------+
1 row in set (0.000 sec)
- LINESTRINGでも動作します。3つの点があるので3と返ってきます。ST_NumPoints() と同じ動作のはずです。
mysql> SELECT STX_NPoints(ST_GeomFromText('LINESTRING(1 2, 3 4, 5 6)')) g;
+------+
| g |
+------+
| 3 |
+------+
1 row in set (0.000 sec)
- POLYGON でも動作します。四角形を描いて元に戻ってくる指定なので、感覚的には 4 なのですが、「始点に戻った点」もカウントするので 5 となります。PostGISでも同様の動作なので、POLYGONに対してはそういうものということで。
mysql> SELECT STX_NPoints(ST_GeomFromText('POLYGON((1 2, 3 4, 5 6, 5 1, 1 2))')) g;
+------+
| g |
+------+
| 5 |
+------+
1 row in set (0.000 sec)
- 中をくり抜くPOLYGONでもカウントしてくれます。大きな四角の中に三角形をくり抜くもので、外側のポリゴン四角形で5点、くりぬき三角形で4点の計「9」と返ってきます。
mysql> SELECT STX_NPoints(ST_GeomFromText('POLYGON((1 1, 11 1, 11 11, 1 11, 1 1),(3 3, 6 3, 5 6, 3 3))')) g;
+------+
| g |
+------+
| 9 |
+------+
1 row in set (0.000 sec)イメージとしてはこんな形を表しています。測地系指定していないので、背景地図は気にしないでください。

- マルチ系の動作確認です。マルチポイントを与えても正しく、含まれるポイント数を返してくれます。他のマルチ系の動作例は割愛。
mysql> SELECT STX_NPoints(ST_GeomFromText('MULTIPOINT(1 2, 3 4, 5 6, 7 8)')) g;
+------+
| g |
+------+
| 4 |
+------+
1 row in set (0.000 sec)
- 測地系を指定したときの動作も問題ありません。POINTなので1が返る。
mysql> SELECT STX_NPoints(ST_GeomFromText('POINT(35 135)',6668)) g;
+------+
| g |
+------+
| 1 |
+------+
1 row in set (0.000 sec)
- 4点を結ぶポイント(SRID=6668)も、もちろん正常に動作
mysql> SELECT STX_NPoints(ST_GeomFromText('LINESTRING(35 135, 35.5 135, 35.3 135.5, 35 135.5)',6668)) g;
+------+
| g |
+------+
| 4 |
+------+
1 row in set (0.000 sec)
- 測地系付きPOLYGONも問題なし。
mysql> SELECT STX_NPoints(ST_GeomFromText('POLYGON((35 135, 35.5 135, 35.3 135.5, 35 135.5, 35 135))',6668)) g;
+------+
| g |
+------+
| 5 |
+------+
1 row in set (0.000 sec)
ということで、簡単な関数から紹介していこうと思ってこの関数を選んだのですが、簡単すぎて(書くほうも)ちょっと物足りない気分になる STX_NPoints()関数の紹介でした。
