Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
sakaik opened this issue Oct 21, 2024 · 2 comments

Comments

@sakaik
Copy link

sakaik commented Oct 21, 2024

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));

挙動結果

  • PG-Strom 有効時(4件の結果が返ります)
db=# SET pg_strom.enabled=true;

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
Copy link
Contributor

kaigai commented Oct 21, 2024

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

@sakaik
Copy link
Author

sakaik commented Oct 22, 2024

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants