sdo_distance

Hi, I took the following limits for 32616 EPSG SRID and trying to calculate the distance.

Proposed limits:
166021,44 0.00
534994.66 9329005.18

SELECT sdo_geom.sdo_distance (sdo_geom.sdo_geometry (2001, 32616, sdo_geom.sdo_point_type (166021.44, 0, NULL), NULL, NULL))

sdo_geom.sdo_geometry (2001, 32616, SDO_POINT (534994.66, 0, NULL), NULL, NULL), 0.0001, 'unit = COUNTER') distance_in_m

from DUAL;

I get the result 368973,22 m (368 km), I think that the distance should be approximately 600 km.

Please help me if I'm wrong.

Thank you

The spherical difference should be smaller, your second point seems not wrong, here you can compare:

SELECT sdo_cs.transform(sdo_geometry(2001 ,4326 ,sdo_geom.sdo_point_type(-90, 0, NULL), NULL ,NULL),32616) FROM dual
--------------
(2001; 32616; (166021.443179323; 0; ); ; )

SELECT sdo_cs.transform(sdo_geometry(2001 ,4326 ,sdo_geom.sdo_point_type(-84, 0, NULL), NULL ,NULL),32616) FROM dual
--------------
(2001; 32616; (833978.556820659; 0; ); ; )

SELECT sdo_geom.sdo_distance
(sdo_geom.sdo_geometry(2001 ,32616 ,sdo_point_type(166021, 0, 0) ,NULL ,NULL),
  sdo_geom.sdo_geometry(2001 ,32616 ,sdo_point_type(833978, 0, 0) ,NULL ,NULL)
  ,0.0001 ,'unit=KM') distance_in_m
  FROM DUAL;
--------------
667,957

Tags: Database

