Go to content Go to navigation and search

Home

Current Oracle Spatial Blog Articles


Search

Browse

RSS / Atom

Email me

textpattern

Creative Commons License
All Blog Articles, Data Models and Free Source Code by Simon Greener, The SpatialDB Advisor is licensed under a Creative Commons Attribution-ShareAlike 3.0 Unported License.

Free Aggregate Method for Concatenating 2D Lines in Oracle Locator 10g

Sunday June 26 2011 at 15:38

The SDO_AGGR_CONCAT_LINES function in Oracle 10g and above allows for linestrings to be concatenated via GROUP BY SQL clauses.

However, this function is only available for Spatial users on Enterprise Edition of the Oracle database 10g (it can be used on 11g).

Locator users can, however, use the mdsys.sdo_util.concat_lines function to append two linestrings together.

This function can be used as the basis for a custom, license free, aggregation function as the following shows.

-- First we need to create an collection type
--
Create Or Replace Type GeometrySet Is Table Of mdsys.SDO_GEOMETRY;
/
Grant execute on GeometrySet to public;
 
-- Now we create a function that uses that type along with the mdsys.sdo_util.concat_lines function
--
create or replace
Function concatLines(p_lines IN geometrySet) 
  Return mdsys.sdo_geometry 
Is
  v_geometry mdsys.sdo_geometry;
Begin
  IF ( p_lines is null ) THEN
      Return NULL;
  END IF;
  IF ( p_lines.COUNT = 1 ) THEN
      Return p_lines(1);
  Else
    v_geometry := p_lines(1);
    FOR i IN (p_lines.FIRST+1) .. p_lines.LAST LOOP
      v_geometry := mdsys.sdo_util.concat_lines(v_geometry,p_lines(i));
    END LOOP;
    Return v_geometry;
  End If;
End concatLines;
/
SHOW ERRORS
 
Grant execute on concatLines to public;

Now, let’s test our function….

select id, concatLines(CAST(COLLECT(a.GEOM) as geometrySet)) as aggregatedLines
  from (select 1 as id, MDSYS.SDO_GEOMETRY(2002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(127.8819,-39.9566,143.774,-39.1098)) as geom from dual
        union all 
        select 1 as id, MDSYS.SDO_GEOMETRY(2002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(143.774,-39.1098,128.8819,-38.9566)) as geom from dual
        union all
        select 2 as id, MDSYS.SDO_GEOMETRY(2002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(27.8819,-3.9566,28.774,-3.1098)) as geom from dual
        union all 
        select 2 as id, MDSYS.SDO_GEOMETRY(2002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(28.774,-3.1098,27.8819,-3.9566)) as geom from dual
        ) a
group by id;
 
-- mdsys.sdo_util.concat_lines doesn't support 3D linestrings. These must be degrated to 2D linestrings to use this function
--
ID AGGREGATEDLINES
-- -----------------------------------------------------------------------------------------------------------------------------------------------------------
1  MDSYS.SDO_GEOMETRY(2002, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1), MDSYS.SDO_ORDINATE_ARRAY(127.8819, -39.9566, 143.774, -39.1098, 128.8819, -38.9566))
2  MDSYS.SDO_GEOMETRY(2002, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1), MDSYS.SDO_ORDINATE_ARRAY(27.8819, -3.9566, 28.774, -3.1098, 27.8819, -3.9566))
 
 
select id, concatLines(CAST(COLLECT(geom.to_2d(a.GEOM)) as geometrySet)) as aggregatedLines
  from (select 1 as id, MDSYS.SDO_GEOMETRY(3002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(127.8819,-39.9566,1,143.774,-39.1098,2)) as geom from dual
        union all 
        select 1 as id, MDSYS.SDO_GEOMETRY(3002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(143.774,-39.1098,3,128.8819,-38.9566,4)) as geom from dual
        union all
        select 2 as id, MDSYS.SDO_GEOMETRY(3002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(27.8819,-3.9566,5,28.774,-3.1098,6)) as geom from dual
        union all 
        select 2 as id, MDSYS.SDO_GEOMETRY(3002,4326,NULL,MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1),MDSYS.SDO_ORDINATE_ARRAY(28.774,-3.1098,7,27.8819,-3.9566,8)) as geom from dual
        ) a
group by id;
 
ID AGGREGATEDLINES
-- -----------------------------------------------------------------------------------------------------------------------------------------------------------
1  MDSYS.SDO_GEOMETRY(2002, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1), MDSYS.SDO_ORDINATE_ARRAY(127.8819, -39.9566, 143.774, -39.1098, 128.8819, -38.9566))
2  MDSYS.SDO_GEOMETRY(2002, 4326, NULL, MDSYS.SDO_ELEM_INFO_ARRAY(1,2,1), MDSYS.SDO_ORDINATE_ARRAY(27.8819, -3.9566, 28.774, -3.1098, 27.8819, -3.9566))

I hope this helps someone.

Creative Commons License

post this at del.icio.uspost this at Diggpost this at Technoratipost this at Redditpost this at Farkpost this at Yahoo! my webpost this at Windows Livepost this at Google Bookmarkspost this to Twitter

Comment