| 1 |
|
| 2 |
|
| 3 |
|
| 4 |
|
| 5 |
|
| 6 |
|
| 7 |
|
| 8 |
|
| 9 |
|
| 10 |
|
| 11 |
|
| 12 |
|
| 13 |
package org.locationtech.jts.geom; |
| 14 |
|
| 15 |
import java.util.Comparator; |
| 16 |
|
| 17 |
/** |
| 18 |
* Compares two {@link CoordinateSequence}s. |
| 19 |
* For sequences of the same dimension, the ordering is lexicographic. |
| 20 |
* Otherwise, lower dimensions are sorted before higher. |
| 21 |
* The dimensions compared can be limited; if this is done |
| 22 |
* ordinate dimensions above the limit will not be compared. |
| 23 |
* <p> |
| 24 |
* If different behaviour is required for comparing size, dimension, or |
| 25 |
* coordinate values, any or all methods can be overridden. |
| 26 |
* |
| 27 |
*/ |
| 28 |
public class CoordinateSequenceComparator |
| 29 |
implements Comparator |
| 30 |
{ |
| 31 |
/** |
| 32 |
* Compare two <code>double</code>s, allowing for NaN values. |
| 33 |
* NaN is treated as being less than any valid number. |
| 34 |
* |
| 35 |
* @param a a <code>double</code> |
| 36 |
* @param b a <code>double</code> |
| 37 |
* @return -1, 0, or 1 depending on whether a is less than, equal to or greater than b |
| 38 |
*/ |
| 39 |
public static int compare(double a, double b) |
| 40 |
{ |
| 41 |
if (a < b) return -1; |
| 42 |
if (a > b) return 1; |
| 43 |
|
| 44 |
if (Double.isNaN(a)) { |
| 45 |
if (Double.isNaN(b)) return 0; |
| 46 |
return -1; |
| 47 |
} |
| 48 |
|
| 49 |
if (Double.isNaN(b)) return 1; |
| 50 |
return 0; |
| 51 |
} |
| 52 |
|
| 53 |
/** |
| 54 |
* The number of dimensions to test |
| 55 |
*/ |
| 56 |
protected int dimensionLimit; |
| 57 |
|
| 58 |
/** |
| 59 |
* Creates a comparator which will test all dimensions. |
| 60 |
*/ |
| 61 |
public CoordinateSequenceComparator() |
| 62 |
{ |
| 63 |
dimensionLimit = Integer.MAX_VALUE; |
| 64 |
} |
| 65 |
|
| 66 |
/** |
| 67 |
* Creates a comparator which will test only the specified number of dimensions. |
| 68 |
* |
| 69 |
* @param dimensionLimit the number of dimensions to test |
| 70 |
*/ |
| 71 |
public CoordinateSequenceComparator(int dimensionLimit) |
| 72 |
{ |
| 73 |
this.dimensionLimit = dimensionLimit; |
| 74 |
} |
| 75 |
|
| 76 |
/** |
| 77 |
* Compares two {@link CoordinateSequence}s for relative order. |
| 78 |
* |
| 79 |
* @param o1 a {@link CoordinateSequence} |
| 80 |
* @param o2 a {@link CoordinateSequence} |
| 81 |
* @return -1, 0, or 1 depending on whether o1 is less than, equal to, or greater than o2 |
| 82 |
*/ |
| 83 |
public int compare(Object o1, Object o2) |
| 84 |
{ |
| 85 |
CoordinateSequence s1 = (CoordinateSequence) o1; |
| 86 |
CoordinateSequence s2 = (CoordinateSequence) o2; |
| 87 |
|
| 88 |
int size1 = s1.size(); |
| 89 |
int size2 = s2.size(); |
| 90 |
|
| 91 |
int dim1 = s1.getDimension(); |
| 92 |
int dim2 = s2.getDimension(); |
| 93 |
|
| 94 |
int minDim = dim1; |
| 95 |
if (dim2 < minDim) |
| 96 |
minDim = dim2; |
| 97 |
boolean dimLimited = false; |
| 98 |
if (dimensionLimit <= minDim) { |
| 99 |
minDim = dimensionLimit; |
| 100 |
dimLimited = true; |
| 101 |
} |
| 102 |
|
| 103 |
|
| 104 |
if (! dimLimited) { |
| 105 |
if (dim1 < dim2) return -1; |
| 106 |
if (dim1 > dim2) return 1; |
| 107 |
} |
| 108 |
|
| 109 |
|
| 110 |
int i = 0; |
| 111 |
while (i < size1 && i < size2) { |
| 112 |
int ptComp = compareCoordinate(s1, s2, i, minDim); |
| 113 |
if (ptComp != 0) return ptComp; |
| 114 |
i++; |
| 115 |
} |
| 116 |
if (i < size1) return 1; |
| 117 |
if (i < size2) return -1; |
| 118 |
|
| 119 |
return 0; |
| 120 |
} |
| 121 |
|
| 122 |
/** |
| 123 |
* Compares the same coordinate of two {@link CoordinateSequence}s |
| 124 |
* along the given number of dimensions. |
| 125 |
* |
| 126 |
* @param s1 a {@link CoordinateSequence} |
| 127 |
* @param s2 a {@link CoordinateSequence} |
| 128 |
* @param i the index of the coordinate to test |
| 129 |
* @param dimension the number of dimensions to test |
| 130 |
* @return -1, 0, or 1 depending on whether s1[i] is less than, equal to, or greater than s2[i] |
| 131 |
*/ |
| 132 |
protected int compareCoordinate(CoordinateSequence s1, CoordinateSequence s2, int i, int dimension) |
| 133 |
{ |
| 134 |
for (int d = 0; d < dimension; d++) { |
| 135 |
double ord1 = s1.getOrdinate(i, d); |
| 136 |
double ord2 = s2.getOrdinate(i, d); |
| 137 |
int comp = compare(ord1, ord2); |
| 138 |
if (comp != 0) return comp; |
| 139 |
} |
| 140 |
return 0; |
| 141 |
} |
| 142 |
} |
| 143 |
|