sql >> Database >  >> RDS >> Oracle

Oracle Spatial - selecteer objecten die binnen het gebied vallen

U kunt dit op twee manieren doen. Ten eerste, zoals je al zei, SDO_WITHIN_DISTANCE is een geldige benadering.

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 dit geval is de afstand in lineaire eenheden gedefinieerd door de ruimtelijke referentie van a. Oracle behandelt de coördinaten als cartesiaans, dus u moet ervoor zorgen dat u een lineair coördinatensysteem heeft voordat u deze operator gebruikt (in tegenstelling tot hoekige lat/lon-eenheden). Aangezien je met noorden/oosten werkt, denk ik dat het goed komt, zolang de punten waarmee je vergelijkt zich in dezelfde ruimtelijke referentie bevinden.

Deze aanpak maakt gebruik van een innerlijke lus om de vraag op te lossen, dus niet erg efficiënt als je veel punten hebt om mee te vergelijken. Oracle Spatial is ook ZEER kieskeurig over de volgorde van operanden in de SDO-functies, dus je moet misschien wat spelen met de parametervolgorde om de sweetspot te vinden. Als uw query voor een lange periode loopt, probeer dan de eerste en tweede parameter van uw sdo-operator om te schakelen. Je kunt ook spelen met de volgorde van de 'from' en 'inner join' tafels met behulp van de /*+ ORDERED */ hind na SELECT .

Een andere benadering is om de geometrie te bufferen en vergelijk met de buffer.

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

Houd er rekening mee dat alles wat in de tweede parameter van de SDO_RELATE (het venster wordt genoemd) geen ruimtelijke index heeft als je het transformeert zoals we hier zijn met de buffer.

Als je van plan bent dit met meerdere punten te doen, is het aan te raden om een ​​tabel te maken waarin alle bronpunten worden gebufferd. Maak vervolgens een ruimtelijke index tegen de gebufferde gebieden en vergelijk die met uw streefpunten.

Bijvoorbeeld:

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

OPMERKING:wanneer u punten kruist met polygonen, wilt u altijd dat de polygoon zich in de vensterpositie bevindt van de sdo_relate (wat de tweede parameter is). Dit zorgt ervoor dat uw ruimtelijke index correct wordt gebruikt.



  1. Converteer deze vraag naar welsprekend

  2. hoe loop ik van terminal zonder buitensporige wachtwoordverzoeken?

  3. Creatieve toepassingen voor de blackhole engine

  4. geef de waarde van de PHP-variabele door aan de SQL IN-clausule