自作の、Spatial(GIS)関連の関数をMySQLに追加するプラグインの関数をひとつひとつ動作確認しながら紹介するシリーズ。
https://sakaik.hateblo.jp/entry/20260215/mysql_spatial_functions_plugin
STX_PointonSurface(geom)
与えられたジオメトリ内にあることが保証されている点をひとつ返す。POINTでもLINESTRINGでも動作するが、おそらくPOLYGONで使うことが多そう。
「ポリゴンの内側にその点がある」というだけであり、点の位置そのものには意味はない(ようなシーンで使う)。
動作紹介
- POINT上の代表点はそのPOINTそのもの
mysql> SELECT ST_AsText(STX_PointOnSurface(ST_GeomFromText('POINT(2 5)'))) p;
+------------+
| p |
+------------+
| POINT(2 5) |
+------------+
1 row in set (0.000 sec).
- LINESTRING上の代表点は線の上に採られる。この場合は始点が代表点として得られている
mysql> SELECT ST_AsText(STX_PointOnSurface(ST_GeomFromText('LINESTRING(2 5, 2 10)'))) p;
+------------+
| p |
+------------+
| POINT(2 5) |
+------------+
1 row in set (0.000 sec).
- POLYGONの代表点はその重心であることが保証されているわけではないが、この場合はいいかんじに重心が得られている(アルゴリズム的にはまず重心を求めてそれがPOLYGON内なら採用、それ以外なら平行移動して求めるということをやっているので、これは正しい動き)
mysql> SELECT ST_AsText(STX_PointOnSurface(ST_GeomFromText('POLYGON((0 0, 0 5, 5 5, 5 0, 0 0))'))) p;
+----------------+
| p |
+----------------+
| POINT(2.5 2.5) |
+----------------+
1 row in set (0.000 sec).
- POLYGONの重心がPOLYGON外となる場合は良きに計らってPOLYGON内であることが保証されている点を返してくれる
mysql> SET @g=ST_GeomFromText('POLYGON((1 1, 5 1, 5 5, 4 5, 4 2, 2 2, 2 3, 1 3, 1 1))');
mysql> SELECT ST_AsText(STX_PointOnSurface(@g)) s;
+--------------+
| s |
+--------------+
| POINT(4.5 4) |
+--------------+
1 row in set (0.000 sec)
.
開発秘話(秘密という程でもない)
当初、本関数はPOLYGONにのみ対応していた。このブログを書くための動作確認の中で発覚し、POINT/LINESTRING/POLYGONに対応するように修正を行った。