heterodb / pg-strom

PG-Strom - Master development repository
http://heterodb.github.io/pg-strom/
Other
1.3k stars 162 forks source link

[VTJ-JP]ST_Crosses() returns too much more results.(it includes the exact same linestrings) #844

Closed sakaik closed 2 weeks ago

sakaik commented 1 month ago

Summary

 PG-Strom有効時、ST_Crosses() が余計な行を返します。

Data

以下のSQLで、交叉する2つのLINESTRINGデータを作成します。

CREATE TABLE g2 (id integer, geom geometry);
INSERT INTO g2 VALUES (1, ST_GeomFromText('LINESTRING (139.95915 35.70669, 139.95932 35.70692, 139.95935 35.70696, 139.95948 35.70714, 139.95957 35.70728, 139.95966 35.70738, 139.95984 35.70768, 139.95989 35.70775)',6668));
INSERT INTO g2 VALUES (2, ST_GeomFromText('LINESTRING (139.9581 35.70796, 139.95948 35.70714, 139.9599 35.70689, 139.96004 35.70682)',6668));

挙動結果

db=# SELECT s1.id id1, s2.id id2, ST_AsText(s1.geom) geom1, ST_AsText(s2.geom) geom2 db-# FROM g2 s1, g2 s2 db-# WHERE st_crosses(s1.geom, s2.geom); id1 | id2 | geom1 | geom2
-----+-----+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 | 1 | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) 2 | 1 | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) 1 | 2 | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) 2 | 2 | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) (4 rows)


- PG-Strom無効時(2件の結果が返ります;これが正しい)

db=# SET pg_strom.enabled=false;

db=# SELECT s1.id id1, s2.id id2, ST_AsText(s1.geom) geom1, ST_AsText(s2.geom) geom2 db-# FROM g2 s1, g2 s2 db-# WHERE st_crosses(s1.geom, s2.geom); id1 | id2 | geom1 | geom2
-----+-----+---------------------------------------------------------------------------------------------------------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------- 1 | 2 | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) 2 | 1 | LINESTRING(139.9581 35.70796,139.95948 35.70714,139.9599 35.70689,139.96004 35.70682) | LINESTRING(139.95915 35.70669,139.95932 35.70692,139.95935 35.70696,139.95948 35.70714,139.95957 35.70728,139.95966 35.70738,139.95984 35.70768,139.95989 35.70775) (2 rows)


## 解説
PostGISマニュアルによると、ST_Crosses()は、「交叉を判定するが、完全一致する場合は含まない」仕様です。

Compares two geometry objects and returns true if their intersection "spatially crosses"; that is, the geometries have some, but not all interior points in common.


http://postgis.net/docs/manual-3.5/ST_Crosses.html

PG-Strom有効時の挙動は、(id1, id2)=(1,1)や(2,2)のように自分自身(=完全に一致するLINESTRING)を結果に含んでしまっている点が、誤りです。
kaigai commented 1 month ago

優先順位としてはどれくらい急ぐ必要がありそうでしょうか?

sakaik commented 1 month ago

さしあたって案件等がストップする系でない点では超特急ではないのですが 様々な検証の中で自然に使う関数なので、その都度違いを意識して使い続けなくて済むと嬉しい、と言ったくらいの温度感です。

kaigai commented 2 weeks ago

1581adb0966c5c7f371ed829482d077e248dc53b にて修正しました。

St_CrossesのIM-9E行列って、LINE-LINEの場合だと0********と書かれていますが、実際には0***F****でなければならないようですね。(Boundaryの共通部分が存在してはならない) https://postgis.net/docs/ja/ST_Crosses.html

sakaik commented 2 weeks ago

da05771daa205b684b2eb30ee5a7dbfb1ddde20e にて期待通りの件数(2件)が得られることを確認しました。

PostGIS側のマニュアルの誤りでしたか。 対応ありがとうございました。