[Geoserver-devel] Exception using SDO_POINT_TYPE geometry

GS 1.7.1, GT 2.5.2 using OracleNG, Ora 10gR2.

Table has SDO_GEOMETRY column built using SDO_POINT_TYPE e.g.

... SDO_GEOMETRY(2001, 8311, SDO_POINT_TYPE(long, lat, null), null, null)
...

ERROR [geotools.rendering] - This type of sequence is always 2 dimensional
java.lang.IllegalArgumentException: This type of sequence is always 2
dimensional
  at
org.geotools.geometry.jts.LiteCoordinateSequence.<init>(LiteCoordinateSequence.java:101)
  at
org.geotools.geometry.jts.LiteCoordinateSequenceFactory.create(LiteCoordinateSequenceFactory.java:50)
  at org.geotools.data.oracle.sdo.SDO.coordinates(SDO.java:2066)

The call @ SDO.java:2066 looks like this
    CoordinateSequence cs = f.create(1, ordinates.length);

The ordinates array has (<valid x value>, <valid y value, NAN) which would
seem correct given the null in the SDO_POINT_TYPE, which is compulsory.

One workaround is to use DIM_INFO and ORDINATE array to specify geometry in
Oracle, but this is a SIGNIFICANT performance hit.

The OracleNG code needs to be modified to detect the SDO_POINT_TYPE and
create the ordinates array with only 2 elements. (I won't even suggest
modifying GS to allow 3D points;-)

Cheers

Stuart

--
View this message in context: http://www.nabble.com/Exception-using-SDO_POINT_TYPE-geometry-tp21102736p21102736.html
Sent from the GeoServer - Dev mailing list archive at Nabble.com.

Having looked further at the code, it would appear a simple fix.

Given that we've already determined that the number of dimensions is 2, the
code could be changed as follows (with a possible improvement the error
message).
[SDO.class lines 2065-70]

       if ((D == 2) && (L == 0) && (TT == 1)) {

            if(ordinates.length < 2)
                 throw new IllegalArgumentException("Bad Oracle SDO_POINT -
should never see this!");
            CoordinateSequence cs = f.create(1, 2 /*ordinates.length*/);
            for (int i = 0; i < 2 /*ordinates.length*/ ; i++)
                cs.setOrdinate(0, i, ordinates[i]);
            return cs;
        }

Cheers

Stuart
--
View this message in context: http://www.nabble.com/Exception-using-SDO_POINT_TYPE-geometry-tp21102736p21102833.html
Sent from the GeoServer - Dev mailing list archive at Nabble.com.

A further investigation shows that in oracle-spatial/.../sdo.java it was
handled this way.

        if ((D == 2) && (L == 0) && (TT == 01) && (ordinates.length == 3)) {
            return f.create(new Coordinate {
                    new Coordinate(ordinates[0], ordinates[1],
ordinates[2]),
                });
        }

I am debugging against jdbc-ng/.../sdo.java.

I am trying to use OracleNG. Am I picking up the wrong sdo.java class?

Cheers

Stuart
--
View this message in context: http://www.nabble.com/Exception-using-SDO_POINT_TYPE-geometry-tp21102736p21102893.html
Sent from the GeoServer - Dev mailing list archive at Nabble.com.

Hi Stuart - I wrote the first version of that code way back when; and do not often have a copy of Oracle installed to test against.
I very carefully just went off the documentation and have never looked at the sdo java classes; indeed this code replies on community testing to be any good (as with all open source).

My understanding from the documentation is that it has already checked that D == 2 above so the check it already knows it can expect 2 points right?

What I would like to confirm with you is that you are using a point type where their ordinates are expected? Or are you using some kind of multipoint? And if so I kind of expected one of those other constants to have told us that ...).

Jody

stumit63 wrote:

Having looked further at the code, it would appear a simple fix.

Given that we've already determined that the number of dimensions is 2, the
code could be changed as follows (with a possible improvement the error
message). [SDO.class lines 2065-70]

       if ((D == 2) && (L == 0) && (TT == 1)) {

            if(ordinates.length < 2)
                 throw new IllegalArgumentException("Bad Oracle SDO_POINT -
should never see this!");
            CoordinateSequence cs = f.create(1, 2 /*ordinates.length*/);
            for (int i = 0; i < 2 /*ordinates.length*/ ; i++)
                cs.setOrdinate(0, i, ordinates[i]);
            return cs;
        }

Cheers

Stuart
  

stumit63 ha scritto:

A further investigation shows that in oracle-spatial/.../sdo.java it was
handled this way.

        if ((D == 2) && (L == 0) && (TT == 01) && (ordinates.length == 3)) {
            return f.create(new Coordinate {
                    new Coordinate(ordinates[0], ordinates[1],
ordinates[2]),
                });
        }

I am debugging against jdbc-ng/.../sdo.java.

I am trying to use OracleNG. Am I picking up the wrong sdo.java class?

No, you're not. The old SDO class was simply making too many
allocations (the Coordinate is thrown away immediately if one
is rendering cause the coordiante sequence uses packed arrays
instead) but in doing so, it was hiding the issue of Oracle
points having two dimensions but three coordinates.

The fix you proposed in an earlier mail seems to work fine,
I'm fixing and adding a test, thanks for sharing

Cheers
Andrea

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.

Andrea Aime ha scritto:
...

The fix you proposed in an earlier mail seems to work fine,
I'm fixing and adding a test, thanks for sharing

Fixed:
http://jira.codehaus.org/browse/GEOT-2228

--
Andrea Aime
OpenGeo - http://opengeo.org
Expert service straight from the developers.