Hello All,
we're using Oracle Spatial 11.2 and I notice a strange behavior when calculating the MBR of a multipart line which crosses the antimeridian.
//fails if multipart line and crosses the antimeridian
select SDO_UTIL.TO_WKTGEOMETRY(
SDO_GEOM.SDO_MBR(
MDSYS.SDO_GEOMETRY('MULTILINESTRING((178 0, 179.99 1), (-179.99 1, -178 2))',8307)
)
) from dual;
//returns POLYGON ((-179.99 0.0, 179.99 0.0, 179.99 2.0, -179.99 2.0, -179.99 0.0)) which is incorrect
//succeeds if simple line and crosses the antimeridian
select SDO_UTIL.TO_WKTGEOMETRY(
SDO_GEOM.SDO_MBR(
MDSYS.SDO_GEOMETRY('LINESTRING(178 0, 179.99 1, -179.99 1, -178 2)',8307)
)
) from dual;
//returns POLYGON ((178.0 0.0, -178.0 0.0, -178.0 2.0, 178.0 2.0, 178.0 0.0)) which is correct
//succeeds if multipart line and does not cross the antimeridian
select SDO_UTIL.TO_WKTGEOMETRY(
SDO_GEOM.SDO_MBR(
MDSYS.SDO_GEOMETRY('MULTILINESTRING((-170 0, -160 1), (-150 1, -140 2))', 8307))
) from dual;
// returns POLYGON ((-170.0 0.0, -140.0 0.0, -140.0 2.0, -170.0 2.0, -170.0 0.0))
Any ideas?
Thanks!
--john
When the geometry crosses the antimeridian, the MBR is not well defined.
In such cases, we make the best possible guess about where the geometry is crossing the meridian line.
In the case of your multi-line, the line does not really cross the meridian line. It has two line segments that are on either
side of the meridian line. So the MBR returned by Spatial is a valid result for this case.
If the line actually crosses the meridian, we know it is supposed to cross the meridian and the expected result is returned.
siva
Thanks Siva. Can you suggest a work around then? For example, is there a command that will join the segments of a multilinestring into a single line so I can calc the MBR on it? The only workable solution I've come up with is to programatically create a MBR on each of the segments and then union them.
--john
You can treat the geometry as a single line instead of a multi-line and call the sdo_mbr function.
For that, you need to do something like this:
select SDO_UTIL.TO_WKTGEOMETRY(
SDO_GEOM.SDO_MBR(sdo_geometry(2002,8307,null,
sdo_elem_info_array(1,2,1), b.geom.sdo_ordinates))) from (
select
MDSYS.SDO_GEOMETRY('MULTILINESTRING((178 0, 179.99 1), (-179.99 1, -178 2))',
8307) geom from dual ) b;
Thanks Siva, that's a great idea.
--john