Skip to content

Commit

Permalink
Merge pull request #159 from dr-jts/oram-9.x
Browse files Browse the repository at this point in the history
[GEOT-3101] Oracle SDO fixes to read measured geometries
  • Loading branch information
aaime committed Mar 12, 2013
2 parents ab0c669 + c41f12b commit 55f68ca
Show file tree
Hide file tree
Showing 3 changed files with 389 additions and 20 deletions.
Expand Up @@ -106,7 +106,7 @@ public final class SDO {
* </ul>
*
* <p>
* Definition provided by Oracle Spatial User�s Guide and Reference.
* Definition provided by Oracle Spatial User�s Guide and Reference.
* </p>
*
* @param geom
Expand Down Expand Up @@ -1726,7 +1726,7 @@ private static CoordinateSequence subList(
// Use all Cordiantes
return coords;
}
final int LEN = D(GTYPE) + L(GTYPE);
final int LEN = D(GTYPE);

int start = (STARTING_OFFSET - 1) / LEN;
int end = (ENDING_OFFSET != -1) ? ((ENDING_OFFSET - 1) / LEN)
Expand Down Expand Up @@ -2030,20 +2030,26 @@ public static Coordinate[] asCoordiantes(double[] ordinates, int d) {
* D: Dimension of ordinates
* </li>
* <li>
* L: Dimension of LRS measures
* L: Ordinate that represents the LRS measure
* </li>
* </ul>
* </p>
*
* <p>
* The number of ordinates per coordinate are taken to be L+D, and the
* The number of ordinates per coordinate are taken to be D, and the
* number of ordinates should be a multiple of this value.
* </p>
*
* <p>
* In the Special case of GTYPE 2001 and a three ordinates are interpreted
* as a single Coordinate rather than an error.
* </p>
*
* <p>
* For 3-dimensional coordinates we assume z to be the third ordinate. If
* the LRS measure value is stored in the third ordinate (L=3) we assume a
* 2-dimensional coordinate.
* </p>
*
* @param f CoordinateSequenceFactory used to encode ordiantes for JTS
* @param GTYPE Encoding of <b>D</b>imension, <b>L</b>RS and <b>TT</b>ype
Expand Down Expand Up @@ -2071,15 +2077,22 @@ public static CoordinateSequence coordinates(CoordinateSequenceFactory f,
return cs;
}

final int LEN = D + L;
final int LEN = D; // bugfix 20121231-BK: LEN = D instead of LEN = D + L as Oracle supports only one LRS ordinate!

if ((ordinates.length % LEN) != 0) {
throw new IllegalArgumentException("Dimension D:" + D + " and L:"
+ L + " denote Coordiantes " + "of " + LEN
// bugfix 20121231-BK: LEN is D instead of D + L
throw new IllegalArgumentException("Dimension D:" + D
+ " denote Coordiantes " + "of " + LEN
+ " ordinates. This cannot be resolved with"
+ "an ordinate array of length " + ordinates.length);
}

// bugfix 20121231-BK: throw exception if L > D (4 lines added)
if (L != 0 && L > D) {
throw new IllegalArgumentException("Dimension D:" + D
+ " and LRS with L: " + L + " is not supported at a position > D");
}

// special optimization for faster 2D rendering
if(D == 2 && L == 0 && f instanceof LiteCoordinateSequenceFactory) {
return ((LiteCoordinateSequenceFactory) f).create(ordinates);
Expand All @@ -2091,17 +2104,16 @@ public static CoordinateSequence coordinates(CoordinateSequenceFactory f,
OrdinateList y = new OrdinateList(ordinates, 1, LEN);
OrdinateList z = null;

if (D == 3) {
// bugfix 20121231-BK: add z-Coordinate just if D >= 3 and L != 3
if (D >= 3 && L != 3) {
z = new OrdinateList(ordinates, 2, LEN);
}

if (L != 0) {
OrdinateList[] m = new OrdinateList[L];

for (int i = 0; i < L; i++) {
m[i] = new OrdinateList(ordinates, D + i, LEN);
}
// bugfix 20121231-BK: Oracle supports only one LRS ordinate! (removed 6 lines, added 2)
OrdinateList m = new OrdinateList(ordinates, L - 1, LEN);

// TODO org.geotools.geometry.jts.CoordinateSequenceFactory does not support 4 dimensions - thus we will get only 3 dimensions!
return coordiantes(f, x, y, z, m);
} else {
return coordiantes(f, x, y, z);
Expand Down Expand Up @@ -2180,6 +2192,49 @@ public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
}

/**
* bugfix 20121231-BK: added:
* TODO org.geotools.geometry.jts.CoordinateSequenceFactory does not support 4 dimensions!
* Construct CoordinateSequence with LRS measures.
*
* <p>
* To produce three dimension Coordiantes pass in <code>null</code> for z
* </p>
*
* @param f {@link CoordinateSequenceFactory}
* @param x x-ordinates
* @param y y-ordinates
* @param z z-ordinates, <code>null</code> for 2D
* @param m m-ordinates
*
* @return {@link CoordinateSequence}
*/
public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
OrdinateList x, OrdinateList y, OrdinateList z, OrdinateList m) {
final int LENGTH = x.size();
// TODO org.geotools.geometry.jts.LiteCoordinateSequenceFactory does not support 4 dimensions!
// CoordinateSequence cs = f.create(LENGTH, z == null ? 3: 4);
CoordinateSequence cs = f.create(LENGTH, z == null ? 2: 3);

if (z != null) {
for (int i = 0; i < LENGTH; i++) {
cs.setOrdinate(i, 0, x.getDouble(i));
cs.setOrdinate(i, 1, y.getDouble(i));
cs.setOrdinate(i, 2, z.getDouble(i));
// cs.setOrdinate(i, 3, m.getDouble(i));
}
} else {
for (int i = 0; i < LENGTH; i++) {
cs.setOrdinate(i, 0, x.getDouble(i));
cs.setOrdinate(i, 1, y.getDouble(i));
// cs.setOrdinate(i, 2, m.getDouble(i));
}
}

return cs;
}

/**
* @deprecated bugfix 20121231-BK: Oracle supports only one LRS measure information! use {@link SDO#coordiantes(CoordinateSequenceFactory, OrdinateList, OrdinateList, OrdinateList, OrdinateList) coordiantes() with just a OrdinateList of measures}!
* Construct SpatialCoordiantes, with LRS measure information.
*
* <p>
Expand All @@ -2194,6 +2249,7 @@ public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
*
* @return DOCUMENT ME!
*/
@Deprecated
public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
OrdinateList x, OrdinateList y, OrdinateList z, OrdinateList[] m) {
final int D = (z != null) ? 3 : 2;
Expand Down Expand Up @@ -2222,6 +2278,7 @@ public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
}

/**
* @deprecated bugfix 20121231-BK: Oracle supports only one LRS measure information! use {@link SDO#coordiantes(CoordinateSequenceFactory, OrdinateList, OrdinateList, OrdinateList, OrdinateList) coordiantes() with just a OrdinateList of measures}!
* Construct SpatialCoordiantes, with LRS measure information.
*
* <p>
Expand All @@ -2236,6 +2293,7 @@ public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
*
* @return DOCUMENT ME!
*/
@Deprecated
public static CoordinateSequence coordiantes(CoordinateSequenceFactory f,
AttributeList x,
AttributeList y,
Expand Down Expand Up @@ -2718,7 +2776,7 @@ private static MultiPoint createMultiPoint(GeometryFactory gf,
return null;
}

final int LEN = D(GTYPE) + L(GTYPE);
final int LEN = D(GTYPE);

int start = (STARTING_OFFSET - 1) / LEN;
int end = start + INTERPRETATION;
Expand Down Expand Up @@ -2779,7 +2837,7 @@ private static MultiLineString createMultiLine(GeometryFactory gf,
return null;
}

final int LEN = D(GTYPE) + L(GTYPE);
//final int LEN = D(GTYPE);
final int endTriplet = (N != -1) ? (triplet + N) : (elemInfo.length / 3);

List list = new LinkedList();
Expand Down Expand Up @@ -2848,7 +2906,6 @@ private static MultiPolygon createMultiPolygon(GeometryFactory gf,
LOGGER.warning( "Could not create MultiPolygon with INTERPRETATION "+INTERPRETATION +" - we can only represent 1 for straight edges, or 3 for rectangle");
return null;
}
final int LEN = D(GTYPE) + L(GTYPE);
final int endTriplet = (N != -1) ? (triplet + N)
: ((elemInfo.length / 3) + 1);

Expand Down Expand Up @@ -2914,15 +2971,12 @@ private static GeometryCollection createCollection(GeometryFactory gf,
final int GTYPE, final int SRID, final int[] elemInfo,
final int triplet, CoordinateSequence coords, final int N) {
final int STARTING_OFFSET = STARTING_OFFSET(elemInfo, triplet);
final int eTYPE = ETYPE(elemInfo, triplet);
final int INTERPRETATION = INTERPRETATION(elemInfo, triplet);

final int LENGTH = coords.size()*D(GTYPE);

if (!(STARTING_OFFSET >= 1) || !(STARTING_OFFSET <= LENGTH))
throw new IllegalArgumentException("ELEM_INFO STARTING_OFFSET "+STARTING_OFFSET+" inconsistent with ORDINATES length "+coords.size());

final int LEN = D(GTYPE) + L(GTYPE);
final int endTriplet = (N != -1) ? (triplet + N)
: ((elemInfo.length / 3) + 1);

Expand Down Expand Up @@ -2989,4 +3043,4 @@ private static GeometryCollection createCollection(GeometryFactory gf,

return geoms;
}
}
}
@@ -0,0 +1,63 @@
package org.geotools.data.oracle.sdo;

/**
* Mimics Oracle MDSYS functions for building geometries. Useful for creating test objects.
*
* @author Martin Davis
*
*/
public class MDSYS {

protected static final int NULL = -1;

public static SDO_GEOMETRY SDO_GEOMETRY(int gType, int srid, int ptType, int[] elemInfo,
double[] ordinates) {
return new SDO_GEOMETRY(gType, srid, elemInfo, ordinates);
}

public static SDO_GEOMETRY SDO_GEOMETRY(int gType, int srid, double[] ptType, int null1,
int null2) {
return new SDO_GEOMETRY(gType, srid, ptType);
}

public static double[] SDO_POINT_TYPE(double x, double y, double z) {
if (z == NULL)
z = Double.NaN;
return new double[] { x, y, z };
}

public static int[] SDO_ELEM_INFO_ARRAY(int... i) {
return i;
}

public static double[] SDO_ORDINATE_ARRAY(double... d) {
return d;
}

public static class SDO_GEOMETRY {

int gType;

int srid;

double[] ptType;

int[] elemInfo;

double[] ordinates;

public SDO_GEOMETRY(int gType, int srid, int[] elemInfo, double[] ordinates) {
this.gType = gType;
this.srid = srid;
this.elemInfo = elemInfo;
this.ordinates = ordinates;
}

public SDO_GEOMETRY(int gType, int srid, double[] ptType) {
this.gType = gType;
this.srid = srid;
this.ptType = ptType;
}

}
}

0 comments on commit 55f68ca

Please sign in to comment.