From acbd6f179b66ce0df7a7fd84b6491f345645805e Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Fri, 15 Feb 2019 13:11:29 -0800 Subject: [PATCH 1/2] Check consistency of array Coordinates rather than fixing Signed-off-by: Martin Davis --- .../geom/impl/CoordinateArraySequence.java | 52 ++++++++++++------- .../impl/CoordinateArraySequenceTest.java | 13 ++--- 2 files changed, 40 insertions(+), 25 deletions(-) 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..7950fada80 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,12 @@ /** * 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 toCoordinateArray and 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 +47,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 is this is not possible + * the sequence will have 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 +65,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 is this is not possible + * the sequence will have 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 +102,7 @@ public CoordinateArraySequence(Coordinate[] coordinates, int dimension, int meas if (coordinates == null) { this.coordinates = new Coordinate[0]; } - enforceArrayConsistency( this.coordinates ); + checkArrayConsistency( this.coordinates ); } /** @@ -161,19 +175,19 @@ public CoordinateArraySequence(CoordinateSequence coordSeq) * * @param array array is modified in place as needed */ - 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"); } } } 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) { From d82868d253f45a61061cc5c6505dd9b1e4e9c8c4 Mon Sep 17 00:00:00 2001 From: Martin Davis Date: Fri, 15 Feb 2019 13:58:49 -0800 Subject: [PATCH 2/2] Fixes to CoordinateArraySequence text. Signed-off-by: Martin Davis --- .../geom/impl/CoordinateArraySequence.java | 26 ++++++++++++------- 1 file changed, 17 insertions(+), 9 deletions(-) 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 7950fada80..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,7 +18,8 @@ /** * 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 toCoordinateArray 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, @@ -51,8 +52,8 @@ public class CoordinateArraySequence * of {@link Coordinate}s (the * array is not copied). * The coordinate dimension and measure count is determined by the coordinates - * in the provided array, or is this is not possible - * the sequence will have dimension = 3, measures = 0. + * 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. @@ -69,8 +70,8 @@ public CoordinateArraySequence(Coordinate[] coordinates) * of {@link Coordinate}s (the * array is not copied). * The coordinate measure count is determined by the coordinates - * in the provided array, or is this is not possible - * the sequence will have measures = 0. + * 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. @@ -171,9 +172,15 @@ 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 array is modified in place as needed + * @param array the coordinate array to check. + * + * @throw IllegalStateException if coordinate types are not identical */ protected void checkArrayConsistency(Coordinate[] array) { @@ -186,8 +193,9 @@ protected void checkArrayConsistency(Coordinate[] array) if (type == null) { type = coordinate.getClass(); } - else if(!coordinate.getClass().equals(type)) { - throw new IllegalStateException("Coordinates in array have different types"); + else if(! coordinate.getClass().equals(type)) { + throw new IllegalStateException("Coordinates in array have different types: " + + type.getCanonicalName() + " and " + coordinate.getClass().getCanonicalName()); } } }