如何从Oracle的sdo_geometry中获取纬度和经度

11

我该如何从 Oracle 中的点获取纬度和经度?

就像这样:

MDSYS.SDO_GEOMETRY(2001,4326,NULL,
  MDSYS.SDO_ELEM_INFO_ARRAY(1,1,1),
  MDSYS.SDO_ORDINATE_ARRAY(51.702814,32.624736))
4个回答

22
您展示的符号并不是表示单个2D或3D点的最佳方式。常见且最有效的编码方式如下:
SDO_GEOMETRY(2001,4326,SDO_POINT_TYPE(51.702814,32.624736,NULL),NULL,NULL)

我见过的所有GIS工具都使用这种表示法。你展示的那种表示法也是有效的 - 只不过需要更多的存储空间。但是这两种表示法在功能上完全等效。

使用紧凑表示法,将单个坐标提取出来非常简单。例如,考虑US_CITIES包含上述紧凑表示法中的点:

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.

使用更复杂的基于数组的符号表示法获得相同的结果更加复杂。您可以使用SDO_UTIL.GETVERTICES方法。例如,假设US_CITIES_A包含相同的点但是采用了基于数组的符号表示法:

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.

另一种我认为更简单的方法是定义几个简单的函数来从数组中提取值:
create or replace function get_x (g sdo_geometry) return number is
begin
  return g.sdo_ordinates(1);
end;
/

并且

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

然后使用函数可以使语法更简单:
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.

2
有趣的是,只是提供信息,您必须在具有几何图形的表上使用表别名才能使用sdo_point.x|y。 - Mark Giaconia
1
需要明确的是:在使用Oracle中的对象时,这是一个通用要求。您还需要一个别名来调用任何对象方法。这是在SQL中,而不是OL/SQL中:您可以直接检查变量中的对象。 - Albert Godfrind

6
您可以使用sdo_util.getvertices。以下是来自文档的示例。
SELECT c.mkt_id, c.name, t.X, t.Y, t.id
   FROM cola_markets c,
   TABLE(SDO_UTIL.GETVERTICES(c.shape)) t
   ORDER BY c.mkt_id, t.id;

被接受的答案似乎无法在您只拥有定位器许可证的情况下使用。至少对我们来说是这样的。这个答案可以在定位器许可证下使用。 - MonsterMushroom
这很奇怪,因为在定位器中使用sdo_point_type是非常受支持的。 - Rene
这个语法应该可以工作:从表t选择t.geometry.sdo_point - Rene
您说得对。 如果我使用 select ora_geometry.sdo_point from foo_table,那么会出现无效标识符的错误。 如果我使用 select t.ora_geometry.sdo_point from foo_table t,就可以正常工作。 您能解释一下为什么需要表别名吗? - MonsterMushroom
“你能解释一下为什么需要表别名吗?”这与 SQL 解析器中的“.”符号歧义有关。添加别名可以消除这种歧义。 - Albert Godfrind
显示剩余2条评论

1

如果您不使用别名,这将无法正常工作。


你能在你的回答中添加更多的上下文吗? - codeepic
使用表的别名形式命名,例如:select * from tabla t。 - carlosaar22

0

选择a.id,t.x,t.y from geometry_table a,table(sdo_util.getvertices(a.geometry_column)) t where a.id = 1;


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接