Oracle Spatial measured polyline bug
------------------------------------

                 Key: GEOT-3101
                 URL: http://jira.codehaus.org/browse/GEOT-3101
             Project: GeoTools
          Issue Type: Bug
          Components: data oraclespatial
    Affects Versions: 2.6.3
         Environment: Windows 2008 64-bit, Java 1.6.0_2-b02 32-bit, Tomcat 
6.0.2 32-bit, Geoserver 2.0.1, Oracle 11.1.0.7 64-bit
            Reporter: Chris Morgan
            Assignee: Andrea Aime


I am attempting to use Geoserver to create KML from an oracle data source of 
polylines with measures.
I am receiving the following error message when attempting to render the layer, 
either as KML or as OpenLayers:

IllegalArgumentException
Dimension D:3 and L:3 denote Coordiantes of 6 ordinates. This cannot be 
resolved withan ordinate array of length 15.
 
The Oracle Spatial layer is defined with SDO_GTYPE 3302. This is a valid
layer which displays correctly when rendered with ArcSDE or a direct connection 
from ArcMap.

There is a bug in method
org.geotools.data.oracle.sdo.SDO.coordinates(CoordinateSequenceFactory f, final 
int GTYPE, double[] ordinates))
which incorrectly adds the measure dimenion to the total number of coordinate 
dimensions,
when actually it should just be checking whether the measure dimension is valid.

Sample SQL for inserting a line
{{
insert into SEISMIC_2D_SDO (GEOMETRY_ID, LINE_NAME, GEOMETRY)
values (1, 'P/PLE-1',
   mdsys.sdo_geometry(
      3302,
      8307,
      null,
      mdsys.sdo_elem_info_array(1,2,1),
      mdsys.sdo_ordinate_array(
         -- LON,LAT,SP
         2.97819, 54.04142, 895,
         2.98058, 54.03858, 900,
         2.98497, 54.03645, 905,
         2.98775, 54.03433, 910
      )
   )
);
}}

Here is a working fix for this method (please excuse my code).
Using this fixed and rebuilt jar gt-jdbc-oracle-x.x.x.jar, Geoserver renders 
the polylines correctly.

{{
    public static CoordinateSequence coordinates(CoordinateSequenceFactory f,
        final int GTYPE, double[] ordinates) {
 
        if ((ordinates == null) || (ordinates.length == 0)) {
            return f.create(new Coordinate[0]);
        }

        final int D = SDO.D(GTYPE);
        final int L = SDO.L(GTYPE);
        final int TT = SDO.TT(GTYPE);

        //      POINT_TYPE Special Case
        //
        if ((D == 2) && (L == 0) && (TT == 1)) {
            CoordinateSequence cs = f.create(1, 2);
            for (int i = 0; i < 2; i++)
                cs.setOrdinate(0, i, ordinates[i]);
            return cs;
        }

        // CM 4/05/2010 bug fix for measured polylines - SDO_GTYPE 3302
        // valid values for L are 0,3,4 - could check for this somewhere
        //final int LEN = D + L; // this is wrong
        if (L > D) {
            throw new IllegalArgumentException("Dimension L:"+L+" is greater 
than D:"+D);    
        }
        
        final int LEN = D;

        if ((ordinates.length % LEN) != 0) {
            throw new IllegalArgumentException("Dimension D:" + D + " and L:"
                + L + " denote Coordiantes " + "of " + LEN
                + " ordinates. This cannot be resolved with"
                + "an ordinate array of length " + ordinates.length);
        }
        
        // special optimization for faster 2D rendering
        if (D == 2 && L == 0 && f instanceof LiteCoordinateSequenceFactory) {
            return ((LiteCoordinateSequenceFactory) f).create(ordinates);
        }

        // CM 4/05/2010 LENGTH never used - code removed
        //final int LENGTH = ordinates.length / LEN;
        
        OrdinateList x = new OrdinateList(ordinates, 0, LEN);
        OrdinateList y = new OrdinateList(ordinates, 1, LEN);
        OrdinateList z = null;

        if (D == 3 && L != 3) { // CM 4/05/2010 check L
            z = new OrdinateList(ordinates, 2, LEN);
        }
        
        if (L != 0) {
            /* // CM 4/05/2010 code removed
            OrdinateList[] m = new OrdinateList[L];

            for (int i = 0; i < L; i++) {
                m[i] = new OrdinateList(ordinates, D + i, LEN);
            }
            */

            // CM 4/05/2010 
            // Oracle SDO shapes can only have a single measure dimension,
            // so not sure what the point of the array and for-loop are doing 
here.
            // We just need to populate a single measure dimension
            OrdinateList[] m = new OrdinateList[1];
            m[0] = new OrdinateList(ordinates, L-1, LEN);
            
            return coordiantes(f, x, y, z, m);            
        } else {
            return coordiantes(f, x, y, z);
        }        
    }
}}


-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: 
http://jira.codehaus.org/secure/Administrators.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        

------------------------------------------------------------------------------

_______________________________________________
Geotools-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/geotools-devel

Reply via email to