Skip to content

Commit fb0635e

Browse files
committed
Shift polygon away from antimeridan for orientation detection
1 parent d9f01ba commit fb0635e

File tree

1 file changed

+36
-5
lines changed

1 file changed

+36
-5
lines changed

src/main/java/gov/nasa/cumulus/metadata/aggregator/UMMUtils.java

+36-5
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
import gov.nasa.podaac.inventory.model.Dataset;
1313
import gov.nasa.podaac.inventory.model.DatasetCitation;
1414
import org.apache.commons.lang3.StringUtils;
15+
import org.apache.commons.lang3.SerializationUtils;
1516
import org.apache.commons.logging.Log;
1617
import org.apache.commons.logging.LogFactory;
1718

@@ -222,6 +223,34 @@ public static boolean isGlobalBoundingBox(ArrayList<Coordinate> coordinates) {
222223
}
223224
}
224225

226+
227+
/**
228+
* Shift the polygon, if necessary, to move it into Cartesian space when there
229+
* is an antimeridian crossing.
230+
* @param coordinates the polygon coordinates
231+
* @return the shifted polygon if there is an antimeridian cross, else a copy
232+
* of the original polygon
233+
*/
234+
public static Coordinate[] shiftPolygon(final Coordinate[] coordinates) {
235+
Coordinate[] shiftedCoordinates = SerializationUtils.clone(coordinates);
236+
237+
for (int i = 1; i < shiftedCoordinates.length; ++i) {
238+
Coordinate coordinate = shiftedCoordinates[i];
239+
Coordinate previousCoordinate = shiftedCoordinates[i - 1];
240+
241+
double deltaLongitude = coordinate.x - previousCoordinate.x;
242+
243+
if (Math.abs(deltaLongitude) > 180) {
244+
double direction = deltaLongitude / Math.abs(deltaLongitude);
245+
double crossingShift = direction * 360;
246+
coordinate.x = coordinate.x - crossingShift;
247+
}
248+
}
249+
250+
return shiftedCoordinates;
251+
}
252+
253+
225254
/**
226255
* This function is to take a counterclockwise or clockwise sequence indicator and translate the input coordination
227256
* array based on the desired orientation.
@@ -234,17 +263,19 @@ public static Coordinate[] ensureOrientation(
234263
if (coord.length == 0) {
235264
return coord;
236265
}
237-
final int orientation = CGAlgorithms.isCCW(coord) ? CGAlgorithms.COUNTERCLOCKWISE
266+
267+
Coordinate[] shiftedPolygon = shiftPolygon(coord);
268+
final int orientation = CGAlgorithms.isCCW(shiftedPolygon) ? CGAlgorithms.COUNTERCLOCKWISE
238269
: CGAlgorithms.CLOCKWISE;
239270

240271
if (orientation != desiredOrientation) {
241-
final Coordinate[] reverse = coord.clone();
242-
reverse(reverse);
243-
244-
return reverse;
272+
reverse(coord);
245273
}
274+
246275
return coord;
247276
}
277+
278+
248279
public static ArrayList<Coordinate> eliminateDuplicates(ArrayList<Coordinate> inputCoordinates) {
249280
int size = inputCoordinates.size();
250281
ArrayList<Coordinate> removeCandidateCoordinates = new ArrayList<>();

0 commit comments

Comments
 (0)