1 Reply Latest reply on Sep 27, 2012 4:23 AM by Simon Greener

# SDO_DISTANCE and tolerance

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
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