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;-)
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;
}
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;
}
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.