Oracle code to calculate distance between point/centroids/polygons

后端 未结 2 1225
礼貌的吻别
礼貌的吻别 2021-01-26 08:03

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 no

相关标签:
2条回答
  • 2021-01-26 08:39

    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/

    0 讨论(0)
  • 2021-01-26 08:54

    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.

    0 讨论(0)
提交回复
热议问题