2016-07-29 4 views
0

У меня есть таблица с SDO_Geometries, и я запрашиваю все геометрии, чтобы найти их начальную и конечную точки, затем вставляю эти точки в другую таблицу под названием ORAHAN. Теперь моя главная цель заключается в каждом пункте в orahan, который я должен найти, если он пересекает другую точку в orahan, когда дает 2 см буфера к точкам. Итак, я пишу некоторые pl sql, используя функции Relate и Bufer, но когда я проверяю некоторые записи в Map Info, я видел, что есть точки в пределах 1 см от себя, но нет записи в таблице пересечений под названием ORAHANCROSSES. Я использую эти функции неправильно или что?Oracle Spatial - SDO_BUFFER не работает?

. Примечание: Я использую Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64-битные производства и PL/SQL Release 11.2.0.1.0 - и SDO_PACKAGE

ORAHAN насчитывает около 400 тысяч записей (точки и другие столбцы.)

declare 
BEGIN 
for curs in (select * from ORAHAN t) loop 
    for curs2 in (select * 
        from ORAHAN t2 
        where SDO_RELATE(t2.geoloc,SDO_GEOM.SDO_BUFFER(curs.geoloc,0.02,0.5) , 
        'mask=ANYINTERACT') = 'TRUE' 
        and t2.mi_prinx <> curs.mi_prinx) loop      
    Insert INTO ORAHANCROSSES 
    values 
     (curs.Mip, curs.Startmi, curs2.Mip, curs2.Startmi); 
    commit; 
    end loop; 
end loop; 
END; 

и это MapInfo изображение карты показывает, что 3 точки, которые близки друг к другу 1 сантиметр приближенно минимаксным. Но в orahancrosses нет записи соответствия этих 3.

Примечание: 0,00001000km не равна 1 см enter image description here

Orahan Метаданные:

select * from user_sdo_geom_metadata where table_name = 'ORAHAN'; 

enter image description here

И diminfo:

enter image description here

ответ

1

Что такое система координат ваших данных? И, самое главное, что допуск вы установили в свои метаданные?

Некоторые другие комментарии:

1) Не используйте связаны с буферным подходом. Просто используйте подход на расстоянии.

2) Вам не нужно PL/SQL цикл для такого рода запроса просто использовать простой CTAS:

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from orahan c1, orahan c2 
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' 
and c2.mi_prinx <> c1.mi_prinx; 

3) Как написано, пары точек А и В, которые находятся в пределах 2 см будет возвращен дважды: один раз (A, B) и еще раз (B, A). Чтобы избежать этого (и возвращать только один из случаев), а затем написать запрос следующим образом:

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from orahan c1, orahan c2 
where sdo_wihin_distance (c2.geoloc, c1.geoloc, 'distance=2 unit=cm') = 'TRUE' 
and c1.rowid < c2.rowid; 

3) обработка количество точек вы упоминаете (400000+) должен работать лучше, используя технику SDO_JOIN, как это :

create table orahancrosses as 
select c1.mip mip_1, c1.startmi startmi_1, c2.mip mip_2, c2.startmi startmi_2 
from table (
     sdo_join (
      'ORAHAN','GEOLOC', 
      'ORAHAN','GEOLOC', 
      'DISTANCE=2 UNIT=CM' 
     ) 
    ) j, 
     orahan c1, 
     orahan c2 
where j.rowid1 < j.rowid2 
and c1.rowid = j.rowid1 
and c2.rowid = j.rowid2; 

Это, вероятно, все еще требует времени для обработки - в зависимости от емкости вашего сервера базы данных. Если вы являетесь лицензией для Oracle Enterprise Edition, и ваше оборудование имеет соответствующую емкость (количество ядер), то параллелизм может сократить прошедшее время.

4) Вы говорите, что используете Oracle 11g. Какая точная версия? Версия 11.2.0.4 является терминальной версией для 11gR2. Все, что старше, больше не поддерживается. К настоящему времени вы действительно должны быть на 12cR1 (12.1.0.2). Основное преимущество 12.1.0.2 в вашем случае - функция ускорения Vector Performance Accelerator, которая ускоряет работу ряда пространственных функций и операторов (только если вы владеете надлежащими лицензиями Oracle Spatial - она ​​недоступна со свободной функцией Oracle Locator).

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

Используя две точки в вашем примере. Давайте вычислить расстояние:

select sdo_geom.sdo_distance(
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null), 
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 
    0.005 
) distance 
from dual; 


    DISTANCE 
---------- 
.01000197 

1 row selected. 

Уведомление: Я не указываю никаких SRID. Предполагая, что координаты выражены в метрах, расстояние между ними действительно немного больше 1 см.

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

Причина, почему ваш Исходный синтаксис не работает, как вы заметили, из-за толерантности, который вы указываете для вызова SDO_BUFFER(). Вы передаете его как 0,5 (= 50 см) для получения буфера с радиусом 0,02 (2 см). Эффект заключается в том, что полученный буфер эффективно растворяется в самой точке.

Например, на толерантность 0,5:

select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.5) from dual; 

Производит:

SDO_GEOMETRY(2001, NULL, SDO_POINT_TYPE(521554.782, 4230983.08, NULL), NULL, NULL) 

В толерантностью 0.005:

select sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005) from dual; 

Вы получаете правильный буфер:

SDO_GEOMETRY(2003, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1003, 2), SDO_ORDINATE_ARRAY(521554.782, 4230983.06, 521554.802, 4230983.08, 521554.782, 4230983.1, 521554.762, 4230983.08, 521554.782, 4230983.06)) 

И очень близко точка теперь соответствует с этим буфером:

select sdo_geom.relate(
    sdo_geom.sdo_buffer(sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.08336913,null),null,null),0.02,0.005), 
    'determine', 
    sdo_geometry (2001,null,sdo_point_type(521554.782174622,4230983.07336716,null),null,null), 
    0.005 
) relation 
from dual; 

RELATION 
------------------------- 
CONTAINS 

1 row selected. 

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

Теперь тот факт, что ваши данные не имеют надлежащего явного SRID, означает, что использование явных единиц измерения или дистанционных поисковых запросов не будет работать. Поскольку база данных не знает, в какой системе координат находятся ваши данные, она не знает, как определить, что две точки меньше заданного числа см или м друг от друга. Все, что вы можете сделать, это предположить, что координаты находятся в метрах.

Таким образом, в примерах, которые я даю выше, заменить 'DISTANCE=2 UNIT=CM' с 'DISTANCE=0.02'

+0

Я работаю компания, которая использует оракул 11gR2 в некоторых проектах. Орахан имеет около 400 000 записей (строк). Я отредактирую asap мой вопрос и добавлю значение допуска в метаданные. –

+0

Если компания использует 11gR2 и имеет системный администратор и администратор базы данных, то они, вероятно, уже находятся на 11.2.0.4. Тем не менее, в этой версии и с объемом данных, которые вам нужно обработать, подход SDO_JOIN определенно подходит для меня (я добавил синтаксис в свой ответ). В 12c будет отличаться функцией Vector Performance Accelerator. –

+0

Я стараюсь, чтобы вы сказали, SDO_JOIN метод, и это очень быстро. Он выполнил эту работу за 2 минуты. Спасибо за это. Но проблема все еще остается. Он не находит пересечения, а некоторые точки имеют расстояние 1 см друг от друга. Я думаю, что diminfo моей колонки неверна. –