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