sdo_relate дает неправильный результат запроса

У меня есть две геометрии в двух классах объектов, одна с именем «HY90299», а другая с именем «hyboxsdo», две геометрии не пересекаются.

but when i run a spatial query in oralce ,

"select sdo_relate(t.shape,g.shape ,'mask=ANYINTERACT') from HY90299 t,hyboxsdo g " ,

it return "true", the result is not correct .am I doing something wrong?

моя версия оракула 11g

you can get the two geometry by 

1.i put the  two geometry into two shape file . you can get them from here
https://pan.baidu.com/s/1YQnwe8nstzgHOAwHgx9JGQ

2.or create the two geometry  by wkt
①MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))
②MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))

Добавить

1.select * from user_sdo_geom_metadata where table_name='HY90299'

=============================

return "HY90299    SHAPE     {{null,-180,180,0.001},{null,-90,90,0.001}}    4326"



2.select sdo_geom.validate_geometry_with_context(c.shape,0.000000005) from  hy90299 c
   select sdo_geom.validate_geometry_with_context(c.shape,0.001) from hy90299 c

=============================

all return  "true"



3.select shape from hy90299

=============================

return "{2003,4326,null,{1,1003,1},{111.186300278,67.126588821,-16.657423019,82.843477249,16.71090126,66.242341995,74.611375809,57.038061142,111.186300278,67.126588821}}"



4.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750)),0.000000005) as spat_rel from HY90299 t

=============================

return "DISJOINT"



5.select sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(60.840,26.570, 143.450,26.570, 143.450,55.750,60.840,55.750,60.840, 26.570)),0.000000005) as spat_rel from HY90299 t

=============================

return "OVERLAPBDYINTERSECT"

person bigjames    schedule 19.08.2019    source источник


Ответы (1)


Из руководства (https://docs.oracle.com/cd/B28359_01/appdev.111/b28400/sdo_operat.htm#SPATL1039), пространственные операторы «всегда должны использоваться в предложении WHERE», а не в части SELECT запрос.

Чтобы использовать их (в предложении WHERE, как уже упоминалось), они должны быть пространственно проиндексированы.

Если вы хотите увидеть пространственное отношение, вы можете использовать одну из пространственных функций, например:

select t.*,g.*, sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) as spat_rel
from HY90299 t, hyboxsdo g

Если вы хотите, вы также можете добавить функцию в вызов WHERE, чтобы отфильтровать результаты - например. добавьте в приведенный выше фрагмент:

where sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) not in ('TOUCH','DISJOINT')

Для нескольких геометрий все будет в порядке. По мере роста количества геометрий вы должны либо использовать пространственные индексы и добавлять операторы в предложении WHERE, либо использовать другой способ фильтрации строк (например, по атрибуту, идентификатору и т. д.) — пространственные функции плохо масштабируются.

Вы также несете ответственность за выбор значения ДОПУСК, которое подходит для ваших данных и запроса (я выбрал 0,000000005, поскольку ваши фигуры, похоже, имеют 8 значащих десятичных знаков).

И последнее, НО НЕ В МЕНЬШЕ, вы хотели бы убедиться, что ваши геометрии действительны (опять же, с соответствующим допуском).

ХТН

ДОБАВИТЬ:
1)

with HY90299 as (
  select sdo_util.from_wktgeometry( 
  'MULTIPOLYGON (((-16.657423019000021 82.843477248999989, 16.710901260000014 66.242341995000004, 74.611375808999981 57.038061142000004, 111.18630027799998 67.126588820999984, -16.657423019000021 82.843477248999989)))'
  ) shape from dual ), 
HYBOXSDO as (
  select sdo_util.from_wktgeometry( 
  'MULTIPOLYGON (((60.839999999999975 26.569999999999993, 143.45000000000005 26.569999999999993, 143.45000000000005 55.75, 60.839999999999975 55.75, 60.839999999999975 26.569999999999993)))'
  ) shape  from dual )
select sdo_geom.relate(t.shape,'determine',g.shape,0.000000005)
from HY90299 t,hyboxsdo g ;

