001: /*
002: * GeoTools - OpenSource mapping toolkit
003: * http://geotools.org
004: * (C) 2007, GeoTools Project Managment Committee (PMC)
005: * (C) 2007, Geomatys
006: *
007: * This library is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU Lesser General Public
009: * License as published by the Free Software Foundation;
010: * version 2.1 of the License.
011: *
012: * This library is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: */
017: package org.geotools.referencing.cs;
018:
019: // J2SE dependencies
020: import java.util.Arrays;
021:
022: // OpenGIS dependencies
023: import org.opengis.referencing.cs.AxisDirection;
024: import org.opengis.referencing.cs.CoordinateSystemAxis;
025:
026: /**
027: * Wraps a {@linkplain CoordinateSystemAxis coordinate system axis} for comparaison purpose.
028: * The sorting order tries to favor a right-handed system. Compass directions like
029: * {@linkplain AxisDirection#NORTH North} or {@linkplain AxisDirection#EAST East} are first,
030: * and vertical or temporal directions like {@linkplain AxisDirection#UP Up} are last.
031: *
032: * @version $Id: ComparableAxisWrapper.java 24683 2007-03-06 06:02:15Z desruisseaux $
033: * @source $URL: http://svn.geotools.org/geotools/tags/2.4.1/modules/library/referencing/src/main/java/org/geotools/referencing/cs/ComparableAxisWrapper.java $
034: * @author Martin Desruisseaux
035: */
036: final class ComparableAxisWrapper implements Comparable {
037: /**
038: * The wrapped axis.
039: */
040: private final CoordinateSystemAxis axis;
041:
042: /**
043: * The direction along meridian, or {@code null} if none.
044: */
045: private final DirectionAlongMeridian meridian;
046:
047: /**
048: * Creates a new wrapper for the given axis.
049: */
050: private ComparableAxisWrapper(final CoordinateSystemAxis axis) {
051: this .axis = axis;
052: meridian = DirectionAlongMeridian.parse(axis.getDirection());
053: }
054:
055: /**
056: * Returns {@code true} if the specified direction is a compass direction.
057: */
058: private static boolean isCompassDirection(
059: final AxisDirection direction) {
060: int compass = DefaultCoordinateSystemAxis.getCompassAngle(
061: direction, AxisDirection.NORTH);
062: return compass != Integer.MIN_VALUE;
063: }
064:
065: /**
066: * Compares with the specified object. See class javadoc
067: * for a description of the sorting order.
068: */
069: public int compareTo(final Object other) {
070: final ComparableAxisWrapper that = (ComparableAxisWrapper) other;
071: final AxisDirection d1 = this .axis.getDirection();
072: final AxisDirection d2 = that.axis.getDirection();
073: final int compass = DefaultCoordinateSystemAxis
074: .getCompassAngle(d2, d1);
075: if (compass != Integer.MIN_VALUE) {
076: return compass;
077: }
078: if (isCompassDirection(d1)) {
079: assert !isCompassDirection(d2) : d2;
080: return -1;
081: }
082: if (isCompassDirection(d2)) {
083: assert !isCompassDirection(d1) : d1;
084: return +1;
085: }
086: if (meridian != null) {
087: if (that.meridian != null) {
088: return meridian.compareTo(that.meridian);
089: }
090: return -1;
091: } else if (that.meridian != null) {
092: return +1;
093: }
094: return 0;
095: }
096:
097: /**
098: * Sorts the specified axis in an attempt to create a right-handed system.
099: * The sorting is performed in place. This method returns {@code true} if
100: * at least one axis moved.
101: */
102: public static boolean sort(final CoordinateSystemAxis[] axis) {
103: final ComparableAxisWrapper[] wrappers = new ComparableAxisWrapper[axis.length];
104: for (int i = 0; i < axis.length; i++) {
105: wrappers[i] = new ComparableAxisWrapper(axis[i]);
106: }
107: Arrays.sort(wrappers);
108: boolean changed = false;
109: for (int i = 0; i < axis.length; i++) {
110: final CoordinateSystemAxis a = wrappers[i].axis;
111: changed |= (axis[i] != a);
112: axis[i] = a;
113: }
114: return changed;
115: }
116: }
|