Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle Spatial - Wählen Sie Objekte aus, die in den Bereich fallen

Sie können dies auf zwei Arten tun. Zuerst, wie Sie erwähnt haben, SDO_WITHIN_DISTANCE ist ein gültiger Ansatz.

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

In diesem Fall wird die Entfernung in linearen Einheiten angegeben, die durch den Raumbezug von a definiert sind. Oracle behandelt die Koordinaten als kartesisch, daher müssen Sie sicherstellen, dass Sie ein lineares Koordinatensystem haben, bevor Sie diesen Operator verwenden (im Gegensatz zu Winkel-Breiten-/Längen-Einheiten). Da Sie mit Hoch-/Rechtswerten arbeiten, denke ich, dass Sie in Ordnung sind, solange sich die Punkte, mit denen Sie vergleichen, im selben räumlichen Bezug befinden.

Dieser Ansatz verwendet eine innere Schleife, um die Abfrage zu lösen, was nicht sehr effizient ist, wenn Sie viele Punkte zum Vergleichen haben. Außerdem ist Oracle Spatial SEHR wählerisch in Bezug auf die Reihenfolge der Operanden in den SDO-Funktionen, sodass Sie möglicherweise mit der Parameterreihenfolge herumspielen müssen, um den Sweetspot zu finden. Wenn Ihre Abfrage über einen längeren Zeitraum ausgeführt wird, versuchen Sie, den ersten und zweiten Parameter Ihres sdo-Operators zu wechseln. Sie können auch mit der Reihenfolge der 'From'- und 'Inner Join'-Tabellen spielen, indem Sie /*+ ORDERED */ verwenden hinter SELECT .

Ein anderer Ansatz besteht darin, die Geometrie zu puffern und mit dem Puffer vergleichen.

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

Denken Sie daran, dass der zweite Parameter von SDO_RELATE (als Fenster bezeichnet) keinen räumlichen Index hat, wenn Sie ihn so umwandeln, wie wir hier mit dem Puffer sind.

Wenn Sie dies mit mehreren Punkten planen, empfiehlt es sich, eine Tabelle zu erstellen, in der alle Quellpunkte gepuffert sind. Erstellen Sie dann einen räumlichen Index für die gepufferten Bereiche und vergleichen Sie diesen mit Ihren Zielpunkten.

Zum Beispiel:

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

HINWEIS:Wenn Sie Punkte mit Polygonen schneiden, sollte sich das Polygon immer in der Fensterposition befinden des sdo_relate (das ist der zweite Parameter). Dadurch wird sichergestellt, dass Ihr räumlicher Index korrekt verwendet wird.