【发布时间】:2020-03-28 12:30:10
【问题描述】:
我有客户 A 和客户 B 的质心。现在我需要使用质心将客户 A 和 B 之间的距离计算为英里。我如何在 Oracle 中做到这一点?
目前,我正在使用alteryx“距离”空间工具进行质心距离计算,但需要将其转换为oracle查询。
谢谢!
【问题讨论】:
标签: oracle geospatial distance alteryx
我有客户 A 和客户 B 的质心。现在我需要使用质心将客户 A 和 B 之间的距离计算为英里。我如何在 Oracle 中做到这一点?
目前,我正在使用alteryx“距离”空间工具进行质心距离计算,但需要将其转换为oracle查询。
谢谢!
【问题讨论】:
标签: oracle geospatial distance alteryx
如果您有笛卡尔坐标,那么如果由 Matthew 已经提供的勾股定理给出的近似距离。
对于 Lat/Lon 值,您应该使用 Oracle 内置 SDO_GEOM.SDO_DISTANCE 函数(如果可用)。
如果您的 Oracle DB 没有安装 Oracle Spatial(需要额外付费),那么您可以使用 Haversine formula 来获取大致距离,如下所示:
CREATE OR REPLACE FUNCTION p2p_distance(
p_latitude1 NUMBER,
p_longitude1 NUMBER,
p_latitude2 NUMBER,
p_longitude2 NUMBER)
RETURN NUMBER DETERMINISTIC IS
earth_radius NUMBER := 6371;
deg2rad NUMBER := ACOS(-1)/180;
lat_delta NUMBER;
lon_delta NUMBER;
arc NUMBER;
BEGIN
lat_delta := (p_latitude2-p_latitude1)*deg2rad;
lon_delta := (p_longitude2-p_longitude1)*deg2rad;
arc := SIN(lat_delta/2) * SIN(lat_delta/2) + SIN(lon_delta/2) * SIN(lon_delta/2) * COS(p_latitude1*deg2rad) * COS(p_latitude2*deg2rad);
return earth_radius * 2 * atan2(sqrt(arc), sqrt(1-arc));
END;
结果以公里为单位,如果您想获得英里数,请将earth_radius 替换为相应的英里数。
【讨论】:
质心只是一个点,它是给定几何体的质心(一个形状,一组点,等等)。所以,它们之间的距离就是勾股定理。
例如,在 Oracle 中求点 (1,1) 和 (4,5) 之间的距离:
select sqrt(power(4-1,2)+power(5-1,2)) distance from dual;
+----------+ | DISTANCE | +----------+ | 5 | +----------+
如果您使用内置的 Oracle 类型 SDO_GEOMETRY 来表示您的点,您可以使用 SDO_GEOM.DISTANCE 函数。例如,
with centroids as (
select sdo_geometry(2001 /* 2001=single point in 2 dimensions using non linear referencing system geometry */,
null,
sdo_point_type(1,1,0),
null,
null) point_x,
sdo_geometry(2001 /* 2001=single point in 2 dimensions using non linear referencing system geometry */,
null,
sdo_point_type(4,5,0),
null,
null) point_y
from dual )
SELECT sdo_geom.sdo_distance(point_x, point_y, 0.005) distance
from centroids;
+----------+ | DISTANCE | +----------+ | 5 | +----------+
如果您的质心以纬度和经度的形式给出,那么您需要使用SDO_GEOM.SDO_DISTANCE 函数,如上所述,但表明您正在使用 WGS84 坐标(纬度和经度)。像这样:
with centroids as (
select sdo_geometry(2001 /* 2001=single point in 2 dimensions using non linear referencing system geometry */,
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(74.0060,40.7128,null),
null,
null) point_x,
sdo_geometry(2001 /* 2001=single point in 2 dimensions using non linear referencing system geometry */,
4326, -- Spatial reference system id (SRID) for WGS84 coordinates
sdo_point_type(118.2437,34.0522,null),
null,
null) point_y
from dual )
SELECT sdo_geom.sdo_distance(point_x, point_y, 0.005, 'unit=km') distance
from centroids;
+-------------------+ | DISTANCE | +-------------------+ | 3944.42223197608 | +-------------------+
我给出的示例点是针对纽约和洛杉矶的。答案以公里为单位。请注意,在构造SDO_POINT_TYPE 时必须先指定经度。
【讨论】:
SDO_GEOMETRY 与 GPS 坐标一起使用。