Oracle
 sql >> Database >  >> RDS >> Oracle

Come ottenere lat e long da sdo_geometry in Oracle

La notazione che mostri non è la migliore per rappresentare singoli punti 2D o 3D. Il modo più comune e più efficiente per codificare quei punti è questo:

SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(51.702814,32.624736,NULL),NULL,NULL)

Tutti gli strumenti GIS che ho visto usano questa notazione. Anche quello che mostri è valido:utilizza solo più spazio di archiviazione. Ma le due notazioni sono funzionalmente equivalenti.

Utilizzando la notazione compatta, ottenere le singole coordinate è banale. Ad esempio, considerando che US_CITIES contiene un punto nella notazione compatta sopra:

select c.city, c.location.sdo_point.x longitude, c.location.sdo_point.y latitude 
from us_cities c where state_abrv='CO';

CITY                                        LONGITUDE   LATITUDE
------------------------------------------ ---------- ----------
Aurora                                     -104.72977  39.712267
Lakewood                                   -105.11356    39.6952
Denver                                     -104.87266  39.768035
Colorado Springs                            -104.7599    38.8632

4 rows selected.

Ottenere lo stesso risultato dalla notazione basata su array più complessa che usi è più contorto. È possibile utilizzare l'approccio SDO_UTIL.GETVERTICES. Ad esempio, supponendo che US_CITIES_A contenga gli stessi punti ma nella notazione basata su array:

select city, t.x longitude, t.y latitude
from us_cities_a, table (sdo_util.getvertices(location)) t
where state_abrv = 'CO';

CITY                                        LONGITUDE   LATITUDE
------------------------------------------ ---------- ----------
Aurora                                     -104.72977  39.712267
Lakewood                                   -105.11356    39.6952
Denver                                     -104.87266  39.768035
Colorado Springs                            -104.7599    38.8632

4 rows selected.

Un altro approccio che trovo più semplice è definire semplicemente un paio di semplici funzioni per estrarre i valori dall'array:

create or replace function get_x (g sdo_geometry) return number is
begin
  return g.sdo_ordinates(1);
end;
/

e

create or replace function get_y (g sdo_geometry) return number is
begin
  return g.sdo_ordinates(2);
end;
/

Quindi l'utilizzo delle funzioni rende la sintassi più semplice:

select city, get_x(location) longitude, get_y(location) latitude
from us_cities_a
where state_abrv = 'CO';

CITY                                        LONGITUDE   LATITUDE
------------------------------------------ ---------- ----------
Aurora                                     -104.72977  39.712267
Lakewood                                   -105.11356    39.6952
Denver                                     -104.87266  39.768035
Colorado Springs                            -104.7599    38.8632

4 rows selected.