This discussion is archived
1 Reply Latest reply: Sep 26, 2012 9:23 PM by Simon Greener RSS

SDO_DISTANCE and tolerance

900016 Newbie
Currently Being Moderated
I am very new to Geospatial (Oracle 11.2), so I am having a lot of trouble figuring out how to use tolerance in SDO_DISTANCE between a point and a polygon.

Distance between 2 points works as expected, but distance between a polygon and a point (SRID=8265 for both) seems to be always ignored.

SELECT
SDO_GEOM.SDO_DISTANCE(
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-50, 48, NULL), NULL, NULL),
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL),
*100*) as distance
FROM dual;

DISTANCE
--------
149.250735546699


SELECT
SDO_GEOM.SDO_DISTANCE(
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-50, 48, NULL), NULL, NULL),
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL),
*200*) as distance
FROM dual;

DISTANCE
--------
0

Here the tolerance parameter seems to be completely ignored:

SELECT
SDO_GEOM.SDO_DISTANCE(
g.arspc_border_sdo,
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL),
*1000*) as distance
FROM AIRSPACE_BORDER_GEOMETRY g, AIRSPACE_BORDER b, AIRSPACE asp
WHERE g.ARSPC_BORDER_UID = 123


DISTANCE
--------
148.808025088469


Even if I set all my DIM_ARRAYs explicitly, tolerance is still ignored:

SELECT
SDO_GEOM.SDO_DISTANCE(
g.arspc_border_sdo, MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-180,180,300),MDSYS.SDO_DIM_ELEMENT('Y',-90,90,300)),
SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL), MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-180,180,300),MDSYS.SDO_DIM_ELEMENT('Y',-90,90,300)),
'unit=METER') as distance
FROM AIRSPACE_BORDER_GEOMETRY g, AIRSPACE_BORDER b, AIRSPACE asp
WHERE g.ARSPC_BORDER_UID =123;

DISTANCE
--------
148.808025088469


Am I doing something wrong? Any ideas would be greatly appreciated. Thanks.
  • 1. Re: SDO_DISTANCE and tolerance
    Simon Greener Journeyer
    Currently Being Moderated
    user5394025 (Your real name?),

    First off, to find out the distance between the two execute the sdo_distance function with the recommended geodetic tolerance value of 0.05m.
    SELECT 
     SDO_GEOM.SDO_DISTANCE(
       SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-50, 48, NULL), NULL, NULL), 
       SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL), 
     0.05) as distance 
     FROM dual;
    -- Result
    --
    DISTANCE
    --------
    149.250705285824 
    So, 149.25 meter is the actual distance between your two geometries.

    Your tolerances look like you are checking distances rather than stating the precision of the data as a distance between any two vertices for those vertices to be the same.

    So, while one cannot be sure exactly how SDO_DISTANCE will perform using tolerance values as actual distances appears to be collapsing the distance between the two geometries (or two vertices on those objects) such that it becomes so close to the actual tolerance that the objects are snapped together.

    To see this rough effect check this:
    SELECT 90+(level*10) as tolerance,
           SDO_GEOM.SDO_DISTANCE(
               SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-50, 48, NULL), NULL, NULL), 
               SDO_GEOMETRY(2001, 8265, SDO_POINT_TYPE(-49.998, 48, NULL), NULL, NULL), 
               90+(level*10)) as distance 
      FROM dual
    CONNECT BY LEVEL < 6;
    -- Results
    --
    TOLERANCE DISTANCE
    --------- --------
          100 149.250705285824 
          110 149.250705285824 
          120        0 
          130        0 
          140        0
    SDO_DISTANCE calculates a distance between two objects. They can only be a certain distance apart so as long as the tolerance doesn't "collapse" the two geometries together, that distance will always remain the same regardless as to tolerance.

    Don't mix tolerances and distances.

    regards
    Simon

Legend

  • Correct Answers - 10 points
  • Helpful Answers - 5 points