Actually, the following returns a wrong result:
SQL> select sdo_util.from_wktgeometry('MULTILINESTRING (( 0.0 5.0 -100000.0, 10.0 10.0 -100000.0, 30.0 0.0 -100000.0),( 50.0 10.0 -100000.0, 60.0 10.0 -100000.0))') from dual;
SDO_UTIL.FROM_WKTGEOMETRY('MULTILINESTRING((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))')(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORD
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(3006, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1, 10, 2, 1), SDO_ORDINATE_ARRAY(0, 5, -100000, 10, 10, -100000, 30, 0, -100000, 50, 10, -100000, 60, 10, -100000))
1 row selected.
Notice that the GTYPE is 3006, i.e. a 3D multiline, i.e. the measures are now interpreted as Z values. It is not a LRS segment.
And the rejection of MULTILINESTRING M
is because the WKT parser used by Oracle does not know about this notation.
For now, you can use a function like this:
create or replace function set_lrs (geom sdo_geometry)
return sdo_geometry
is
lrs_geom sdo_geometry;
begin
lrs_geom := geom;
lrs_geom.sdo_gtype := lrs_geom.sdo_gtype + 300;
return lrs_geom;
end;
/
That function sets the second digit of the GTYPE to 3, indicating that the third dimension is a measure instead of a z value:
SQL> select set_lrs(sdo_util.from_wktgeometry('MULTILINESTRING (( 0.0 5.0 -100000.0, 10.0 10.0 -100000.0, 30.0 0.0 -100000.0),( 50.0 10.0 -100000.0, 60.0 10.0 -100000.0))')) from dual;
SET_LRS(SDO_UTIL.FROM_WKTGEOMETRY('MULTILINESTRING((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))'))(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(3306, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1, 10, 2, 1), SDO_ORDINATE_ARRAY(0, 5, -100000, 10, 10, -100000, 30, 0, -100000, 50, 10, -100000, 60, 10, -100000))
1 row selected.
or simpler:
SQL> select set_lrs(sdo_geometry('MULTILINESTRING (( 0.0 5.0 -100000.0, 10.0 10.0 -100000.0, 30.0 0.0 -100000.0),( 50.0 10.0 -100000.0, 60.0 10.0 -100000.0))')) from dual;
SET_LRS(SDO_GEOMETRY('MULTILINESTRING((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))'))(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINAT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(3306, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1, 10, 2, 1), SDO_ORDINATE_ARRAY(0, 5, -100000, 10, 10, -100000, 30, 0, -100000, 50, 10, -100000, 60, 10, -100000))
1 row selected.
Now the GTYPE is 3306 indicating that we have a valid LRS segment.
EDIT I realize I did not do anything about the extra M
not recognized by Oracle. This can be eliminated with a simple SQL replace()
function:
SQL> select replace('MULTILINESTRING M ((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))','LINESTRING M','LINESTRING') from dual;
REPLACE('MULTILINESTRINGM((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))','LINESTRINGM','LINESTRING')
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
MULTILINESTRING ((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))
1 row selected.
And the complete operation would be like this:
select set_lrs(sdo_geometry(replace(wkt_geom,'LINESTRING M','LINESTRING')))from dual;
Or better, let's use a simple function that makes it simpler:
create or replace function from_lrs_wkt (wkt_geom clob)
return sdo_geometry
is
lrs_geom sdo_geometry;
begin
lrs_geom := sdo_geometry(replace(upper(wkt_geom),'LINESTRING M','LINESTRING'));
lrs_geom.sdo_gtype := lrs_geom.sdo_gtype + 300;
return lrs_geom;
end;
/
And an example:
SQL> select from_lrs_wkt('MULTILINESTRING M ((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))') from dual;
FROM_LRS_WKT('MULTILINESTRINGM((0.05.0-100000.0,10.010.0-100000.0,30.00.0-100000.0),(50.010.0-100000.0,60.010.0-100000.0))')(SDO_GTYPE, SDO_SRID, SDO_POINT(X, Y, Z), SDO_ELEM_INFO, SDO_ORDINATES)
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SDO_GEOMETRY(3306, NULL, NULL, SDO_ELEM_INFO_ARRAY(1, 2, 1, 10, 2, 1), SDO_ORDINATE_ARRAY(.05, 0, -100000, 10.01, 0, -100000, 30, 0, -100000, 50.01, 0, -100000, 60.01, 0, -100000))
1 row selected.