Результат DISJOINT - также:

with HY90299 as (
select sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-16.657423019000021, 82.843477248999989, 16.710901260000014, 66.242341995000004, 74.611375808999981, 57.038061142000004, 111.18630027799998, 67.126588820999984, -16.657423019000021, 82.843477248999989))
 shape from dual )
select sdo_geom.relate(t.shape,'determine',
sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450,55.750))
,0.000000005) as spat_rel from HY90299 t

Результат снова DISJOINT.
Вашего 'overlapbdyintersect' там быть не должно - проверьте содержимое ваших таблиц (поскольку разница в ваших двух запросах заключается в геометрии 'window', дважды проверьте таблицу hyboxsdo).< br> 2) Ты не прав. Терпимость необходима. Если вы используете sdo_geom.relate(t.shape,'determine',g.shape,2) — это допуск 2 метра — в приведенных выше запросах, вы получите TOUCH вместо DISJOINT (и этим вы также можете сказать, что ваши геометрии находятся на расстоянии примерно 2 метра друг от друга). Однако с этими двумя геометриями вы никогда не получите ПЕРЕКРЫТИЕ.
3) Достоверность геометрии напрямую связана с используемым допуском. Ваши геометрии верны (с точностью до 8 знаков после запятой) — я просто говорю, что это избавит вас от МНОГО головной боли, если вы не примете это как должное. Никогда не предполагайте — проверяйте!
4) Неважно, как вы поместите геометрию в таблицу. Единственное, что вы можете принять во внимание (особенно в рабочей среде), — это количество десятичных знаков, хранящихся в базе данных. лучше округлить или урезать свои координаты до этого. Более простые координаты приводят к меньшей занимаемой площади (хранилище базы данных) и более высокой производительности.

person GregStef    schedule 19.08.2019
comment
спасибо за Ваш ответ! 1. Я попробовал этот запрос select t.*,g.*, sdo_geom.relate(t.shape,'determine',g.shape,0.000000005) as spat_rel из HY90299 t, hyboxsdo g , он все равно возвращает перекрытие byintersect 2.one геометрия имеет minY 57,038, другой имеет maxY 55,750, я не думаю, что ДОПУСК является причиной такого результата 3. две геометрии очень простые геометрии, которые имеют только четыре точки. они должны быть действительными - person bigjames; 20.08.2019
comment
4. Я создаю класс объектов и импортирую объекты с помощью arcgis. Влияет ли это на пространственный запрос? 5. Я запускаю запрос другим способом select t.*, sdo_geom.relate(t.shape,'determine',sdo_geometry(2003,4326,null, SDO_ELEM_INFO_ARRAY(1,1003,3),SDO_ORDINATE_ARRAY(60.840,26.570,143.450 ,55.750)),0.000000005) как spat_rel из HY90299 t, он возвращает правильный результат - непересекающийся. геометрия в hyboxsdo имеет нижний левый (60.840,26.570) и верхний правый (143.450,55.750) запрос в некотором роде одинаковый, давая разные результаты. Я не понимаю, почему - person bigjames; 20.08.2019
comment
надеюсь на ваш ответ и извините за мой плохой английский - person bigjames; 20.08.2019
comment
См. APEND в моем ответе. - person GregStef; 20.08.2019
comment
см. также мое приложение. ‹пред› ‹/пре› - person bigjames; 20.08.2019
comment
Две геометрические единицы - десятичная степень. один minY равен 57,038, другой maxY равен 55,750, как это возможно, что они находятся на расстоянии 2 м друг от друга. Я пытаюсь спроецировать две геометрии с помощью mecator, они находятся на расстоянии не менее 1000 метров друг от друга. - person bigjames; 20.08.2019
comment
Насчет дистанции, моя беда - пробежал без перепроекции. Моя точка зрения, однако, заключалась в том, что геометрии действительно не пересекались. Я не понимаю последнюю часть вашего добавления: вы запрашиваете отношение геометрии HY90299, но геометрии «окна» (те, что после «определить») различаются в ваших (4) и (5). Я что-то упустил здесь? - person GregStef; 20.08.2019