Similar Questions

  • Bad result SDO_DISTANCE?

    I try to use SDO_DISTANCE to calculate the distance of the flight from Dallas to Frankfurt. According to various Internet sites, this distance is about 8 266 kilometers.

    The following query gives 11 618 km. I made sure the details are correct.

    Select SDO_GEOM. () SDO_DISTANCE

    MDSYS. SDO_GEOMETRY)

    2001

    4326

    MDSYS. SDO_POINT (32.7801300,-96.8004511, NULL)

    NULL

    NULL

    )

    MDSYS. SDO_GEOMETRY)

    2001

    4326

    MDSYS. SDO_POINT (50.121212,8.6365638, NULL)

    NULL

    NULL

    )

    1

    'unit = KM'

    ) As a double dist_in_km;

    No idea why the result is different?

    Christoph,

    MDSYS. SDO_POINT parameters are longitude then latitude. So when you change them all about you will get the answer you expect.

    Select SDO_GEOM. () SDO_DISTANCE

    MDSYS. SDO_GEOMETRY)

    2001

    4326

    MDSYS. SDO_POINT (-96.8004511,32.7801300, NULL)

    NULL

    NULL

    )

    MDSYS. SDO_GEOMETRY)

    2001

    4326

    MDSYS. SDO_POINT (8.6365638,50.121212, NULL)

    NULL

    NULL

    )

    1

    'unit = KM'

    ) AS the double dist_in_km

    Kind regards.

    Ivan

  • Performance SDO_DISTANCE

    Table A_SPATIAL has 15 million records with different values of longitude and latitude. I also have the SDO_GEOMETRY shape, which stores the column SDO_GEOMETRY (2001, 8307, MDSYS.) SDO_POINT_TYPE (LONGITUDE, LATITUDE, NULL), NULL, NULL).

    I created the function and the index below:

    create or replace function get_long_lat_pt(longitude in number,  
                                             latitude in number)  
    return SDO_GEOMETRY deterministic is  
    begin  
    return sdo_geometry(2001, 8307,  
                    sdo_point_type(longitude, latitude, NULL),NULL, NULL);  
    end;  
    / 
    INSERT INTO user_sdo_geom_metadata VALUES(  
    'A_SPATIAL', -- table  
    'SHAPE', -- function  
       mdsys.sdo_dim_array( 
          mdsys.sdo_dim_element('LONGITUDE', -180, 180, 0.005),  
          mdsys.sdo_dim_element('LATITUDE', -90, 90, 0.005)  
       ), 
       8307  -- SRID  
        ); 
    commit;  
    CREATE INDEX A_SPATIAL_SHAPE_IDX  
    ON A_SPATIAL(Shape)  
    INDEXTYPE IS MDSYS.SPATIAL_INDEX;  
    
    

    Then when I run the query below, it performs a full table scan. Even though I have the index above, the index get used because I use SDO_DISTANCE to wrap around her, I guess. The longitude and latitude provided to the get_long_lat_pt function below are some user input, and they all vary.

    select * from A_SPATIAL where  
    SDO_GEOM.SDO_DISTANCE(SHAPE, get_long_lat_pt(95.224, 31.601), 1, 'unit=MILE') < 20;  
    
    

    Issues related to the:

    1. What is the optimal way of running this query to perform the best? I guess the full table scan is obvious as I need to calculate the distance, but is there a way to improve the performance?

    2 is the index above or even useful at all?

    3. I use SDO_WITHIN_DISTANCE in my case, but it would run a full table in any case scan because I still need to calculate the distance. He would perform better than the example above?

    Thank you.

    The only difference in your queries (Simplified) is the max_resolution of the additional parameter, it is only applied in the other, but max_resolution = 400 is big enough?

    Don't know if it makes a difference separating the parameters with ',' I got the same result.

    'distance=400, max_resolution=400 , unit=mile') = 'TRUE';
    
    'distance=400 max_resolution=400, unit=mile') = 'TRUE';
    

    You can try to force ORACLE to use the INDEX and the execution of test plan:

    SELECT /*+ INDEX (g a_spatial_shape_idx) */
           SDO_GEOM.SDO_DISTANCE(shape, get_long_lat_pt(95.224, 31.601),0.001,'unit=mile') dist
      FROM a_spatial g
     WHERE SDO_WITHIN_DISTANCE(shape, get_long_lat_pt(95.224, 31.601),'distance=400 unit=mile') = 'TRUE'
     ORDER BY dist;
    

    If you can use the postal code instead of lat/lon for the query results, of course, create an index on the zip code, use it in the WHERE clause and test execution plan.

  • SDO_DISTANCE - tolerance

    If I point 2 parms (not), with lat/long with decimal places in 5 to 7 in long, and I wanted to calculate the distance less than 5 CM, the formula would be:

    SELECT MDSYS. SDO_GEOM. () SDO_DISTANCE
    mdsys.sdo_geometry(2001,8307,mdsys.) SDO_POINT_TYPE(f_long,f_lat,null), NULL, null),
    mdsys.sdo_geometry(2001,8307,mdsys.) SDO_POINT_TYPE(t_long,t_lat,null), NULL, null),
    .05, 'unit = KM') AS km_dist2 FROM dual;

    What would be the equivalent (roughly 5 cm) using a unit = MILE? I have to use a tolerance de.0005?

    SELECT MDSYS. SDO_GEOM. () SDO_DISTANCE
    mdsys.sdo_geometry(2001,8307,mdsys.) SDO_POINT_TYPE(f_long,f_lat,null), NULL, null),
    mdsys.sdo_geometry(2001,8307,mdsys.) SDO_POINT_TYPE(t_long,t_lat,null), NULL, null),
    (. 0005, 'unit = MILE') AS mi_dist2 FROM dual;

    Thank you
    JB

    IBO

    Spatial documentation matches the following description of the tolerance.

    1.5.5 tolerance

    Tolerance is used to associate a level of precision with spatial data. Tolerance reflects the distance two points can be separated and still be considered to be identical (for example, to account for rounding errors). The tolerance value must be a non-negative number greater than zero. The importance of the value depends on whether or not the spatial data are associated with a geodetic coordinate system. (Geodetic and other types of coordinate systems are described in Section 1.5.4)

    For geodetic data (such as data by the longitude and latitude coordinates), the tolerance value is a number of counters. For example, a value of tolerance of 100 indicates a tolerance of 100 meters.

    For non-geodesique data, the tolerance value is a number of units that are associated with the coordinate system associated with the data. For example, if the unit of measure is miles, a tolerance of 0.005 value indicates a tolerance of 0.005 (in other words, 1/200) thousand (about 105 feet) and a value of tolerance of 2 indicates a tolerance of two miles.

    In both cases, the value of tolerance, precision is to be associated with the data.

    A tolerance value is specified in two cases:

    In the metadata definition of the geometry of a layer (see Section 1.5.5.1)

    As an optional entry to certain functions (see point 1.5.5.2) setting

    Concerning

    Ivan

  • Vs MDSYS Haversine formula. SDO_GEOM. SDO_DISTANCE

    We need calculate the distance between 2 lat/long (from the GPS unit).

    What is more precise, the use of MDSYS. SDO_GEOM. SDO_DISTANCE or a hand coded formula Haversine?

    Thank you
    JB

    Well, the best thing to do is to perform a test.

    I looked at this website: http://www.movable-type.co.uk/scripts/latlong-vincenty.html

    The answer to the default functional demo is 969954.114 meters.

    Test with SDO_DISTANCE, we get (I converted values DMS to DD):

    select sdo_geom.sdo_distance(
              sdo_geometry(2001,8307,sdo_point_type(-5.71475,      50.0663222222,null),null,null),
              sdo_geometry(2001,8307,sdo_point_type(-3.07009444444,58.6440222222,null),null,null),
              0.05) as dist
      from dual;
    -- Result
    --
    969954.113110585
    

    Which is pretty similar!

    So, don't bother coding your own Haversine (you need to add additional parameters to pass in parameters to ellisodal for non - WGS84 SRID...), use what comes out of the box.

    That answer your question? If so, please give points.

    concerning
    Simon

  • Find the minimum distance between two SDO_GEOMETRY in Oracle Spatial?

    annular ring edit.png

    A circle (SDO_GEOMETRY)
    B - polygon (SDO_GEOMETRY)

    CASE:
    B contains A (or)
    The Interior of B.

    How to find the minimum distance between A and B in Oracle Spatial

    Hello guuid nameless person.

    What is

    my_answer := MDSYS.SDO_GEOM.SDO_DISTANCE(
       my_circle_geometry
      ,MDSYS.SDO_UTIL.POLYGONTOLINE(my_outer_polygon)
      ,my_tolerance
    );
    

    Now, you may need to pay attention to the holes in your polygon, would you the distance and an inner ring if it was closer to you?

    If the measure is only to outer rings, so something like

    my_answer := MDSYS.SDO_GEOM.SDO_DISTANCE(
       my_circle_geometry
      ,MDSYS.SDO_UTIL.POLYGONTOLINE(
          MDSYS.SDO_UTIL.EXTRACT(my_outer_polygon,1,1)
       )
      ,my_tolerance
    );
    

    And then also beware of the multipolygons as the foregoing only measured against the first polygon in the MultiPolygon.  You need to loop through the polygons of tests just the outer ring in this case.

    See you soon,.

    Paul

  • Problems with validation

    I went from one ploygon is and I'm now getting a validation error. The error is 13351 indicating the crossing, but makes no sense since the geometry has changed only to become bigger. No changes were made to the difference between the ring and the polygon.

    -Geometry valid

    POLYGON ((-135.0 30,5,-134.99185 30.041386,-134.98405 30.034086,-134.95401 30.005964,-134.94765 30,0,-133.5 30,0,-133.5 30,5,-135.0 30,5), (-134.14302 30.005978,-134.15857 30.006021 - 134.1741 30.006367-, 134.18962 30.007006 - 134.20514 30.00795-, 134.22061 30.009184 - 134.23605 30.010723-, 30.012556 - 134.2668 30.014683 - 134.25145, 134.28804 30.019129 - 134.3007 30.02694-, 30.036272 - 134.32144 30.046923 - 134.31192, 134.32907 30.05866 - 134.33464 30.071234-, 30.084389 - 134.33902 30.097822 - 134.33798, 134.33699 30.111183 - 134.33412 30.124422-, 30.1375 - 134.3264 30.1505 - 134.33043, 134.32031 30.162872)) ,-134.31268 30.174572 - 134.30228 30.184523-, 134.28958 30.192234 - 134.27316 30.1978-, 134.228 30.207745 - 134.1761 30.2131-, 134.12085 30.212633 - 134.04973 30.202162-, 133.9964 30.189205 - 133.9541 30.17085-, 133.9415 30.162994 - 133.9309 30.153177-, 133.92265 30.141773 - 133.91707 30.129238-, 133.91539 30.115883 - 133.91785 30.102583-, 133.92172 30.089539 - 133.92686 30.076834-, 133.9339 30.064833 - 133.94272 30.053745-, 30.043777 - 133.96469 30.034756 - 133.95316, 133.97697 30.026539 - 133.9909 30.0206-, 30.016367 - 134.03474 30.014029 - 134.01944, 134.0501 30.01199 - 134.0655 30.010244-, 30.008795 - 134.09645 30.007645 - 134.08096, 134.11195 30.006788-134.12749 30.006233 (,-134.14302 30.005978))


    -Invalid geometry, (only differences is polygon is shifted is)

    POLYGON ((-135.0 30,5,-134.99185 30.041386,-134.98405 30.034086,-134.95401 30.005964,-134.94765 30,0,-132.0 30,0,-132.0 30,5,-135.0 30,5), (-134.14302 30.005978,-134.15857 30.006021 - 134.1741 30.006367-, 134.18962 30.007006 - 134.20514 30.00795-, 134.22061 30.009184 - 134.23605 30.010723-, 30.012556 - 134.2668 30.014683 - 134.25145, 134.28804 30.019129 - 134.3007 30.02694-, 30.036272 - 134.32144 30.046923 - 134.31192, 134.32907 30.05866 - 134.33464 30.071234-, 30.084389 - 134.33902 30.097822 - 134.33798, 134.33699 30.111183 - 134.33412 30.124422-, 30.1375 - 134.3264 30.1505 - 134.33043, 134.32031 30.162872)) ,-134.31268 30.174572 - 134.30228 30.184523-, 134.28958 30.192234 - 134.27316 30.1978-, 134.228 30.207745 - 134.1761 30.2131-, 134.12085 30.212633 - 134.04973 30.202162-, 133.9964 30.189205 - 133.9541 30.17085-, 133.9415 30.162994 - 133.9309 30.153177-, 133.92265 30.141773 - 133.91707 30.129238-, 133.91539 30.115883 - 133.91785 30.102583-, 133.92172 30.089539 - 133.92686 30.076834-, 133.9339 30.064833 - 133.94272 30.053745-, 30.043777 - 133.96469 30.034756 - 133.95316, 133.97697 30.026539 - 133.9909 30.0206-, 30.016367 - 134.03474 30.014029 - 134.01944, 134.0501 30.01199 - 134.0655 30.010244-, 30.008795 - 134.09645 30.007645 - 134.08096, 134.11195 30.006788-134.12749 30.006233 (,-134.14302 30.005978))

    Hello the number of name-less 1064020,

    Oracle spatial determines the validity of your GEODESIC geometry on the sphere, not a flat surface.  So in your original geometry that is large enough, the distance between the hole and the outer edge is only 447 meters.  As stretch you the outer ring of the geometry (you will double the size of it) of the lower edge of geometry "hiking upward" along the curve of the Earth.  However, the hole is anchored by many peaks to be where you placed it.  So, there's a point where they begin to cross.

    This is the measure of the gap before and after your stretching.

    WITH geometries AS (
      SELECT
        MDSYS.SDO_UTIL.POLYGONTOLINE(MDSYS.SDO_UTIL.EXTRACT(a.original,1,1))  AS original_outer
      ,MDSYS.SDO_UTIL.POLYGONTOLINE(MDSYS.SDO_UTIL.EXTRACT(a.original,1,2))  AS original_hole
      ,MDSYS.SDO_UTIL.POLYGONTOLINE(MDSYS.SDO_UTIL.EXTRACT(a.stretched,1,1)) AS stretched_outer
      ,MDSYS.SDO_UTIL.POLYGONTOLINE(MDSYS.SDO_UTIL.EXTRACT(a.stretched,1,2)) AS stretched_hole
      FROM (
          SELECT
          MDSYS.SDO_GEOMETRY('POLYGON ((-135.0 30.5,-134.99185 30.041386,-134.98405 30.034086,-134.95401 30.005964,-134.94765 30.0,-133.5 30.0,-133.5 30.5, -135.0 30.5),( -134.14302 30.005978,-134.15857 30.006021,-134.1741 30.006367,-134.18962 30.007006,-134.20514 30.00795,-134.22061 30.009184,-134.23605 30.010723,-134.25145 30.012556,-134.2668 30.014683,-134.28804 30.019129,-134.3007 30.02694,-134.31192 30.036272,-134.32144 30.046923,-134.32907 30.05866,-134.33464 30.071234,-134.33798 30.084389,-134.33902 30.097822,-134.33699 30.111183,-134.33412 30.124422,-134.33043 30.1375,-134.3264 30.1505,-134.32031 30.162872,-134.31268 30.174572,-134.30228 30.184523,-134.28958 30.192234,-134.27316 30.1978,-134.228 30.207745,-134.1761 30.2131,-134.12085 30.212633,-134.04973 30.202162,-133.9964 30.189205,-133.9541 30.17085,-133.9415 30.162994,-133.9309 30.153177,-133.92265 30.141773,-133.91707 30.129238,-133.91539 30.115883,-133.91785 30.102583,-133.92172 30.089539,-133.92686 30.076834,-133.9339 30.064833,-133.94272 30.053745,-133.95316 30.043777,-133.96469 30.034756,-133.97697 30.026539,-133.9909 30.0206,-134.01944 30.016367,-134.03474 30.014029,-134.0501 30.01199,-134.0655 30.010244,-134.08096 30.008795,-134.09645 30.007645,-134.11195 30.006788,-134.12749 30.006233,-134.14302 30.005978))',8265) AS original
          ,MDSYS.SDO_GEOMETRY('POLYGON ((-135.0 30.5,-134.99185 30.041386,-134.98405 30.034086,-134.95401 30.005964,-134.94765 30.0,-132.0 30.0,-132.0 30.5, -135.0 30.5),( -134.14302 30.005978,-134.15857 30.006021,-134.1741 30.006367,-134.18962 30.007006,-134.20514 30.00795,-134.22061 30.009184,-134.23605 30.010723,-134.25145 30.012556,-134.2668 30.014683,-134.28804 30.019129,-134.3007 30.02694,-134.31192 30.036272,-134.32144 30.046923,-134.32907 30.05866,-134.33464 30.071234,-134.33798 30.084389,-134.33902 30.097822,-134.33699 30.111183,-134.33412 30.124422,-134.33043 30.1375,-134.3264 30.1505,-134.32031 30.162872,-134.31268 30.174572,-134.30228 30.184523,-134.28958 30.192234,-134.27316 30.1978,-134.228 30.207745,-134.1761 30.2131,-134.12085 30.212633,-134.04973 30.202162,-133.9964 30.189205,-133.9541 30.17085,-133.9415 30.162994,-133.9309 30.153177,-133.92265 30.141773,-133.91707 30.129238,-133.91539 30.115883,-133.91785 30.102583,-133.92172 30.089539,-133.92686 30.076834,-133.9339 30.064833,-133.94272 30.053745,-133.95316 30.043777,-133.96469 30.034756,-133.97697 30.026539,-133.9909 30.0206,-134.01944 30.016367,-134.03474 30.014029,-134.0501 30.01199,-134.0655 30.010244,-134.08096 30.008795,-134.09645 30.007645,-134.11195 30.006788,-134.12749 30.006233,-134.14302 30.005978))',8265) AS stretched
          FROM
          dual
      ) a
    )
    SELECT
    MDSYS.SDO_GEOM.SDO_DISTANCE(a.original_outer,a.original_hole,0.05) AS original_gap
    ,MDSYS.SDO_GEOM.SDO_DISTANCE(a.stretched_outer,a.stretched_hole,0.05) AS stretched_gap
    FROM
    geometries a;
    

    If you wish to change your geometries in this way, you must use a projected coordinate system.  You can also simply densify your GEODESIC geometry by adding more points along the long edges of the polygon.

    This happens from time to time on the forum, I searched on a good explanation online but couldn't find something simple.  Someone else has a link to 1064020?

    See you soon,.

    Paul

  • sdo_within_distance return invalid results

    I use sdo_within_distance, and I notice that there are cases where results contain geometries that are outside the distance, I said. In the example below, the geometry is returned even if it is 4 miles from the reference geometry. If I use sdo_nn with the remote setting, the correct results are returned. DB version is 12.1.0.1.0

    Create the table testdistance

    (

    Identification number,

    geom sdo_geometry

    );

    Insert into testdistance (ID, GEOM) values (1, MDSYS. SDO_GEOMETRY (2001,4326, MDSYS. SDO_POINT_TYPE(-117.234313964844,32.7089462280273,), NULL, NULL));

    Insert into testdistance (ID, GEOM) values (477488906, MDSYS. SDO_GEOMETRY (2003,4326, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,1003,1), MDSYS. SDO_ORDINATE_ARRAY(-117.175918579102,32.6773681640625,-117.17529296875,32.6780090332031,-117.174987792969,32.6778030395508,-117.17561340332,32.6771392822266,-117.175918579102,32.6773681640625)));

    insert into (table_name, column_name, diminfo, srid) user_sdo_geom_metadata

    values ('TESTDISTANCE', "GEOM", MDSYS. SDO_DIM_ARRAY (MDSYS. SDO_DIM_ELEMENT ('Longitude',-180, 180, 0.05), MDSYS. SDO_DIM_ELEMENT('Latitude',-90,90,0.05)), 4326);

    create index testdistance_sidx on testdistance (geom) INDEXTYPE IS MDSYS. SPATIAL_INDEX;

    -results of evil

    WITH the entry INTO

    (SELECT / * + materialize * / idgeom )

    OF testdistance

    ID WHERE = 1

    )

    SELECT / * + index (testdistance, testdistance_sidx) * / testdistance.id, testdistance.geom, sdo_geom.sdo_distance (testdistance.geom, input.geom, 0.05, ' unit = mile') dist

    Testdistance entry

    WHERE sdo_within_distance (testdistance.geom, input.geom, 'distance = 2.5 unit = mile') = 'TRUE '.

    -correct results

    WITH the entry INTO

    (SELECT / * + materialize * / idgeom )

    OF testdistance

    ID WHERE = 1

    )

    SELECT / * + index (testdistance, testdistance_sidx) * / testdistance.id, testdistance.geomSDO_NN_DISTANCE (1) dist

    Testdistance entry

    WHERE sdo_nn (testdistance.geom, input.geom, 'distance = 2.5 thousand = unit', 1) = "TRUE".

    Geometry with id = 477488906 is not valid because its outer ring is

    in a clockwise direction. You can use the following query to check them.

    Select sdo_geom.validate_geometry (geom, 0.05), id testdistance;

    Once the geometry with id = 477488906 is corrected (e.g. using sdo_util.rectify_geometry),

    the result of sdo_within_distance() should be good.

  • How gaps (fill) when converting to a 2006 geometry in a geometry of 2002

    Is it possible to fill (filling) the differences when converting to a geometry in a single geometry of 2002 in 2006. I have a solution for the conversion of 2006 to 2002 provided by BHall but on other investigation of my dataset some of the multi line polygons are weak I need to fill and I don't know how to go on this subject.

    Here is a simple example of what I'm trying to reach

    Front

    SELECT (sdo_geometry (2006, 81989, NULL,))

    MDSYS.sdo_elem_info_array (1,2,1,5,2,1,9,2,1,13,2,1),

    MDSYS.sdo_ordinate_array (16,0.999,16.998,-0,001, 17.253,-0.001, 18.003, 0.999, 18.003, 0.999, 19.001, 0.999, 19.001, 0.999, 19,999,-0,001)))

    OF the double

    After

    SELECT (sdo_geometry (2006, 81989, NULL,))

    MDSYS.sdo_elem_info_array (1,2,1),

    MDSYS.sdo_ordinate_array (16,0.999,17.253,-0.001,18.003,0.999,19.001,0.999,19.999,-0.001))) DOUBLE

    Thanks in advance

    Hi rock,

    Well, I ran all three examples that you sent through my code and it seemed to work!  I pasted the code above in a "pre" html tag and I can still see things deteriorated.  Lemme try this with a different syntax.  You know that this new forum software not only grew on me.  It's just clumsy and exaggerated.  And those weird people at the top.  What were they looking at?  I imagine that Larry on some loft above.

    Anyway, you are right that when Bryan code is used to convert the multiple string, the gaps are filled.  But that's because he wrote of this approach.

    Really, there is no generic way to convert a multiple line string we are discussing.  If you use SDO_UTIL. CONCATENATE_LINES, it will leave gaps.

    See you soon,.

    Paul

    CREATE OR REPLACE PACKAGE dz_gap_fill
    AUTHID CURRENT_USER
    AS
    
       FUNCTION linear_gap_filler(
           p_input            IN  MDSYS.SDO_GEOMETRY
          ,p_tolerance        IN  NUMBER DEFAULT 0.05
       ) RETURN MDSYS.SDO_GEOMETRY;
    
    END dz_gap_fill;
    
    CREATE OR REPLACE PACKAGE BODY dz_gap_fill
    AS
    
       FUNCTION fast_point(
           p_x             IN  NUMBER
          ,p_y             IN  NUMBER
          ,p_z             IN  NUMBER DEFAULT NULL
          ,p_m             IN  NUMBER DEFAULT NULL
          ,p_srid          IN  NUMBER DEFAULT 8265
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
       BEGIN
    
          --------------------------------------------------------------------------
          -- Step 10
          -- Check over incoming parameters
          --------------------------------------------------------------------------
          IF p_x IS NULL
          OR p_y IS NULL
          THEN
             RAISE_APPLICATION_ERROR(-20001,'x and y cannot be NULL');
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 20
          -- Do the simplest solution first
          --------------------------------------------------------------------------
          IF  p_z IS NULL
          AND p_m IS NULL
          THEN
             RETURN SDO_GEOMETRY(
                 2001
                ,p_srid
                ,SDO_POINT_TYPE(
                     p_x
                    ,p_y
                    ,NULL
                 )
                ,NULL
                ,NULL
             );
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 30
          -- Do the other wilder choices
          --------------------------------------------------------------------------
          IF p_z IS NULL
          AND p_m IS NOT NULL
          THEN
             RETURN SDO_GEOMETRY(
                 3301
                ,p_srid
                ,SDO_POINT_TYPE(
                     p_x
                    ,p_y
                    ,p_m
                 )
                ,NULL
                ,NULL
             );
    
          ELSIF p_z IS NOT NULL
          AND   p_m IS NULL
          THEN
             RETURN SDO_GEOMETRY(
                 3001
                ,p_srid
                ,SDO_POINT_TYPE(
                     p_x
                    ,p_y
                    ,p_z
                 )
                ,NULL
                ,NULL
             );
    
          ELSIF p_z IS NOT NULL
          AND   p_m IS NOT NULL
          THEN
             RETURN SDO_GEOMETRY(
                 4401
                ,p_srid
                ,NULL
                ,SDO_ELEM_INFO_ARRAY(1,1,1)
                ,SDO_ORDINATE_ARRAY(p_x,p_y,p_z,p_m)
             );
    
          ELSE
             RAISE_APPLICATION_ERROR(-20001,'ERR!');
          END IF;
    
       END fast_point;
    
       FUNCTION get_start_point(
          p_input        IN  MDSYS.SDO_GEOMETRY
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
          int_dims PLS_INTEGER;
          int_gtyp PLS_INTEGER;
          int_lrs  PLS_INTEGER;
    
       BEGIN
    
          --------------------------------------------------------------------------
          -- Step 10
          -- Check over incoming parameters
          --------------------------------------------------------------------------
          IF p_input IS NULL
          THEN
             RETURN NULL;
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 20
          -- Gather information about the geometry
          --------------------------------------------------------------------------
          int_dims := p_input.get_dims();
          int_gtyp := p_input.get_gtype();
          int_lrs  := p_input.get_lrs_dim();
    
          --------------------------------------------------------------------------
          -- Step 30
          -- Handle point and multipoint inputs
          --------------------------------------------------------------------------
          IF int_gtyp = 1
          THEN
             RETURN p_input;
    
          ELSIF int_gtyp = 5
          THEN
             RETURN SDO_UTIL.EXTRACT(p_input,1);
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 40
          -- Return results
          --------------------------------------------------------------------------
          IF int_dims = 2
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(1)
                ,p_input.SDO_ORDINATES(2)
                ,NULL
                ,NULL
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 3
          AND int_lrs = 3
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(1)
                ,p_input.SDO_ORDINATES(2)
                ,NULL
                ,p_input.SDO_ORDINATES(3)
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 3
          AND int_lrs = 0
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(1)
                ,p_input.SDO_ORDINATES(2)
                ,p_input.SDO_ORDINATES(3)
                ,NULL
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 4
          AND int_lrs IN (4,0)
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(1)
                ,p_input.SDO_ORDINATES(2)
                ,p_input.SDO_ORDINATES(3)
                ,p_input.SDO_ORDINATES(4)
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 4
          AND int_lrs = 3
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(1)
                ,p_input.SDO_ORDINATES(2)
                ,p_input.SDO_ORDINATES(4)
                ,p_input.SDO_ORDINATES(3)
                ,p_input.SDO_SRID
             );
    
          ELSE
             RAISE_APPLICATION_ERROR(-20001,'ERR!');
    
          END IF;
    
       END get_start_point;
    
       FUNCTION get_end_point(
          p_input        IN  MDSYS.SDO_GEOMETRY
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
          int_dims PLS_INTEGER;
          int_gtyp PLS_INTEGER;
          int_lrs  PLS_INTEGER;
          int_len  PLS_INTEGER;
    
       BEGIN
    
          --------------------------------------------------------------------------
          -- Step 10
          -- Check over incoming parameters
          --------------------------------------------------------------------------
          IF p_input IS NULL
          THEN
             RETURN NULL;
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 20
          -- Gather information about the geometry
          --------------------------------------------------------------------------
          int_dims := p_input.get_dims();
          int_gtyp := p_input.get_gtype();
          int_lrs  := p_input.get_lrs_dim();
          int_len  := p_input.SDO_ORDINATES.COUNT();
    
          --------------------------------------------------------------------------
          -- Step 30
          -- Handle point and multipoint inputs
          --------------------------------------------------------------------------
          IF int_gtyp = 1
          THEN
             RETURN p_input;
          ELSIF int_gtyp = 5
          THEN
             RETURN SDO_UTIL.EXTRACT(
                 p_input
                ,SDO_UTIL.GETNUMELEM(p_input)
             );
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 40
          -- Return results
          --------------------------------------------------------------------------
          IF int_dims = 2
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(int_len - 1)
                ,p_input.SDO_ORDINATES(int_len)
                ,NULL
                ,NULL
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 3
          AND int_lrs = 3
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(int_len - 2)
                ,p_input.SDO_ORDINATES(int_len - 1)
                ,NULL
                ,p_input.SDO_ORDINATES(int_len)
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 3
          AND int_lrs = 0
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(int_len - 2)
                ,p_input.SDO_ORDINATES(int_len - 1)
                ,p_input.SDO_ORDINATES(int_len)
                ,NULL
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 4
          AND int_lrs IN (4,0)
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(int_len - 3)
                ,p_input.SDO_ORDINATES(int_len - 2)
                ,p_input.SDO_ORDINATES(int_len - 1)
                ,p_input.SDO_ORDINATES(int_len)
                ,p_input.SDO_SRID
             );
    
          ELSIF  int_dims = 4
          AND int_lrs = 3
          THEN
             RETURN fast_point(
                 p_input.SDO_ORDINATES(int_len - 3)
                ,p_input.SDO_ORDINATES(int_len - 2)
                ,p_input.SDO_ORDINATES(int_len)
                ,p_input.SDO_ORDINATES(int_len - 1)
                ,p_input.SDO_SRID
             );
    
          ELSE
             RAISE_APPLICATION_ERROR(-20001,'ERR!');
    
          END IF;
    
       END get_end_point;
    
       FUNCTION is_spaghetti(
           p_input             IN  MDSYS.SDO_GEOMETRY
          ,p_tolerance         IN  NUMBER DEFAULT 0.05
       ) RETURN VARCHAR2
       AS
          num_tolerance    NUMBER := p_tolerance;
          ary_strings      MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY();
          ary_starts       MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY();
          ary_ends         MDSYS.SDO_GEOMETRY_ARRAY := MDSYS.SDO_GEOMETRY_ARRAY();
          int_count        PLS_INTEGER;
          ary_start_count  MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY();
          ary_end_count    MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY();
          ary_inside_count MDSYS.SDO_NUMBER_ARRAY := MDSYS.SDO_NUMBER_ARRAY();
    
       BEGIN
    
          --------------------------------------------------------------------------
          -- Step 10
          -- Check over incoming parameters
          --------------------------------------------------------------------------
          IF p_input IS NULL
          THEN
             RETURN NULL;
    
          ELSIF p_input.get_gtype = 2
          THEN
             RETURN 'FALSE';
    
          ELSIF p_input.get_gtype <> 6
          THEN
             RAISE_APPLICATION_ERROR(-20001,'input gtype must be 2 or 6');
    
          END IF;
    
          IF num_tolerance IS NULL
          THEN
             num_tolerance := 0.05;
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 20
          -- Break multistring into single linestrings with nodes
          --------------------------------------------------------------------------
          int_count := SDO_UTIL.GETNUMELEM(p_input);
          ary_strings.EXTEND(int_count);
          ary_starts.EXTEND(int_count);
          ary_ends.EXTEND(int_count);
          ary_start_count.EXTEND(int_count);
          ary_end_count.EXTEND(int_count);
          ary_inside_count.EXTEND(int_count);
          FOR i IN 1 .. int_count
          LOOP
             ary_strings(i) := SDO_UTIL.EXTRACT(p_input,i);
             ary_starts(i)  := get_start_point(ary_strings(i));
             ary_ends(i)    := get_end_point(ary_strings(i));
    
          END LOOP;
    
          --------------------------------------------------------------------------
          -- Step 30
          -- Loop through and count the nodes connections
          --------------------------------------------------------------------------
          FOR i IN 1 .. int_count
          LOOP
             ary_start_count(i)  := 0;
             ary_end_count(i)    := 0;
             ary_inside_count(i) := 0;
    
             FOR j IN 1 .. int_count
             LOOP
                IF i != j
                THEN
                   IF SDO_GEOM.RELATE(
                      ary_starts(i),
                      'DETERMINE',
                      ary_strings(j),
                      num_tolerance
                   ) IN ('TOUCH','CONTAINS','COVERS','ON')
                   THEN
                      ary_start_count(i) := ary_start_count(i) + 1;
    
                   ELSIF SDO_GEOM.RELATE(
                      ary_ends(i),
                      'DETERMINE',
                      ary_strings(j),
                      num_tolerance
                   ) IN ('TOUCH','CONTAINS','COVERS','ON')
                   THEN
                      ary_end_count(i) := ary_end_count(i) + 1;
    
                   ELSIF SDO_GEOM.RELATE(
                      ary_strings(i),
                      'DETERMINE',
                      ary_strings(j),
                      num_tolerance
                   ) IN ('TOUCH','CONTAINS','COVERS','OVERLAPBYINTERSECT')
                   THEN
                      ary_inside_count(i) := ary_inside_count(i) + 1;
    
                   END IF;
    
                END IF;
    
             END LOOP;
    
             IF ary_start_count(i) > 1
             OR ary_end_count(i) > 1
             OR ary_inside_count(i) > 0
             THEN
                RETURN 'TRUE';
             END IF;
    
          END LOOP;
    
          RETURN 'FALSE';
    
       END is_spaghetti;
    
       -----------------------------------------------------------------------------
       -----------------------------------------------------------------------------
       FUNCTION points2segment(
           p_point_one              IN  MDSYS.SDO_POINT_TYPE
          ,p_point_two              IN  MDSYS.SDO_POINT_TYPE
          ,p_srid                   IN  NUMBER
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
       BEGIN
    
          IF ( p_point_one.Z IS NULL AND p_point_two.Z IS NOT NULL )
          OR ( p_point_one.Z IS NOT NULL AND p_point_two.Z IS NULL )
          THEN
             RAISE_APPLICATION_ERROR(
                -20001,
                'both points must have the same number of dimensions, point_one Z is ' ||
                NVL(TO_CHAR(p_point_one.Z),'') ||
                ' and point_two Z is ' ||
                NVL(TO_CHAR(p_point_two.Z),'')
             );
    
          END IF;
    
          IF p_point_one.Z IS NULL
          THEN
             RETURN SDO_GEOMETRY(
                 2002
                ,p_srid
                ,NULL
                ,SDO_ELEM_INFO_ARRAY(1,2,1)
                ,SDO_ORDINATE_ARRAY(p_point_one.X,p_point_one.Y,p_point_two.X,p_point_two.Y)
             );
    
          ELSE
             RETURN SDO_GEOMETRY(
                 3002
                ,p_srid
                ,NULL
                ,SDO_ELEM_INFO_ARRAY(1,2,1)
                ,SDO_ORDINATE_ARRAY(p_point_one.X,p_point_one.Y,p_point_one.Z,p_point_two.X,p_point_two.Y,p_point_two.Z)
             );
    
          END IF;
    
       END points2segment;
    
       -----------------------------------------------------------------------------
       -----------------------------------------------------------------------------
       FUNCTION points2segment(
           p_point_one              IN  MDSYS.SDO_GEOMETRY
          ,p_point_two              IN  MDSYS.SDO_GEOMETRY
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
          int_gtype1 PLS_INTEGER;
          int_dims1  PLS_INTEGER;
          int_gtype2 PLS_INTEGER;
          int_dims2  PLS_INTEGER;
          point_one  MDSYS.SDO_POINT_TYPE;
          point_two  MDSYS.SDO_POINT_TYPE;
    
       BEGIN
    
          int_gtype1 := p_point_one.get_gtype();
          int_dims1  := p_point_one.get_dims();
          int_gtype2 := p_point_two.get_gtype();
          int_dims2  := p_point_two.get_dims();
    
          IF  int_gtype1 = 1
          AND int_gtype2 = 1
          AND int_dims1  = int_dims2
          AND p_point_one.SDO_SRID = p_point_two.SDO_SRID
          THEN
             NULL;  -- Good
    
          ELSE
             RAISE_APPLICATION_ERROR(
                 -20001
                ,'both point objects must be points and have the same number of dimensions and SRIDs'
             );
    
          END IF;
    
          IF int_dims1 = 4
          THEN
             RETURN SDO_GEOMETRY(
                 4402
                ,p_point_one.SDO_SRID
                ,NULL
                ,SDO_ELEM_INFO_ARRAY(1,2,1)
                ,SDO_ORDINATE_ARRAY(
                     p_point_one.SDO_ORDINATES(1)
                    ,p_point_one.SDO_ORDINATES(2)
                    ,p_point_one.SDO_ORDINATES(3)
                    ,p_point_one.SDO_ORDINATES(4)
                    ,p_point_two.SDO_ORDINATES(1)
                    ,p_point_two.SDO_ORDINATES(2)
                    ,p_point_two.SDO_ORDINATES(3)
                    ,p_point_two.SDO_ORDINATES(4)
                )
             );
    
          ELSE
             -- Use the sdo_point_type method for the rest
             IF p_point_one.SDO_POINT IS NOT NULL
             THEN
                point_one := p_point_one.SDO_POINT;
    
             ELSE
                IF int_dims1 = 3
                THEN
                   point_one := SDO_POINT_TYPE(
                       p_point_one.SDO_ORDINATES(1)
                      ,p_point_one.SDO_ORDINATES(2)
                      ,p_point_one.SDO_ORDINATES(3)
                   );
    
                ELSE
                   point_one := SDO_POINT_TYPE(
                       p_point_one.SDO_ORDINATES(1)
                      ,p_point_one.SDO_ORDINATES(2)
                      ,NULL
                   );
    
                END IF;
    
             END IF;
    
             IF p_point_two.SDO_POINT IS NOT NULL
             THEN
                point_two := p_point_two.SDO_POINT;
    
             ELSE
                IF int_dims1 = 3
                THEN
                   point_two := SDO_POINT_TYPE(
                        p_point_two.SDO_ORDINATES(1)
                       ,p_point_two.SDO_ORDINATES(2)
                       ,p_point_two.SDO_ORDINATES(3)
                   );
    
                ELSE
                   point_two := SDO_POINT_TYPE(
                       p_point_two.SDO_ORDINATES(1)
                      ,p_point_two.SDO_ORDINATES(2)
                      ,NULL
                   );
    
                END IF;
    
             END IF;
    
             RETURN points2segment(
                 p_point_one   => point_one
                ,p_point_two   => point_two
                ,p_srid        => p_point_one.SDO_SRID
             );
    
          END IF;
    
       END points2segment;
    
       FUNCTION linear_gap_filler(
           p_input            IN  MDSYS.SDO_GEOMETRY
          ,p_tolerance        IN  NUMBER DEFAULT 0.05
       ) RETURN MDSYS.SDO_GEOMETRY
       AS
          sdo_input     MDSYS.SDO_GEOMETRY := p_input;
          num_tolerance NUMBER;
          int_counter   PLS_INTEGER;
          ary_edges     MDSYS.SDO_GEOMETRY_ARRAY;
          ary_starts    MDSYS.SDO_GEOMETRY_ARRAY;
          ary_ends      MDSYS.SDO_GEOMETRY_ARRAY;
          ary_nearest   MDSYS.SDO_NUMBER_ARRAY;
          ary_distance  MDSYS.SDO_NUMBER_ARRAY;
          num_temp      NUMBER;
          num_nearest   NUMBER;
          int_winner    PLS_INTEGER;
          int_winner2   PLS_INTEGER;
          sdo_point1    MDSYS.SDO_GEOMETRY;
          sdo_point2    MDSYS.SDO_GEOMETRY;
          boo_done      BOOLEAN;
          num_one       NUMBER;
          num_two       NUMBER;
          int_looper    PLS_INTEGER := 1;
    
       BEGIN
    
          --------------------------------------------------------------------------
          -- Step 10
          -- Check over incoming parameters
          --------------------------------------------------------------------------
          IF num_tolerance IS NULL
          THEN
             num_tolerance := 0.05;
    
          END IF;
    
          IF sdo_input IS NULL
          OR sdo_input.get_gtype() <> 6
          THEN
             RETURN sdo_input;
    
          END IF;
    
          IF is_spaghetti(sdo_input,p_tolerance) = 'TRUE'
          THEN
             RETURN sdo_input;
    
          END IF;
    
          <>
          ary_edges     := MDSYS.SDO_GEOMETRY_ARRAY();
          ary_starts    := MDSYS.SDO_GEOMETRY_ARRAY();
          ary_ends      := MDSYS.SDO_GEOMETRY_ARRAY();
          ary_nearest   := MDSYS.SDO_NUMBER_ARRAY();
          ary_distance  := MDSYS.SDO_NUMBER_ARRAY();
    
          --------------------------------------------------------------------------
          -- Step 20
          -- Break multistring into edges and start and end nodes
          --------------------------------------------------------------------------
          int_counter := SDO_UTIL.GETNUMELEM(sdo_input);
          ary_edges.EXTEND(int_counter);
          ary_starts.EXTEND(int_counter);
          ary_ends.EXTEND(int_counter);
          FOR i IN 1 .. int_counter
          LOOP
             ary_edges(i)  := SDO_UTIL.EXTRACT(sdo_input,i);
             ary_starts(i) := get_start_point(ary_edges(i));
             ary_ends(i)   := get_end_point(ary_edges(i));
    
          END LOOP;
    
          --------------------------------------------------------------------------
          -- Step 30
          -- Determine the closest endpoints
          --------------------------------------------------------------------------
          ary_nearest.EXTEND(int_counter);
          ary_distance.EXTEND(int_counter);
          FOR i IN 1 .. int_counter
          LOOP
             num_nearest := NULL;
             int_winner := NULL;
             FOR j IN 1 .. int_counter
             LOOP
                IF j != i
                THEN
                   num_temp := SDO_GEOM.SDO_DISTANCE(
                       ary_edges(i)
                      ,ary_edges(j)
                      ,num_tolerance
                   );
    
                   IF num_nearest IS NULL
                   OR num_temp < num_nearest
                   THEN
                      num_nearest := num_temp;
                      int_winner := j;
    
                   END IF;
    
                END IF;
    
             END LOOP;
    
             ary_nearest(i) := int_winner;
             ary_distance(i) := num_nearest;
    
          END LOOP;
    
          --------------------------------------------------------------------------
          -- Step 40
          -- Find the smallest gap
          --------------------------------------------------------------------------
          int_winner := NULL;
          num_nearest := NULL;
          FOR i IN 1 .. int_counter
          LOOP
             IF num_nearest IS NULL
             OR ary_distance(i) < num_nearest
             THEN
                 int_winner := i;
                 num_nearest := ary_distance(i);
                 int_winner2 := ary_nearest(i);
    
             END IF;
    
          END LOOP;
    
          --------------------------------------------------------------------------
          -- Step 50
          -- Determine the endpoints to connect
          --------------------------------------------------------------------------
          num_one := SDO_GEOM.SDO_DISTANCE(
             get_start_point(ary_edges(int_winner)),
             ary_edges(int_winner2),
             num_tolerance
          );
          num_two := SDO_GEOM.SDO_DISTANCE(
             get_end_point(ary_edges(int_winner)),
             ary_edges(int_winner2),
             num_tolerance
          );
    
          IF ( num_one = 0 AND SDO_GEOM.RELATE(
             get_start_point(ary_edges(int_winner)),
             'ANYINTERACT',
             ary_edges(int_winner2),
             num_tolerance
          ) = 'TRUE' )
          OR ( num_two = 0 AND SDO_GEOM.RELATE(
             get_end_point(ary_edges(int_winner)),
             'ANYINTERACT',
             ary_edges(int_winner2),
             num_tolerance
          ) = 'TRUE' )
          THEN
             sdo_point1 := NULL;
    
          ELSIF num_one < num_two
          THEN
             sdo_point1 := get_start_point(ary_edges(int_winner));
    
          ELSE
             sdo_point1 := get_end_point(ary_edges(int_winner));
    
          END IF;
    
          num_one := SDO_GEOM.SDO_DISTANCE(
             get_start_point(ary_edges(int_winner2)),
             ary_edges(int_winner),
             num_tolerance
          );
          num_two := SDO_GEOM.SDO_DISTANCE(
             get_end_point(ary_edges(int_winner2)),
             ary_edges(int_winner),
             num_tolerance
          );
    
          IF ( num_one = 0 AND SDO_GEOM.RELATE(
             get_start_point(ary_edges(int_winner2)),
             'ANYINTERACT',
             ary_edges(int_winner),
             num_tolerance
          ) = 'TRUE' )
          OR ( num_two = 0 AND SDO_GEOM.RELATE(
             get_end_point(ary_edges(int_winner2)),
             'ANYINTERACT',
             ary_edges(int_winner),
             num_tolerance
          ) = 'TRUE' )
          THEN
             sdo_point2 := NULL;
    
          ELSIF num_one < num_two
          THEN
             sdo_point2 := get_start_point(ary_edges(int_winner2));
    
          ELSE
             sdo_point2 := get_end_point(ary_edges(int_winner2));
    
          END IF;
    
          --------------------------------------------------------------------------
          -- Step 50
          -- Smash together
          --------------------------------------------------------------------------
          IF sdo_point1 IS NULL
          OR sdo_point2 IS NULL
          THEN
             sdo_input := SDO_UTIL.CONCAT_LINES(
                ary_edges(int_winner),
                ary_edges(int_winner2)
             );
    
          ELSE
             sdo_input := SDO_UTIL.CONCAT_LINES(
                SDO_UTIL.CONCAT_LINES(
                   ary_edges(int_winner),
                   points2segment(sdo_point1,sdo_point2)
                ),
                ary_edges(int_winner2)
             );
    
          END IF;
    
          boo_done := TRUE;
          FOR i IN 1 .. int_counter
          LOOP
             IF i NOT IN (int_winner,int_winner2)
             THEN
                sdo_input := SDO_UTIL.APPEND(sdo_input,ary_edges(i));
                boo_done := FALSE;
    
             END IF;
    
          END LOOP;
    
          --------------------------------------------------------------------------
          -- Step 60
          -- Check if valid if returning
          --------------------------------------------------------------------------
          IF sdo_input.get_gtype() = 2
          OR boo_done = TRUE
          THEN
             RETURN sdo_input;
    
          END IF;
    
          int_looper := int_looper + 1;
          GOTO TOP_OF_IT;
    
       END linear_gap_filler;
    
    END dz_gap_fill;
    
  • nested to perform DML and wait function call commit

    Hello world

    I would like to make a few DML - one insert statement, to be precise - in function and have the function and then return the number keys on the newly added row. I call this function from a different context and woud then be able to use the newly added data to do something.

    Specifically, what I do is the following: I have a graph composed of triplets source, destination and distance in a picture. A user should now be able to

    1.) add a node "A" to the curve.
    2.) add a node 'B' to the chart
    (3.) to get the shortest path from A to B in the graphs.

    I have an internal function
    function INSERT_NEW_NODE(node_in in sdo_geometry, graph_in in integer) return integer
    is  
    
    pragma autonomous_transaction;
    
    cursor node_cur is  
      select 
          source,
          source_geom
      from graph  
    ;
        
    cursor edge_cur is
        select
            source,
            destination,
            distance,
            edge_geom
        from
          graph
        where
          sdo_geom.relate(edge_geom, 'anyinteract', node_in, .005) = 'TRUE';
    
    begin
    
      -- check if identical with any existing node
      for node_rec in node_cur loop  
        if sdo_geom.relate(node_rec.source_geom, 'EQUAL', node_in, .005) = 'EQUAL' then
          return node_rec.source;
        end if;
      end loop;    
      
      -- get edges
      for edge_rec in edge_cur loop
         -- new_node-->edge.destination and vice versa
        insert into
          graph
          (
            ID,
            GRAPH,
            SOURCE,
            DESTINATION,
            DISTANCE,
            SOURCE_GEOM,
            DESTINATION_GEOM,
            EDGE_GEOM
          )
        values
        (
          graph_id_seq.nextval, --id
          graph_in, --graph
          morton(node_in.sdo_point.x, node_in.sdo_point.y),  -- source morton key
          edge_rec.source, -- destination morton key
          sdo_geom.sdo_distance(edge_rec.source_geom_marl2000, node_in, .005, 'unit=M'), -- distance
          node_in, -- source geom
          edge_rec.source_geom,  -- dest geom
          split_line(edge_rec.edge_geom_marl2000, node_in).segment1 -- edge geom
        );
        commit;
        --new_node-->edge.source and vice versa
        insert into
          gl_graph
          (
            ID,
            GRAPH,
            SOURCE,
            DESTINATION,
            DISTANCE,
            SOURCE_GEOM,
            DESTINATION_GEOM,
            EDGE_GEOM
          )
        values
        (
          graph_id_seq.nextval, --id
          graph_in, --graph
          edge_rec.source, -- source morton key
          morton(node_in.sdo_point.x, node_in.sdo_point.y), -- destination morton key
          sdo_geom.sdo_distance(edge_rec.source_geom, node_in, .005, 'unit=M'), -- distance
          edge_rec.source_geom,  -- source geom
          node_in, -- dest geom
          split_line(edge_rec.edge_geom, node_in).segment2 -- edge geom
        );
        commit;
      end loop
      ;
     
      return(morton(node_in.sdo_point.x, node_in.sdo_point.y));
      
    end insert_new_node;
    adding new nodes to the chart, links, calculates distances etc. and returns a handle to the newly added node. I call this function twice function, external
    function get_path (line_in in sdo_geometry, graph_in in integer) return sdo_geometry
    is  
    
    source number;
    destination number;
    source_geom mdsys.sdo_geometry;
    destination_geom mdsys.sdo_geometry;
      
    begin
      
      source := insert_new_node(get_firstvertex(line_in), graph_in);
      destination := insert_new_node(get_lastvertex(line_in), graph_in);
     
      -- source := insert_new_node(get_firstvertex(line_in), graph_in);
      -- destination := insert_new_node(get_lastvertex(line_in), graph_in);
      
      return(get_path_geom(source, destination)); --returns a geometry which is the shortest path between source and destination
      
    end get_path;
    ; and I think thatI have to use autonomous transaction in the internal function, so that the external function can see any changes made by the inside one. However, it doesn't work, when I call twice the function internal (i.e. remove the comment panels in front of the last two lines of code just before the return statement in the outer function.)

    So here are my questions: 1) why should I call the function twice to see the complete transaction? (and 2.) How can I avoid this? Is it possible to wait for the execution of the return statement in the internal function that the insert is committed and can be seen by the external function?

    See you soon!

    OK, here's the solution: the external function get_path() calls a function get_path_geom(source, destination) , who himself called something like table(dijkstra(source, destination)) , (omitted by me because only carefully tested and ok, my bad!) which makes the job of finding the shortest path and returns an array in pipeline. It turns out that this feature for some reason is not the scope of the external function and therefore does not see the transaction committed themselves on the graphics table. After you change the dijkstra() -function to return a list instead of a table, all works all of a sudden.

    If this question has been answered; I would still like to know why the table function does not have the same scope as the rest of the transaction.

    Edit: removed misleading blame on application external and inserted a correct solution.

  • Creation of spatial data connectivity data

    Hello

    I have a few spatial data, which I'll try to describe the relevant aspects:

    -A LineSegment table, which contains information about cables, including the ID of the area (approximately 4 million lines)
    -An array of location, that contains a LineSegmentID (one by one), and a column (space) geometry (approximately 4 million lines).

    What I need to do, is to create a new table containing conceptual "nodes", containing the following columns:

    -NodeID (number)
    -(Number) LineSegmentID
    -LineSegmentEnd (1 or 2)

    So I need to prepare, for each cable, which other cable it connects, by comparing its ends with the endpoints of other cables in the same sector. A box contains cables up to 464. There are a total of 160 thousand areas.

    I'm working on the most effective way to achieve this, ideally by making a batch which will take less than half an hour. Oracle is relatively new to me, but I'm guessing that the right approach would be to use a series of intermediate (intermediate) tables, as I believe nested cursors would be much too slow (I ran a simple test to confirm this).

    I guess I'll have to get in a temporary table, the starting point and the end point of each cable using SDO_LRS. GEOM_SEGMENT_START_PT and SDO_LRS. GEOM_SEGMENT_END_PT, as well as the area ID. Join the table to itself, and then use SDO_GEOM. SDO_DISTANCE to work on what points are close together (for example less than one meter). However, I'm fighting to describe a step by step process.

    Anyone has any ideas that can help?

    (Oracle 11g)

    Examples of data to illustrate the problem:

    create table line_location (lineid number,
    geometry sdo_geometry);
    create table (ID, areaid) line;

    -a cable in the box 1, 2 in area 4, etc.
    insert into a values (1, 1) line;
    insert into values of line (2, 4);
    insert into values of line (3, 4);
    insert into a values (4, 3) line;
    insert into values of line (5, 3);
    insert into a values (6, 3) line;
    insert into values of line (7, 2);
    insert into values of line (8: 2);
    insert into a values (9, 2) line;
    insert into values of line (10, 2);

    -in reality, the lines are not necessarily straight and simple as these...
    insert into line_location values (1, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (10,1,10,4))); -zone 1
    insert into line_location values (2, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (3,9,5,9))); -zone 4
    insert into line_location values (3, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (5,9,5,10))); -zone 4
    insert into line_location values (4, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (1,1,2,1))); -zone 3
    insert into line_location values (5, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (2,3,2,1))); -zone 3
    insert into line_location values (6, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (2,3,3,3))); -zone 3
    insert into line_location values (7, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (5,3,5,4))); -zone 2
    insert into line_location values (8, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (4,4,5,4))); -zone 2
    insert into line_location values (9, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (5,9,6,4))); -zone 2
    insert into line_location values (10, MDSYS. SDO_GEOMETRY (2002,3785, NULL, MDSYS. SDO_ELEM_INFO_ARRAY (1,2,1), MDSYS. SDO_ORDINATE_ARRAY (5,7,5,9))); -zone 2

    create table node_line (node_id number,
    line_id number,
    endpoint_id number,--1 for starting point, 2 for the end point.
    area_id number
    );

    -expected here. If two lines are less than 0.5, whereas they should share a node.
    insert into node_line values (1, 1, 1, 1); -insulated cable in zone 1, starting point node
    insert into node_line values (2, 1, 2, 1); -insulated cable in zone 1, point endpoint node
    insert into node_line values (3, 2, 1, 4); -zone 4: 2, node starting point of cable
    insert into node_line values (4, 2, 2, 4); -zone 4, cable 2, point endpoint node
    insert into node_line values (4, 3, 1, 4); -point 2 = cable endpoint node cable 3 start knot, etc.
    insert into node_line values (5, 3, 2, 4);
    insert into node_line values (6, 4, 1, 3); -node at (1,1)
    insert into node_line values (7, 4, 2, 3); -node to (2.1)
    insert into node_line (8, 5, 1, 3) values; -node to (2,3)
    insert into node_line values (7, 5, 2, 3); -node to (2.1)
    insert into node_line (8, 6, 1, 3) values; -node to (2,3)
    insert into node_line values (9, 6, 2, 3); -(3.3) node
    insert into node_line values (10, 7, 1, 2); -node to (5.3)
    insert into node_line values (11, 7, 2, 2); -node to (5.4)
    insert into node_line (12, 7, 1, 2) values; -node to (4.4)
    insert into node_line values (11, 7, 2, 2); -node to (5.4)
    insert into node_line (13, 7, 1, 2) values; -node to (5.9)
    insert into node_line (14, 7, 2, 2) values; -node (6.4)
    insert into node_line values (15, 7, 1, 2); -node to (5,7)
    insert into node_line (13, 7, 2, 2) values; -node to (5.9)

    Thank you

    Hi Ronnie

    Have you had a look at the script on the old NET?
    This done in a slightly different result structure, what you're after.
    I took the time this morning to see a bit optimized.

    Below you will find the result.

    With clues about a couple and the use of the SDO_JOIN rather the sdo_relate this speeds up considerably.
    I had tested on a 600 k line objects (which is not 4 million I know) and is reasonable ok on my test (non optimized) environment.

    On the "1 metre" close to each other, I would have supported itself by setting the tolerance appropriately, so
    There should be no reason to perform within the distance checking. Obviously that permitting the resolution of your data.

    Have a look at.

    Note that the final table is different in their structure, but this needs to be easily adjusted in the script if your node_line table must be exactly like you defined.

    Luke

    -drop the existing SEQ_TOPO

    sequence of fall SEQ_TOPO;

    -create sequences with caching

    CREATE SEQ_TOPO CACHE 2000 SEQUENCES;

    commit;

    -drop temporary table

    drop table temp_nodes cascade constraints;

    -create temporary table and fill it with startponts and a field saying this are implemented, as X, Y, as we use it later to remove duplicates in a nonspatial way

    create the table temp_nodes

    as

    Select a.lineid, a.areaid, sdo_geometry (2001, a.node.sdo_srid, SDO_POINT (t.X, t.Y, null), null, null) as a node, SEQ_TOPO.nextval node_id, the from ' AS STEND, t.x, t.y

    Of

    (select lineid, areaid, node sdo_lrs.geom_segment_start_pt (geometry) of line_location, where the LINE line_location.lineid = line.line_id), TABLE (SDO_UTIL. GETVERTICES (a.Node)) t;

    commit;

    -Insert the end points in the temporary table

    insert into temp_nodes

    Select a.lineid, a.areaid, sdo_geometry (2001, a.node.sdo_srid, SDO_POINT (t.X, t.Y, null), null, null) as a node, SEQ_TOPO.nextval node_id, 'E' AS STEND, t.x, t.y

    Of

    (select lineid, areaid, node sdo_lrs.geom_segment_end_pt (geometry) of line_location, where the LINE line_location.lineid = line.line_id), TABLE (SDO_UTIL. GETVERTICES (a.Node)) t;

    commit;

    -insert user_sdo_geom_metadata and have created for temp_nodes index

    -adjust with appropriate metadata to srid, high and lowebounds values and the tolerance of your dataset

    -Here the tolerance is set at 1 meter, this way there is no need to use a distance, let tolerance help us here

    -Obviously this can work if tolerance is smaller, then the distance between the start and end of the link itself.

    delete from user_sdo_geom_metadata where table_name = 'TEMP_NODES ';

    INSERT INTO user_sdo_geom_metadata VALUES ("TEMP_NODES", "NODE", SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X', 0, 1000000, 1), SDO_DIM_ELEMENT ('Y', 0, 100000, 1)), 3785);

    -create spatial indexes with gtype = POINT to use internal optimization

    Drop index node_sx;

    CREATE INDEX node_sx ON temp_nodes (node) INDEXTYPE IS MDSYS. SPATIAL_INDEX PARAMETERS ('sdo_indx_dims = 2, layer_gtype = POINT');

    -create indexes on X, Y combination to accelerate "eliminating duplicates" (in the group by) is actually a "select unique" rather that remove duplicates

    CREATE INDEX INDEX1 ON TEMP_NODES (X, Y);

    CREATE the INDEX INDEX2 ON TEMP_NODES (node_id);

    -create the final node table with unique nodes of the temporary table, x, to y could be omitted

    create the table node_topo

    as

    Select a.nodeid, t.node, t.x, t.y

    Of

    (

    Select min (node_id) as nodeid

    Of

    temp_nodes

    Group x, Y

    ) an inner join

    temp_nodes t

    on (a.nodeid = t.node_id)

    ;

    commit;

    -insertion of metadata information

    delete from user_sdo_geom_metadata where table_name = 'NODE_TOPO ';

    INSERT INTO user_sdo_geom_metadata VALUES ("NODE_TOPO", "NODE", SDO_DIM_ARRAY (SDO_DIM_ELEMENT ('X', 0, 1000000, 1), SDO_DIM_ELEMENT ('Y', 0, 100000, 1)), 3785);

    -create spatial indexes on the table to end node with gtype = POINT (internal optimization)

    Drop index node_topo_sx;

    CREATE INDEX node_topo_sx ON NODE_TOPO (node) INDEXTYPE IS MDSYS. SPATIAL_INDEX PARAMETERS ('sdo_indx_dims = 2, layer_gtype = POINT');

    -create table node_link using SDO_JOIN between end node final tables and temp

    -the NAYINTERACT should take care of the "alignment" as the tolerance will be applied

    create the table node_line

    as

    Select lineid, max (st_ID) START_NODE_ID, max (en_ID) END_NODE_ID, max (areaid) AREAID

    Of

    (

    SELECT b.lineid, case when b.stend = s ' THEN a.nodeid 0 otherwise end st_ID,.

    cases where b.stend = 'E' THEN a.nodeid 0 otherwise end en_ID, areaid

    TABLE (SDO_JOIN ('NODE_TOPO', 'NODE',

    "TEMP_NODES", "NODE",

    "(masque = ANYINTERACT')) c,"

    node_topo has,

    temp_nodes b

    WHERE c.rowid1 = a.rowid AND c.rowid2 = b.rowid

    )

    Lineid group;

    commit;

    -items temp

    drop table temp_nodes cascade constraints;

    delete from user_sdo_geom_metadata where table_name = 'TEMP_NODES ';

    commit;

    seq_topo sequence of fall;

    commit;

  • shortest distance

    Hi, I have a table of geometry of point, to select the intermediate points which gives the shortest between two predefined points (point 1 and point 2) using sdo_geom.sdo_distance.

    ID X Y
    point 1: 6143 - 87.910994 41.982889
    point 2: 6048 - 87.907813 41.982816

    intermediate points:

    point 3: 5991 - 87.909845 41.9828835
    point 4: 5994 - 87.908649 41.98287
    point 5: 5993 - 87.908798 41.9826835
    point 6: 6033 - 87.908493 41.9825935

    any suggestions?
    Thank you

    If you want to find 3 points, you must use 3 loops FOR and concat 3 indexes for the ROAD:

    SET SERVEROUTPUT ON SIZE 900000;
    
    DECLARE
      TYPE points IS TABLE OF sdo_geometry;
    
      ipoints points :=  points();
      apoint sdo_geometry := sdo_geometry(2001, 8307, sdo_point_type(-87.910994, 41.982889 , 0), NULL , NULL);
      epoint sdo_geometry := sdo_geometry(2001, 8307, sdo_point_type(-87.907813, 41.982816 , 0), NULL, NULL);   
    
      dist   NUMBER := 0;
      sumd   NUMBER := 9999999;
    
      route  VARCHAR2(200) := '';
    
    BEGIN
    
      --initialize
      ipoints.extend(3);
      ipoints(1) := sdo_geometry(2001, 8307,sdo_point_type( -87.905464, 41.967392, 0), NULL, NULL);
      ipoints(2) := sdo_geometry(2001, 8307,sdo_point_type( -87.904189, 41.967377, 0), NULL, NULL);
      ipoints(3) := sdo_geometry(2001, 8307,sdo_point_type( -87.901859, 41.9673795,0), NULL, NULL);
    
      --brute force
      FOR i IN 1..3 LOOP
        FOR j IN 1..3 LOOP
          FOR k IN 1..3 LOOP
              --dont use same point twice !
              IF (i=j OR i=k OR j=k) THEN CONTINUE;END IF;
              dist  := sdo_geom.sdo_distance(apoint    ,ipoints(i),1) +
                       sdo_geom.sdo_distance(ipoints(i),ipoints(j),1) +
                       sdo_geom.sdo_distance(ipoints(j),    epoint,1);
              --get the actual route
              IF sumd>dist THEN
                sumd  := dist;
                route := to_char(i)||to_char(j)||to_char(k);
              END IF;
          END LOOP;
        END LOOP;
      END LOOP;
    
      --length of shortest path
      dbms_output.put_line ('route='||route);
      dbms_output.put_line (sumd);
    END;
    
    route=123
    3627,935355905372
    

    The brute force method (in this very simple case) needs more iterations for each intermediate point (n * n), so it cannot be used for a large number of points.
    In this thread there are links and advice for other methods in these cases.

    POINTS ITERATIONS
    ----------------------------
    1            1
    2            4
    3           27
    4          265
    5         3125
    6        46656
    ...
    10 10000000000
    

    BTW. You should use markup bat, to format your code and the intention of the lines, you see the difference, not you?

  • SDO_FILTER which gives weird results

    Hi people,

    Not sure if this is a bug or maybe I'm just not see something simple. On 11.2.0.4. I have an area of the area of interest and a line next door representing a piece of water, the two geometries validate the tolerance of 5 centimeters.
    http://www.dziemiela.com/june27.PNG
    The box is more than a mile away from the stream. The flow is relatively small and its MBR is no where close to touch the area. However, according to SDO_FILTER, two geometries are TRUE. I'm puzzled. So I wrote the mess for anyone wishing to give it a shot. I'll be back

    Streamy is valid? TRUE
    Véronique is valid? TRUE
    Basic SDO_GEOM. RELATE? DISJOINT
    Distance between 1795.19857225394 M
    MIL SDO_GEOM. RELATE? DISJOINT
    Distance between 1794.97512096382 M
    SDO_RELATE County 0
    SDO_FILTER County 1

    If two geometries are distance of 1.7 km and their members are distance of 1.7 km. I would like to say very clearly that these things shouldn't interact. Right? However, filter gives TRUE. Am I a something Klutz?

    Thank you
    Paul
    DECLARE
       sdo_streamy SDO_GEOMETRY := SDO_GEOMETRY(2002,8265,NULL,SDO_ELEM_INFO_ARRAY(1,2,1),SDO_ORDINATE_ARRAY(-77.6495001234516,38.9423350727726,-77.6482987901201,38.9418092727734,-77.6468049234557,38.9413522727742,-77.6461311901235,38.9413982061074,-77.6438177901271,38.942107872773,-77.6427925901286,38.9423368727726,-77.6423533234627,38.9422912727727,-77.6410643234647,38.9417884061068,-77.6406835234653,38.9416968727736,-77.6403321234658,38.9417886061068,-77.6394825901338,38.9417886727735,-77.63760792347,38.9414232061074,-77.6370221234709,38.9410114727747,-77.6357033901397,38.9392504727774,-77.6352933234736,38.9389760727778,-77.6347071901412,38.9380154727793,-77.6313675901464,38.9348822727842,-77.6301375234816,38.9342876061185,-77.6295517234825,38.9336930061194,-77.6294929901493,38.9335098727863));
       sdo_boxy SDO_GEOMETRY := SDO_GEOMETRY(2003,8265,NULL,SDO_ELEM_INFO_ARRAY(1,1003,1),SDO_ORDINATE_ARRAY(-77.6087382736728,38.9295533233688,-77.4229814409148,38.9295533233688,-77.4229814409148,39.0744969598833,-77.6087382736728,39.0744969598833,-77.6087382736728,38.9295533233688));
       num_result NUMBER;
    BEGIN
       dbms_output.put_line('Streamy is valid? ' || SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(sdo_streamy,0.05));
       dbms_output.put_line('Boxy is valid? ' || SDO_GEOM.VALIDATE_GEOMETRY_WITH_CONTEXT(sdo_boxy,0.05));
       dbms_output.put_line('Basic SDO_GEOM.RELATE? ' || SDO_GEOM.RELATE(sdo_streamy,'DETERMINE',sdo_boxy,0.05));
       dbms_output.put_line('Distance Between ' || SDO_GEOM.SDO_DISTANCE(sdo_streamy,sdo_boxy,0.05) || 'M');
       dbms_output.put_line('MBRs SDO_GEOM.RELATE? ' || SDO_GEOM.RELATE(SDO_GEOM.SDO_MBR(sdo_streamy),'DETERMINE',SDO_GEOM.SDO_MBR(sdo_boxy),0.05));
       dbms_output.put_line('Distance Between ' || SDO_GEOM.SDO_DISTANCE(SDO_GEOM.SDO_MBR(sdo_streamy),SDO_GEOM.SDO_MBR(sdo_boxy),0.05) || 'M');
       EXECUTE IMMEDIATE 'CREATE TABLE streamy (shape SDO_GEOMETRY)';
       EXECUTE IMMEDIATE 'INSERT INTO streamy (shape) VALUES (:p01)' USING sdo_streamy; COMMIT;
       INSERT INTO user_sdo_geom_metadata(table_name,column_name,diminfo,srid) VALUES 
       ('STREAMY','SHAPE',MDSYS.SDO_DIM_ARRAY(MDSYS.SDO_DIM_ELEMENT('X',-180,180,.05),MDSYS.SDO_DIM_ELEMENT('Y',-90,90,.05)),8265); COMMIT;
       EXECUTE IMMEDIATE 'CREATE INDEX streamy_spx ON streamy(shape) INDEXTYPE IS MDSYS.SPATIAL_INDEX';
       EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM streamy a WHERE SDO_RELATE(a.shape,:p01,''MASK=ANYINTERACT'')=''TRUE''' INTO num_result USING sdo_boxy;
       dbms_output.put_line('SDO_RELATE Count ' || TO_CHAR(num_result));
       EXECUTE IMMEDIATE 'SELECT COUNT(*) FROM streamy a WHERE SDO_FILTER(a.shape,:p01)=''TRUE''' INTO num_result USING sdo_boxy;
       dbms_output.put_line('SDO_FILTER Count ' || TO_CHAR(num_result));
    END;
    /

    Hi Paul,.

    For geodetic geometry, R-tree index are in 3D. For example, you can see:

    SQL> select sdo_index_name, SDO_ROOT_MBR from user_sdo_index_metadata;
    
    SDO_INDEX_NAME
    --------------------------------
    SDO_ROOT_MBR(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINAT
    --------------------------------------------------------------------------------
    STREAMY_SPX
    SDO_GEOMETRY(3008, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 1007, 3), SDO_ORDINATE_ARR
    AY(.16636, -.759816, .628418, .166646, -.759754, .628538))
    

    sdo_boxy is converted to:
    SDO_GEOMETRY (3008, NULL, NULL, SDO_ELEM_INFO_ARRAY (1, 1007, 3), SDO_ORDINATE_ARR)
    AY (. 166589,-. 759798,.628364,.169393,-. 757698,.630331))

    If the two MBR or minimum limit boxes (MBBs) intersect.

    Thank you
    Ying

  • How to create a polygon that covers a set of geometries?

    Hi people,

    I have a spatial table with the parcel data. Some are polygons and lines.
    What I have to do is to create a single polygon that covers all these plots.
    I tried some spatial functions, but the result is not perfect.
    Could you guys give some advice on how to do it using the Oracle Spatial functions?

    Thank you
    Luis

    Luis etc.,

    Delicate using the ST_PolygonBuilder (JTS) that implements my code SC4O Java-in-the-database and some coding, I managed to product a polygon that covers the data correctly.

    Note that I use only external linestrings which provides some Luis.

    -- First create a table holding only the outer lines.
    --
    create table outerLines as
      SELECT SDO_GEOMETRY(2002, 8292, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(-49.6878936628642, -18.4995538840232, -49.6875224063873, -18.4994400734344, -49.6882811644211, -18.4960292763006, -49.6886251490431, -18.4958803030445, -49.6906307026931, -18.4950115281619)) as geom from dual union all
      SELECT SDO_GEOMETRY(2002, 8292, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(-49.6884083531774, -18.4917625230274, -49.6886528151554, -18.4922451253898, -49.6898503241639, -18.4946091658756, -49.690098431643, -18.4950991112698, -49.6902068702432, -18.4950498009285, -49.6905958643821, -18.4948724904445)) as geom from dual union all
      SELECT SDO_GEOMETRY(2002, 8292, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(-49.6883413960309, -18.4918992292229, -49.6885491287687, -18.4923048595269, -49.6849860033691, -18.4934740072225, -49.6855427926656, -18.4945793006294, -49.6857982402423, -18.4950861997106, -49.6860079716291, -18.4955025995491, -49.6836133980005, -18.4962994912622, -49.6834396716227, -18.4957578264012)) as geom from dual union all
      SELECT SDO_GEOMETRY(2002, 8292, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(-49.6792385551751, -18.5000418095053, -49.6797119992317, -18.4998345697814, -49.6783397446724, -18.4980535328215, -49.6810365599698, -18.4971609552001, -49.6810385833744, -18.4971564511947, -49.6835051531636, -18.4963355157698, -49.6833312619652, -18.4958030666281)) as geom from dual union all
      SELECT SDO_GEOMETRY(2002, 8292, NULL, SDO_ELEM_INFO_ARRAY(1,2,1), SDO_ORDINATE_ARRAY(-49.6878678853177, -18.4996181336176, -49.6861731626715, -18.4991017919552, -49.6834080082784, -18.4982775371379, -49.6833583465082, -18.4983066497055, -49.6832975737928, -18.4983520405102, -49.6831594052426, -18.4984987309426, -49.6830586383606, -18.4986094463067, -49.6829994956301, -18.4986769870823, -49.6829194669485, -18.4987385992949, -49.6828337343539, -18.4987905933782, -49.6827167582476, -18.4988411048671, -49.6825978712605, -18.4988566328165, -49.6824876108137, -18.4988587567866, -49.6824343436196, -18.4988638980162, -49.6823495710101, -18.498901802054, -49.6820036074112, -18.4990727977958, -49.6815739264209, -18.4993045655044, -49.6815394467332, -18.4993194542279, -49.6815037571481, -18.4993313944568, -49.681467095582, -18.4993402576461, -49.6814297528519, -18.4993459734892, -49.6813920251781, -18.4993484966453, -49.6813542118344, -18.4993478070996, -49.6813166127745, -18.4993439103221, -49.6812795262518, -18.4993368372241, -49.6812432464542, -18.4993266439127, -49.6812080820875, -18.4993134018902, -49.6793284309429, -18.5001537628556)) as geom from dual;
    
    -- Firstly, fill in the gaps between all the outer lines by generating small 2 point linestrings....
    -- This is what the CTE, connected_lines, produces
    --
    with connected_lines as (
    select row_number() over (order by 1) as rid,
           f.geom
      from (select sdo_geometry(2002,8292,null,sdo_elem_info_array(1,2,1),sdo_ordinate_array(sx,sy,ex,ey)) as geom
              from (select distinct sx,sy,ex,ey,dist,
                           min(dist) over (partition by sx,sy) as mdist
                      from (select a.x as sx,a.y as sy,b.x as ex,b.y as ey,
                                   sdo_geom.sdo_distance(sdo_geometry(2001,8292,sdo_point_type(a.x,a.y,null),null,null),
                                                         sdo_geometry(2001,8292,sdo_point_type(b.x,b.y,null),null,null),
                                                         0.005) as dist
                              from (select p.x as x, p.y as y
                                      from outerLines g,
                                           table(geom.getVector(g.geom)) v,
                                           table(geom.getPointSet(v.AsSdoGeometry(8292))) p
                                    group by p.x, p.y
                                    having count(*) = 1
                                   ) a,
                                   (select p.x as x, p.y as y
                                      from outerLines g,
                                           table(geom.getVector(g.geom)) v,
                                           table(geom.getPointSet(v.AsSdoGeometry(8292))) p
                                    group by p.x, p.y
                                    having count(*) = 1
                                   ) b
                              where a.x != b.x and a.y != b.y
                            )
                    )
                    where dist = mdist
            UNION ALL
            select g.geom
              from outerLines g
          ) f
    )
    /* Now ask SC4O's ST_PolygonBuilder to try and create a polygon from the set of lines */
    select sc4o.ST_PolygonBuilder(CAST(COLLECT(f.geom) as mdsys.sdo_geometry_array),8) as polygon
      from ( /* Now, the WITH connected_lines produces 2 copies of each linestring with the coordinates reversed.
                    These have to be removed/de-duped before being passed into the ST_PolygonBuilder */
            select sdo_geometry(2002,8292,null,sdo_elem_info_array(1,2,1),sdo_ordinate_array(sum(x1),sum(y1),sum(x2),sum(y2))) as geom
              from (SELECT rid,
                           case when rid=NVL((lag(rid,1) over (partition by rid order by x)),rid)
                                then case when vertexId = 1 then x else null end
                            end as x1,
                           case when rid=NVL((lag(rid,1) over (partition by rid order by x)),rid)
                                then case when vertexId = 1 then y else null end
                            end as y1,
                           case when rid=NVL((lag(rid,1) over (partition by rid order by x)),rid)
                                then case when vertexId = 2 then x else null end
                            end as x2,
                           case when rid=NVL((lag(rid,1) over (partition by rid order by x)),rid)
                                then case when vertexId = 2 then y else null end
                            end as y2
                    FROM   (select rid,
                                   row_number() over (partition by rid order by x) as vertexId,
                                   x, y
                              from (select min(m.rid) rid,
                                           t.x, t.y
                                      from connected_lines m,
                                           table(sdo_util.getVertices(m.geom)) t
                                     where sdo_util.GetNumVertices(m.geom) = 2
                                     group by t.x,t.y
                                     order by t.x )
                           )
                      )
                    group by rid
        union all
        /* Select and pass into ST_PolygonBuilder the original outer lines */
        select m.geom as geom
          from connected_lines m
         where sdo_util.GetNumVertices(m.geom) > 2
        ) f;
    -- Result
    --
    POLYGON
    -----------------------
    MDSYS.SDO_GEOMETRY(2003,8292,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,1003,1),MDSYS.SDO_ORDINATE_ARRAY(-49.6906307026931,-18.4950115281619,-49.6886251490431,-18.4958803030445,-49.6882811644211,-18.4960292763006,-49.6875224063873,-18.4994400734344,-49.6878936628642,-18.4995538840232,-49.6878678853177,-18.4996181336176,-49.6861731626715,-18.4991017919552,-49.6834080082784,-18.4982775371379,-49.6833583465082,-18.4983066497055,-49.6832975737928,-18.4983520405102,-49.6831594052426,-18.4984987309426,-49.6830586383606,-18.4986094463067,-49.6829994956301,-18.4986769870823,-49.6829194669485,-18.4987385992949,-49.6828337343539,-18.4987905933782,-49.6827167582476,-18.4988411048671,-49.6825978712605,-18.4988566328165,-49.6824876108137,-18.4988587567866,-49.6824343436196,-18.4988638980162,-49.6823495710101,-18.498901802054,-49.6820036074112,-18.4990727977958,-49.6815739264209,-18.4993045655044,-49.6815394467332,-18.4993194542279,-49.6815037571481,-18.4993313944568,-49.681467095582,-18.4993402576461,-49.6814297528519,-18.4993459734892,-49.6813920251781,-18.4993484966453,-49.6813542118344,-18.4993478070996,-49.6813166127745,-18.4993439103221,-49.6812795262518,-18.4993368372241,-49.6812432464542,-18.4993266439127,-49.6812080820875,-18.4993134018902,-49.6793284309429,-18.5001537628556,-49.6792385551751,-18.5000418095053,-49.6797119992317,-18.4998345697814,-49.6783397446724,-18.4980535328215,-49.6810365599698,-18.4971609552001,-49.6810385833744,-18.4971564511947,-49.6835051531636,-18.4963355157698,-49.6833312619652,-18.4958030666281,-49.6834396716227,-18.4957578264012,-49.6836133980005,-18.4962994912622,-49.6860079716291,-18.4955025995491,-49.6857982402423,-18.4950861997106,-49.6855427926656,-18.4945793006294,-49.6849860033691,-18.4934740072225,-49.6885491287687,-18.4923048595269,-49.6883413960309,-18.4918992292229,-49.6884083531774,-18.4917625230274,-49.6886528151554,-18.4922451253898,-49.6898503241639,-18.4946091658756,-49.690098431643,-18.4950991112698,-49.6902068702432,-18.4950498009285,-49.6905958643821,-18.4948724904445,-49.6906307026931,-18.4950115281619))
    

    The result is a nice clean polygon.

    http://www.spatialdbadvisor.com/files/PolygonCoveringGeometrySet.PNG

    This, more than my last post is the best I can do. It took me many, many hours to implement. Please allow points since it is a correct result. Also, consider making a PayPal donation on my Web site for the hours I spent.

    NOTE: The package space companion 4 Oracle (SC4O) is available for download FREE on my site. Again, donations accepted if the code made what you want.

    concerning
    Simon

    Published by: Simon Greener on April 11, 2013 09:53 Changed where a.x, b.x and b.y-a.y etc. to where a.x! = b.x and a.y! b.y =

  • Application for vehicle tracking

    Hello friends,
    I am a beginner in oracle spatial and would be useful in the following cases:

    I have a table of positions of a vehicle with [ID / Lat / Long]
    I would like to extract the distance in meters for this vehicle.
    I need help to create the table and extract this information.

    Thanks to you all.

    q shock,

    My previous post answers the question you asked given the data and the information you provide (not)!
    You will see that my new assignment ends with a nearly identical piece of SQL...

    Your new assignment is much better but I had to do a lot of work to use it.

    If you see how I built the answer, you will see how much more easy, faster
    and the most convenient for yourself and all of the people involved, it would be if you provided data in the form
    I reformatted your in (note the issue of internationalization with the, in the field of lat/long).

    -- Construct table given what we know about its structure from the data
    --
    create table veiculo_obs (
      veiculo  number(10),
      datahora date,
      geom     sdo_geometry
    );
    
    -- Now let's add in the forum member's data
    --
    insert all
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:02:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0505555555556,-19.9616666666667,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:04:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0616666666667,-19.9561111111111,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:06:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0633333333333,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:08:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0638888888889,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:10:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0641666666667,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:16:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0641666666667,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:18:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0638888888889,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:19:13','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0641666666667,-19.95,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:22:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0625,-19.9519444444444,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:24:15','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0625,-19.9519444444444,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:24:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0630555555556,-19.9519444444444,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:26:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0630555555556,-19.9586111111111,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:28:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0652777777778,-19.9580555555556,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:30:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0488888888889,-19.9630555555556,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:32:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0277777777778,-19.9569444444444,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:34:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0113888888889,-19.9491666666667,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:36:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0077777777778,-19.9475,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:38:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0075,-19.9416666666667,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:40:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0075,-19.9375,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:42:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-44.0063888888889,-19.9280555555556,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:44:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9941666666667,-19.915,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:46:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9825,-19.9008333333333,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:48:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9672222222222,-19.8855555555556,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:50:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9502777777778,-19.8761111111111,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:52:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9338888888889,-19.8672222222222,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:54:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8719444444444,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:56:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9283333333333,-19.8752777777778,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 16:58:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9297222222222,-19.8788888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:00:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.93,-19.8786111111111,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:02:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9291666666667,-19.8777777777778,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:04:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:06:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:08:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9272222222222,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:10:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:12:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9272222222222,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:14:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8816666666667,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:16:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:18:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:20:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:22:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:24:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8816666666667,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:26:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:28:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:30:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:32:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:34:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:36:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    into veiculo_obs (veiculo,datahora,geom) values (541870,to_date('23/05/2012 17:38:44','DD/MM/YYYY HH24:MI:SS'),SDO_GEOMETRY(2001,8307,SDO_POINT_TYPE(-43.9275,-19.8813888888889,NULL),NULL,NULL))
    select * from dual;
    commit;
    
    -- Here is my solution
    --
    select b.veiculo,
           to_char(b.datahora,'DD/MM/YYYY HH24:MI:SS') as start_datahora,
           to_char(c.datahora,'DD/MM/YYYY HH24:MI:SS') as end_datahora,
           round(sdo_geom.sdo_distance(b.geom,c.geom,0.005,'unit=M'),2) as dist,
           round(sum(sdo_geom.sdo_distance(b.geom,c.geom,0.005,'unit=M')) over (partition by c.veiculo order by c.datahora),2) as cdist
      from (select a.veiculo,
                   a.datahora,
                   lead(a.datahora,1) over (partition by a.veiculo order by a.datahora) as datahora2,
                   a.geom
              from veiculo_obs a
           ) b,
           veiculo_obs c
     where b.datahora2 is not null
       and c.veiculo  = b.veiculo
       and c.datahora = b.datahora2;
    
    -- Results
    --
    VEICULO START_DATAHORA      END_DATAHORA        DIST    CDIST
    ------- ------------------- ------------------- ------- -------
    541870  23/05/2012 16:02:44 23/05/2012 16:04:44 1315.65 1315.65
    541870  23/05/2012 16:04:44 23/05/2012 16:06:44 698.66  2014.3
    541870  23/05/2012 16:06:44 23/05/2012 16:08:44 58.16   2072.46
    541870  23/05/2012 16:08:44 23/05/2012 16:10:44 29.08   2101.54
    541870  23/05/2012 16:10:44 23/05/2012 16:16:44 0       2101.54
    541870  23/05/2012 16:16:44 23/05/2012 16:18:44 29.08   2130.62
    541870  23/05/2012 16:18:44 23/05/2012 16:19:13 29.08   2159.69
    541870  23/05/2012 16:19:13 23/05/2012 16:22:44 277.08  2436.77
    541870  23/05/2012 16:22:44 23/05/2012 16:24:15 0       2436.77
    541870  23/05/2012 16:24:15 23/05/2012 16:24:44 58.15   2494.93
    541870  23/05/2012 16:24:44 23/05/2012 16:26:44 738.02  3232.95
    541870  23/05/2012 16:26:44 23/05/2012 16:28:44 240.6   3473.56
    541870  23/05/2012 16:28:44 23/05/2012 16:30:44 1802.57 5276.12
    541870  23/05/2012 16:30:44 23/05/2012 16:32:44 2311.01 7587.14
    541870  23/05/2012 16:32:44 23/05/2012 16:34:44 1919.51 9506.64
    541870  23/05/2012 16:34:44 23/05/2012 16:36:44 420.64  9927.28
    541870  23/05/2012 16:36:44 23/05/2012 16:38:44 646.43  10573.71
    541870  23/05/2012 16:38:44 23/05/2012 16:40:44 461.26  11034.97
    541870  23/05/2012 16:40:44 23/05/2012 16:42:44 1051.98 12086.96
    541870  23/05/2012 16:42:44 23/05/2012 16:44:44 1930.38 14017.34
    541870  23/05/2012 16:44:44 23/05/2012 16:46:44 1987.92 16005.26
    541870  23/05/2012 16:46:44 23/05/2012 16:48:44 2328.09 18333.35
    541870  23/05/2012 16:48:44 23/05/2012 16:50:44 2059.62 20392.97
    541870  23/05/2012 16:50:44 23/05/2012 16:52:44 1978.5  22371.47
    541870  23/05/2012 16:52:44 23/05/2012 16:54:44 849.12  23220.6
    541870  23/05/2012 16:54:44 23/05/2012 16:56:44 379.19  23599.78
    541870  23/05/2012 16:56:44 23/05/2012 16:58:44 425.4   24025.18
    541870  23/05/2012 16:58:44 23/05/2012 17:00:44 42.33   24067.52
    541870  23/05/2012 17:00:44 23/05/2012 17:02:44 126.99  24194.51
    541870  23/05/2012 17:02:44 23/05/2012 17:04:44 436.2   24630.71
    541870  23/05/2012 17:04:44 23/05/2012 17:06:44 0       24630.71
    541870  23/05/2012 17:06:44 23/05/2012 17:08:44 29.09   24659.8
    541870  23/05/2012 17:08:44 23/05/2012 17:10:44 29.09   24688.89
    541870  23/05/2012 17:10:44 23/05/2012 17:12:44 29.09   24717.98
    541870  23/05/2012 17:12:44 23/05/2012 17:14:44 42.33   24760.31
    541870  23/05/2012 17:14:44 23/05/2012 17:16:44 30.75   24791.06
    541870  23/05/2012 17:16:44 23/05/2012 17:18:44 0       24791.06
    541870  23/05/2012 17:18:44 23/05/2012 17:20:44 0       24791.06
    541870  23/05/2012 17:20:44 23/05/2012 17:22:44 0       24791.06
    541870  23/05/2012 17:22:44 23/05/2012 17:24:44 30.75   24821.81
    541870  23/05/2012 17:24:44 23/05/2012 17:26:44 30.75   24852.57
    541870  23/05/2012 17:26:44 23/05/2012 17:28:44 0       24852.57
    541870  23/05/2012 17:28:44 23/05/2012 17:30:44 0       24852.57
    541870  23/05/2012 17:30:44 23/05/2012 17:32:44 0       24852.57
    541870  23/05/2012 17:32:44 23/05/2012 17:34:44 0       24852.57
    541870  23/05/2012 17:34:44 23/05/2012 17:36:44 0       24852.57
    541870  23/05/2012 17:36:44 23/05/2012 17:38:44 0       24852.57               
    
     47 rows selected 
    

    Note 1: cdist is the DISTANCE EARNED
    Note 2: You have several observations at the same point but different time (vehicle stopped?)

    It looks like a solution/answer for me! Shows please.

    concerning
    Simon

Maybe you are looking for

  • 4-1030 ca: form WBSOD

    Hi, new to the forum. Girls like has been stopped during the update of the VICTORY, now gets a blue screen of death. Unavailable recovery disks (purchase of 2012) Have the new HARD drive, would clean install WIN7 Home Premium Bootable USB with the im

  • Fuze 4 GB - or - Fuze 2 GB and 4 GB sdhc

    Ready to pull the trigger on a rocket for my wife.  For you, the experienced users of rocket, would you buy a: 1 fuze 4 GB ($55.50) 2 fuze 2 GB ($42,95) more a Transcend 4 GB class 6 card microSD with adapter ($10.99) = $53.94 Choice-2 ends with 6 GB

  • Reinstall from Vista 32 bit to 64 bit Vista: problem CD available without CD keys

    Recently, I sent my laptop to change its hard drive. Then of course the current operating system on my laptop (Vista Home premium 64) must be reinstalled. However, the technician only reinstalled a 32-bit Home Premium for me. It is therefore possible

  • «Error 809» big fish games

    How? I'm on the games big fish and I can't play anything until I close a game that is 'currently' open and I het a ' error 809 "I tried ctrl/alt/del; nothing, then, how can I find the game that is 'open' to close and play another one?

  • BlackBerry smartphones HELP! Green bubble with icon and star

    My blackberry recently ran batterery and when I got round to load once again, he had an icon that looks like a green bubble with a white phone inside and a red star and a number 1 next to it. I guess it was a voice message, but my voicemail box is em