空間関係関数は、2つの幾何値 g1 と g2 の間の関係をテストし、正確なオブジェクトの形状を使用します。戻り値1と0はそれぞれ真と偽を表し、距離関数は距離値を返します。
OceanBaseデータベースが現在サポートしている空間関係関数には、ST_Intersects()、ST_Contains()、ST_Distance()、ST_Distance_Sphere()、ST_Within()、ST_Crosses()、ST_Overlaps()、_ST_Touches()、および ST_Equals() が含まれます。
ST_Intersects
ST_Intersects()関数は、g1が空間的にg2と交差するかどうかを示すために1または0を返します。構文は次のとおりです:
ST_Intersects(g1, g2)
ST_Contains
ST_Contains()関数は、g1がg2を完全に含むかどうかを示すために1または0を返します。構文は次のとおりです:
ST_Contains(g1, g2)
ST_Distance
ST_Distance()関数は、幾何学的パラメータの空間参照システム(SRS)の長さ単位で測定されるg1とg2の間の距離を返します。構文は次のとおりです:
ST_Distance(g1, g2 [, unit])
ST_Distance()は、返される距離値の線形単位を指定するオプションのunitパラメータをサポートしています。unitパラメータを指定した場合、オプションのunitパラメータの単位で測定されます。
いずれかのパラメータが幾何学的に無効な場合、結果として任意の数値が返される可能性があります。または、エラーが発生する可能性があります。中間または最終結果がNaNまたは負の数を生成した場合、ER_GIS_INVALID_DATAエラーが報告されます。 例:
obclient [test]> SET @geo1 = ST_GeomFromText('POINT(1 1)', 4230);
Query OK, 0 rows affected
obclient [test]> SET @geo2 = ST_GeomFromText('POINT(3 3)', 4230);
Query OK, 0 rows affected
obclient [test]> SELECT ST_Distance(@geo1, @geo2);
+---------------------------+
| ST_Distance(@geo1, @geo2) |
+---------------------------+
| 313709.8158791322 |
+---------------------------+
1 row in set
obclient [test]> SELECT ST_Distance(@geo1, @geo2, 'metre');
+------------------------------------+
| ST_Distance(@geo1, @geo2, 'metre') |
+------------------------------------+
| 313709.8158791322 |
+------------------------------------+
1 row in set
obclient [test]> SELECT ST_Distance(@geo1, @geo2, 'foot');
+-----------------------------------+
| ST_Distance(@geo1, @geo2, 'foot') |
+-----------------------------------+
| 1029231.6793934782 |
+-----------------------------------+
1 row in set
ST_Distance_Sphere
ST_Distance_Sphere()関数は、球面上のPointまたはMultiPointパラメータ間の最小球面距離をメートル単位で返します。構文は次のとおりです:
ST_Distance_Sphere(g1, g2 [, radius])
オプションのradiusパラメータはメートル単位で指定する必要があります。radiusパラメータが存在する場合でも正の数でない場合、ER_NONPOSITIVE_RADIUSエラーが発生します。距離が倍精度数の範囲を超えると、ER_STD_OVERFLOW_ERRORエラーが発生します。
2つのジオメトリパラメータがいずれも地理空間参照系(SRS)内で有効なPointまたはMultiPoint値である場合、返される値は(半径radius)球面上の2つのジオメトリオブジェクト間の最短距離です。省略した場合、デフォルトの半径は平均半径に等しく、(2a+b)/3として定義されます。ここで、aはSRSの長半径、bは短半径です。
ST_Distance_Sphere()サポートするジオメトリパラメータの組み合わせは、PointとPoint、またはPointとMultiPoint(任意のパラメータ順序)です。少なくとも1つのジオメトリオブジェクトがPointでもMultiPointでもなく、そのSRIDが0の場合、ER_NOT_IMPLEMENTED_FOR_CARTESIAN_SRSエラーが発生します。少なくとも1つのジオメトリがPointまたはMultiPointではなく、そのSRIDが地理SRSを指す場合、ER_NOT_IMPLEMENTED_FOR_GEOGRAPHIC_SRSエラーが発生します。いずれかのジオメトリが投影されたSRSを参照する場合、ER_NOT_IMPLEMENTED_FOR_ProjectED_SRSエラーが発生します。
例:
obclient [test]> SET @pt1 = ST_GeomFromText('POINT(0 0)');
Query OK, 0 rows affected
obclient [test]> SET @pt2 = ST_GeomFromText('POINT(180 0)');
Query OK, 0 rows affected
obclient [test]> SELECT ST_Distance_Sphere(@pt1, @pt2);
+--------------------------------+
| ST_Distance_Sphere(@pt1, @pt2) |
+--------------------------------+
| 20015042.813723423 |
+--------------------------------+
1 row in set
ST_IsValid
ST_IsValid()関数のパラメータジオメトリが有効である場合、1を返します。パラメータジオメトリが無効な場合、0を返します。ジオメトリの有効性はOGC規格によって定義されています。構文は次のとおりです:
ST_IsValid(g)
唯一有効な空のジオメトリオブジェクトは、空のジオメトリオブジェクトの集合値として表されます。この場合、ST_IsValid()1を返し、GISのEMPTY値、例えばPOINT EMPTYはサポートされていません。
obclient [test]> SET @ls_test1 = ST_GeomFromText('LINESTRING(0 0,-0.00 0,0.0 0)');
Query OK, 0 rows affected
obclient [test]> SET @ls_test2 = ST_GeomFromText('LINESTRING(0 0, 1 1)');
Query OK, 0 rows affected
obclient [test]> SELECT ST_IsValid(@ls_test1);
+------------------+
| ST_IsValid(@ls1) |
+------------------+
| 0 |
+------------------+
1 row in set
obclient [test]> SELECT ST_IsValid(@ls_test2);
+------------------+
| ST_IsValid(@ls2) |
+------------------+
| 1 |
+------------------+
1 row in set
ST_Within
ST_Within()関数は、g1が空間的にg2内にあるかどうかを示すために1または0を返します。ST_Contains()とは逆の関係にあります。構文は以下のとおりです:
ST_Within(g1, g2)
ST_Crosses
ST_Crosses関数は、g1が空間的にg2と交差しているかどうかを示すために1または0を返します。g1とg2が交差している場合は1を返し、交差していない場合は0を返します。また、ST_Crosses関数は空間インデックスをサポートしています。
ST_Crosses(g1, g2)とST_Intersects(g1, g2)はどちらも空間関係関数であり、2つの幾何オブジェクトの空間上の関係を判断するために使用されますが、その定義と用途は若干異なります。
ST_Intersects(g1, g2)関数は、2つの幾何オブジェクトが空間的に交差しているかどうかを判断するために使用されます。これは、少なくとも1つの共通点(境界と内部を含む)を共有していることを意味します。2つのオブジェクトが点、線、または面で重なっている部分があれば、
ST_Intersects(g1, g2)は1を返します。ST_Crosses(g1, g2)関数は、2つの幾何オブジェクトが「交差」しているかどうかを判断するために使用されます。これは、幾何学において特定の定義があります。1つのオブジェクトがもう一方のオブジェクトの内部を部分的に貫通している必要があります。
具体的には、2つの線分幾何オブジェクトについて、それらが2点以上で交差し、内部でも交差する場合、ST_Crosses(g1, g2)は1を返します。線分と面の幾何オブジェクトについて、線分が面の内部を貫通する場合、ST_Crosses(g1, g2)は1を返します。
ST_Intersects(g1, g2)とは異なり、ST_Crosses(g1, g2)は2つのオブジェクトの完全な重なりや境界の接触を考慮しません。
ST_Intersects(g1, g2)は2つの幾何オブジェクトに任意の種類の交差があるかどうかを検出しますが、ST_Crosses(g1, g2)は1つのオブジェクトがもう一方のオブジェクトを貫通しているかどうかを特に検出します。例えば、道路が土地を貫通しているかどうかを知りたい場合はST_Crosses(g1, g2)を使用します。その土地を覆ったり触れたりするすべてのルートを見つける必要がある場合はST_Intersects(g1, g2)を使用します。
構文は以下のとおりです:
ST_Crosses(g1,g2)
例は次のとおりです:
obclient > select st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))'));
この例では、ST_Crosses関数は、1点(1,1)から11点(11,11)への直線である線形幾何オブジェクトが、点(0,0)、(0,10)、(10,10)、(10,0)、(0,0)で構成される正方形である多角形幾何オブジェクトを貫通しているかどうかを判断します。結果は1であり、線が多角形を貫通していることを示しています。
結果は次のとおりです:
+------------------------------------------------------------------------------------------------------------------+
| st_crosses(st_geomfromtext('LINESTRING(1 1, 11 11)'), st_geomfromtext('POLYGON((0 0, 0 10, 10 10, 10 0, 0 0))')) |
+------------------------------------------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------------------------------------------+
1 row in set
ST_Overlaps
ST_Overlaps(g1,g2)関数は、2つの幾何オブジェクトg1とg2が空間的に部分的に重なっているかどうかを判断し、1または0を返します。ただし、互いに完全に含まれるわけではありません。g1とg2が重なっている場合は1を返し、重ならない場合や一方がもう一方を完全に含む場合は0を返します。また、ST_Overlaps(g1,g2)関数は空間インデックスをサポートしています。
2つの線分幾何オブジェクトについて、それらが共通する線分を持ちながら、どちらの線ももう一方を完全に含まない場合、ST_Overlaps(g1,g2)は1を返します。 面幾何オブジェクト(例えば多角形)について、2つの多角形が少なくとも部分的に重なり、かつ各多角形の一部が互いに重ならない場合、ST_Overlaps(g1,g2)は1を返します。
構文は以下のとおりです:
ST_Overlaps(g1,g2)
例:
obclient > SELECT ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))'));
この例では、ST_Overlaps関数は2つの多角形が重なっているかどうかを判断します。最初の多角形POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))は10✖️10の正方形で、内部には2✖️2の穴(空間内の小さな正方形)があります。一方、2番目の多角形POLYGON((0 0,0 5,5 5,5 0,0 0))は5✖️5の正方形で、最初の多角形の左下に位置しています。2番目の多角形は最初の多角形の内部領域と重なりますが、完全には含まれていないため、ST_Overlaps関数は1を返します。
実行結果は次のとおりです:
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| ST_OVERLAPS(ST_GEOMFROMTEXT('POLYGON((0 0,0 10,10 10,10 0,0 0,0 0),(2 2,2 4,4 4,4 2,2 2))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 5,5 5,5 0,0 0))')) |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
| 1 |
+-------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set
_ST_Touches
_ST_Touches(ジオメトリA, ジオメトリB)関数は、2つのジオメトリオブジェクトAとBの境界に少なくとも1つの共通点があり、内部が交差しないかどうかを判断するために使用されます。また、_ST_Touches(ジオメトリA, ジオメトリB)関数は空間インデックスをサポートしています。
ここで注意すべき点は、2つのジオメトリオブジェクトがどちらも点(Point)タイプの場合、_ST_Touches(ジオメトリA, ジオメトリB)関数は0を返すということです。これは、点ジオメトリオブジェクトに境界がないため、2つの点を「接触」と見なすことはできないからです。それらは同一であるか(つまり、位置が完全に一致する)、あるいは完全に独立しているかのどちらかです。
構文は以下のとおりです:
_ST_Touches(geometry A, geometry B)
例:
obclient > SELECT _ST_Touches(st_geomfromtext('LINESTRING(0 0, 1 1, 0 2)'), st_geomfromtext('POINT(0 2)'));
この例では、_ST_Touches関数は、線形ジオメトリオブジェクト(LineString)と点ジオメトリオブジェクト(Point)が空間的に接触しているかどうかを判断するために使用されます。点(0 2)は線(0 0, 1 1, 0 2)の終点であるため、結果1を返すことで、これら2つのオブジェクトが接触していることを示します。
結果は次のとおりです:
+------------------------------------------------------------------------------------------+
| _ST_Touches(st_geomfromtext('LINESTRING(0 0, 1 1, 0 2)'), st_geomfromtext('POINT(0 2)')) |
+------------------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------------------+
1 row in set
ST_Equals
ST_Equals(geometry A, geometry B)関数は、2つの幾何オブジェクトAとBが空間構造上等しいかどうかを判断するために使用されます。つまり、これら2つの幾何オブジェクトは同じ点集合を含み、各点の2つの幾何オブジェクトにおける相対的な位置も同じである必要がありますが、この関数では点の順序が完全に一致している必要はありません。
言い換えれば、2つの幾何オブジェクトが完全に同一の空間範囲を占め、その形状とサイズが完全に一致している場合、ST_Equalsは1を返します。2つの幾何オブジェクトがいかなる点でも異なる場合(サイズや形状のわずかな違いであっても)、ST_Equals関数は0を返します。
ST_Equals(geometry A, geometry B)関数は空間インデックスをサポートしています。
構文は以下のとおりです:
ST_Equals(geometry A, geometry B);
例:
obclient > SELECT ST_Equals(ST_GeomFromText('LINESTRING(0 0, 10 10)'), ST_GeomFromText('LINESTRING(0 0, 5 5, 10 10)'));
この例では、ST_Equals関数は2本の線が空間上等しいかどうかを判断するために使用されます。最初の線は(0 0)から(10 10)への単純な直線です。2本目の線も(0 0)から(10 10)へと続きますが、途中に(5 5)という中間点があります。2本目の線には追加の頂点が含まれていますが、2本の線が空間上で同じ点集合をカバーしているため、ST_Equalsはこれら2本の線が空間構造上等しいと判断し、結果として1を返します。
実行結果は次のとおりです:
+------------------------------------------------------------------------------------------------------+
| ST_Equals(ST_GeomFromText('LINESTRING(0 0, 10 10)'), ST_GeomFromText('LINESTRING(0 0, 5 5, 10 10)')) |
+------------------------------------------------------------------------------------------------------+
| 1 |
+------------------------------------------------------------------------------------------------------+
1 row in set
パラメータの注意点
空間関係関数における幾何学的パラメータの戻り値は、以下の場合を除きNULLではありません:
いずれかのパラメータが
NULLであるか、またはいずれかの幾何学的パラメータが空のジオメトリである場合、戻り値はNULLとなります。いずれかの幾何学的パラメータの構文が正しくない場合、
ER_GIS_INVALID_DATAエラーが報告されます。いずれかの幾何学的パラメータが定義されていない空間参照システム(SRS)に属している場合、
ER_SRS_NOT_FOUNDエラーが報告されます。複数の幾何学的パラメータを使用する関数について、これらのパラメータが同一のSRS内にない場合、
ER_GIS_DIFFERENT_SRIDSエラーが報告されます。いずれかの幾何学的パラメータが無効な場合、結果はTrueまたはFalseになる可能性があります。または、エラーが発生する可能性があります。
地理SRSの幾何学的パラメータについて、いずれかのパラメータの経度または緯度が範囲外の場合(範囲は度単位であり、SRSが他の単位を使用する場合は、その単位における対応する値を使用します)、エラーが発生します:
経度値が範囲(-180, 180]外の場合、
ER_GEOMETRY_PARAM_LONGITUDE_OUT_OF_RANGEエラーが報告されます。緯度値が[−90, 90]の範囲外の場合、
ER_GEOMETRY_PARAM_LATITUDE_OUT_OF_RANGEエラーが報告されます。
空間計算の座標精度は(-9.223e18, 9.223e18)を超えてはなりません。超えた場合、エラーが報告されます:
obclient [test]> SELECT ST_CONTAINS(ST_GEOMFROMTEXT('MULTIPOLYGON(((0 1e+19,0 0,0 0,0 1e+19)))'), ST_GEOMFROMTEXT('POLYGON((0 0,0 0,0 0,0 0))')); ERROR 1690 (22003): coordinate value is out of range in 'st_contains'