问题
I've centroids for customer A and customer B. Now I need to calculate distance between customer A and B into miles using centroids. How can I do it in Oracle?
Right now, I'm using alteryx "distance" spatial tool for centroid distance calculation but need to convert it into oracle query.
Thanks!
回答1:
If you have Cartesian coordinates then the approximate distance if given by the Pythagorean theorem as already provided by Matthew.
For Lat/Lon values you should use the Oracle build in SDO_GEOM.SDO_DISTANCE function, if available.
If your Oracle DB does not have Oracle Spatial installed (it cost extra) then you can use the Haversine formula to get approximate distance like this:
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;
pi NUMBER := ACOS(-1)/180;
lat_delta NUMBER;
lon_delta NUMBER;
arc NUMBER;
BEGIN
lat_delta := (p_latitude2-p_latitude1)*pi;
lon_delta := (p_longitude2-p_longitude1)*pi;
arc := SIN(lat_delta/2) * SIN(lat_delta/2) + SIN(lon_delta/2) * SIN(lon_delta/2) * COS(p_latitude1*pi) * COS(p_latitude2*pi);
return earth_radius * 2 * atan2(sqrt(arc), sqrt(1-arc));
END;
Result is given in kilometers, if you like to get miles then replace earth_radius
by according value in miles.
credits: https://connor-mcdonald.com/2017/01/17/haversine-plsql/
回答2:
A centroid is just a point that is a center of mass for given geometry (a shape, set of points, whatever). So, the distance between them is just the Pythagorean theorem.
E.g, to find the distance between points (1,1) and (4,5) in Oracle:
select sqrt(power(4-1,2)+power(5-1,2)) distance from dual;
+----------+ | DISTANCE | +----------+ | 5 | +----------+
If you are using the built-in Oracle type SDO_GEOMETRY
to represent your points, you can use the SDO_GEOM.DISTANCE
function. E.g.,
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 | +----------+
Update for people with customers on Planet Earth
If your centroids are given as latitute and longitude, then you need to use the SDO_GEOM.SDO_DISTANCE
function, as above, but indicate that you are working with WGS84 coordinates (latitude & longitude). Like this:
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 | +-------------------+
The example points I gave are for New York and Los Angeles. The answer is expressed in kilometers. Notice you must specify the longitude first when constructing a SDO_POINT_TYPE
.
来源:https://stackoverflow.com/questions/59162137/oracle-code-to-calculate-centroid-between-lat-long