diff --git a/modules/core/src/main/java/org/locationtech/jts/geom/impl/CoordinateArraySequence.java b/modules/core/src/main/java/org/locationtech/jts/geom/impl/CoordinateArraySequence.java index fef7107f73..50054470f4 100644 --- a/modules/core/src/main/java/org/locationtech/jts/geom/impl/CoordinateArraySequence.java +++ b/modules/core/src/main/java/org/locationtech/jts/geom/impl/CoordinateArraySequence.java @@ -18,13 +18,13 @@ /** * A {@link CoordinateSequence} backed by an array of {@link Coordinate}s. * This is the implementation that {@link Geometry}s use by default. - * Coordinates returned by #toArray and #getCoordinate are live -- + * Coordinates returned by {@link #toCoordinateArray()} + * and {@link #getCoordinate()} are live -- * modifications to them are actually changing the * CoordinateSequence's underlying data. * A dimension may be specified for the coordinates in the sequence, - * which may be 2 or 3. - * The actual coordinates will always have 3 ordinates, - * but the dimension is useful as metadata in some situations. + * which may be 2, 3, or 4. + * A measure count may be specified for the coordinates in the sequence. * * @version 1.7 */ @@ -48,12 +48,17 @@ public class CoordinateArraySequence private Coordinate[] coordinates; /** - * Constructs a sequence based on the given array + * Constructs a sequence using the given array * of {@link Coordinate}s (the * array is not copied). - * The coordinate dimension defaults to 3. + * The coordinate dimension and measure count is determined by the coordinates + * in the provided array, or if this is not possible + * the sequence is assigned dimension = 3, measures = 0. + * The coordinates in the array must all have the same type. * * @param coordinates the coordinate array that will be referenced. + * + * @throw IllegalStateException if coordinate types are not identical */ public CoordinateArraySequence(Coordinate[] coordinates) { @@ -61,24 +66,34 @@ public CoordinateArraySequence(Coordinate[] coordinates) } /** - * Constructs a sequence based on the given array + * Constructs a sequence using the given array * of {@link Coordinate}s (the * array is not copied). + * The coordinate measure count is determined by the coordinates + * in the provided array, or if this is not possible + * the sequence is assigned measures = 0. + * The coordinates in the array must all have the same type. * * @param coordinates the coordinate array that will be referenced. - * @param dimension the dimension of the coordinates + * @param dimension the dimension of the coordinates in the sequence + * + * @throw IllegalStateException if coordinate types are not identical */ public CoordinateArraySequence(Coordinate[] coordinates, int dimension) { this(coordinates, dimension, CoordinateArrays.measures(coordinates)); } /** - * Constructs a sequence based on the given array + * Constructs a sequence using the given array * of {@link Coordinate}s (the * array is not copied). + * The coordinates in the array must all have the same type. * * @param coordinates the coordinate array that will be referenced. - * @param dimension the dimension of the coordinates + * @param dimension the dimension of the coordinates in the sequence + * @param measure the measure of the coordinates in the sequence + * + * @throw IllegalStateException if coordinate types are not identical */ public CoordinateArraySequence(Coordinate[] coordinates, int dimension, int measures) { @@ -88,7 +103,7 @@ public CoordinateArraySequence(Coordinate[] coordinates, int dimension, int meas if (coordinates == null) { this.coordinates = new Coordinate[0]; } - enforceArrayConsistency( this.coordinates ); + checkArrayConsistency( this.coordinates ); } /** @@ -157,23 +172,30 @@ public CoordinateArraySequence(CoordinateSequence coordSeq) } /** - * Ensure array contents of the same type, making use of {@link #createCoordinate()} as needed. + * Check array coordinates are of the same type. + * The array is not modified. + * {@code null} entries are not reported, + * since it is expected that downstream processing + * will report them if needed. + * + * @param array the coordinate array to check. * - * @param array array is modified in place as needed + * @throw IllegalStateException if coordinate types are not identical */ - protected void enforceArrayConsistency(Coordinate[] array) + protected void checkArrayConsistency(Coordinate[] array) { - Coordinate sample = createCoordinate(); - Class type = sample.getClass(); + Class type = null; for( int i = 0; i < array.length; i++) { Coordinate coordinate = array[i]; if( coordinate == null ) { - array[i] = createCoordinate(); + continue; + } + if (type == null) { + type = coordinate.getClass(); } - else if(!coordinate.getClass().equals(type)) { - Coordinate duplicate = createCoordinate(); - duplicate.setCoordinate(coordinate); - array[i] = duplicate; + else if(! coordinate.getClass().equals(type)) { + throw new IllegalStateException("Coordinates in array have different types: " + + type.getCanonicalName() + " and " + coordinate.getClass().getCanonicalName()); } } } diff --git a/modules/core/src/test/java/org/locationtech/jts/geom/impl/CoordinateArraySequenceTest.java b/modules/core/src/test/java/org/locationtech/jts/geom/impl/CoordinateArraySequenceTest.java index a2e5f9176c..5479db26ef 100644 --- a/modules/core/src/test/java/org/locationtech/jts/geom/impl/CoordinateArraySequenceTest.java +++ b/modules/core/src/test/java/org/locationtech/jts/geom/impl/CoordinateArraySequenceTest.java @@ -179,12 +179,13 @@ public void testMixedCoordinates() CoordinateXY coord2 = new CoordinateXY(2.0,2.0); CoordinateXYM coord3 = new CoordinateXYM(3.0,3.0,3.0); Coordinate[] array = new Coordinate[] {coord1, coord2, coord3}; - CoordinateSequence seq = factory.create(array); - assertEquals( 3, seq.getDimension()); - assertEquals( 1, seq.getMeasures()); - assertTrue( coord1.equals( seq.getCoordinate(0))); - assertTrue( coord2.equals( seq.getCoordinate(1))); - assertTrue( coord3.equals( seq.getCoordinate(2))); + try { + CoordinateSequence seq = factory.create(array); + } + catch (IllegalStateException e) { + return; + } + fail(); } private void initProgression(CoordinateSequence seq) {