以下の内容はhttps://sakaik.hateblo.jp/entry/20260220/STX_IsRing_funcより取得しました。


MySQL GIS拡張関数: STX_IsRing()

MySQL Pluginの機能を使って、MySQLにSpatial(GIS;地理空間情報)データを扱う関数を爆増させる試みをしています。
MySQL Spatial Functions Plugin を公開しました(α版) - sakaikの日々雑感~(T)編

検証しながら関数を紹介していくエントリー、6個目の関数は IsRing です。

ST_IsRing()

 引数で与えられた LINESTRINGが「閉じているか」を検証して True/False( 1/0 ) を返す関数です。MySQL標準には似た関数として ST_IsClosed() というのがありますが、こちらは始点と終点が同じであればTrueと判定されるのに対し、本関数は線のクロスや重なりを許さない(閉じているとは見做さない)点が異なります。
 あくまでも LINESTRING専用の関数であることに注意してください。POINTはもちろん、POLYGONを与えてもエラーになります。

動作紹介

  • 基本動作。1辺10の四角形(に見えるようなLINESTRING)は「閉じている」と判定されます
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 0 0)')) ir;
+------+
| ir   |
+------+
|    1 |
+------+
1 row in set (0.000 sec)
  • 始点まで戻りきれずに手前で止まっている(0 1)線は、もちろん「閉じていない」です
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 0 1)')) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • 線で囲まれるエリアが P の字のように始点を通り過ぎて下に延びている場合、塗りつぶし的には閉じているのですが、当関数の判定では「閉じていない」です。あくまでも始点と終点が同じであることが条件
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 1 -1)')) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • 一部に△のように頂点としても閉じた部分を持つ線(ここではσをひっくりかえしたような形)も「閉じていない」です。飽くまでも始点と終点が(以下略)
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 10 0)')) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • 先ほどのσをひっくりかえした形(_△)で、もう1線追加して始点に戻るようにしても、線が被っているのは「閉じていない」と判定されます。ここが IsRingの厳密なところ
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 10 0, 0 0)')) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • 同じ図形を標準関数の ST_IsRing() で判定すると、(始点と終点が一致しているので)「閉じている」と判定されます。面になり得るか面としてはおかしな状態かの判断基準の違いが、この2つの関数にはあります
mysql> SELECT ST_IsClosed(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 0 10, 10 0, 0 0)')) ir;
+------+
| ir   |
+------+
|    1 |
+------+
1 row in set (0.000 sec)
  • 蝶蝶(またはキティさんのリボン)のような形を描く線は、線が交叉してしまうところが「囲まれた空間」とは言えないので、「閉じていない」と判定されます
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 5 -3, 0 0)')) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)
  • もうお分かりですね。ST_IsClose()なら蝶蝶ラインも「閉じている」と判定されます。
mysql> SELECT ST_IsClosed(ST_GeomFromText('LINESTRING(0 0, 10 0, 10 10, 5 -3, 0 0)')) ir;
+------+
| ir   |
+------+
|    1 |
+------+
1 row in set (0.000 sec)
  • POINT型だとエラー(LINESTRING専用の関数です)
mysql> SELECT STX_IsRing(ST_GeomFromText('POINT(2 3)')) ir;
ERROR 3516 (22S01): LINESTRING value is a geometry of unexpected type POINT in stx_isring.
  • POLYGONでもエラー(LINESTRING専用関数です)
mysql> SELECT STX_IsRing(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')) ir;
ERROR 3516 (22S01): LINESTRING value is a geometry of unexpected type POLYGON in stx_isring.
mysql> SELECT ST_IsClosed(ST_GeomFromText('POLYGON((0 0, 10 0, 10 10, 0 10, 0 0))')) ir;
+------+
| ir   |
+------+
| NULL |
+------+
1 row in set (0.000 sec)
  • JGD2011の地理座標系を指定しても、もちろん正しく判定されます。これは「閉じている」例
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(35 135, 35 135.5, 35.5 135.5, 35.5 135, 35 135)',6668)) ir;
+------+
| ir   |
+------+
|    1 |
+------+
1 row in set (0.000 sec)
  • 同じく、線がもとの場所に戻りきれなかった「閉じていない」例です
mysql> SELECT STX_IsRing(ST_GeomFromText('LINESTRING(35 135, 35 135.5, 35.5 135.5, 35.5 135, 35.1 135)',6668)) ir;
+------+
| ir   |
+------+
|    0 |
+------+
1 row in set (0.000 sec)

追加情報

 実装する関数をAIと相談している時に出てきたこの関数。「たしかクローズ判定する関数は既にあったよな」と調べて、というかそれすらAIとお話して情報を得るのですが(もちろんその後でマニュアルをちゃんと参照します)、そこで本エントリで紹介したような違いを理解しました。
 線分を集めてPOLYGON化する過程で、この関数を使って「POLYGONになりうるか」を判定するのに使います。






以上の内容はhttps://sakaik.hateblo.jp/entry/20260220/STX_IsRing_funcより取得しました。
このページはhttp://font.textar.tv/のウェブフォントを使用してます

不具合報告/要望等はこちらへお願いします。
モバイルやる夫Viewer Ver0.14