sql >> Base de Datos >  >> RDS >> Oracle

Oracle Spatial:seleccione los objetos que caen dentro del área

Puedes hacer esto de dos maneras. Primero, como mencionaste, SDO_WITHIN_DISTANCE es un enfoque válido.

select 
    *
from center_point a
inner join target_points b
    on a.id = 1
    and sdo_within_distance( b.shape, a.shape, 'distance = 10' ) = 'TRUE'
;

En este caso, la distancia está en unidades lineales definidas por la referencia espacial de a. Oracle trata las coordenadas como cartesianas, por lo que deberá asegurarse de tener un sistema de coordenadas lineales antes de usar este operador (a diferencia de las unidades angulares de latitud y longitud). Dado que está trabajando con nortes/estes, creo que estará bien siempre que los puntos con los que está comparando estén en la misma referencia espacial.

Este enfoque utiliza un bucle interno para resolver la consulta, por lo que no es muy eficiente si tiene muchos puntos con los que comparar. Además, Oracle Spatial es MUY exigente con el orden de los operandos en las funciones SDO, por lo que es posible que deba jugar con el orden de los parámetros para encontrar el punto óptimo. Si su consulta se ejecuta durante un período prolongado, intente cambiar el primer y segundo parámetro de su operador sdo. También puedes jugar con el orden de las tablas 'from' y 'inner join' usando /*+ ORDERED */ trasero después de SELECT .

Otro enfoque es almacenar la geometría y comparar con el búfer.

select 
    *
from center_point a
inner join target_points b
    on a.id = 1
    and sdo_relate( b.shape, sdo_buffer(a.shape, 0.05 ), 'mask=anyinteract' ) = 'TRUE'
;

Tenga en cuenta que lo que sea que esté en el segundo parámetro de SDO_RELATE (llamado la ventana) no tendrá un índice espacial si lo transforma como si estuviéramos aquí con el búfer.

Si planea hacer esto con varios puntos, se recomienda crear una tabla en la que se almacenen en búfer todos los puntos de origen. Luego cree un índice espacial contra las áreas protegidas y compárelo con sus puntos objetivo.

Por ejemplo:

create table point_bufs unrecoverable as
select sdo_buffer (a.shape, b.diminfo, 1.35)
from centerpoint a, user_sdo_geom_metadata b
where table_name='CENTERPOINT'
  and column_name='SHAPE';

select
    a.gif,
    b.gid 
from target_points a, 
     point_bufs b
where sdo_relate(a.shape, b.shape, 'mask=anyinteract querytype=join') = 'TRUE'
;

NOTA:Al intersecar puntos con polígonos, siempre desea que el polígono esté en la posición de la ventana del sdo_relate (que es el segundo parámetro). Esto asegurará que su índice espacial se utilice correctamente.