sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1813496 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/geometry/ sis-referencing/src/main/java/org/apache/sis/internal/referencing/ sis-referencing/src/main/java/org/apache/sis/referencing/operation/ sis-utility...
Date Fri, 27 Oct 2017 10:02:48 GMT
Author: desruisseaux
Date: Fri Oct 27 10:02:48 2017
New Revision: 1813496

URL: http://svn.apache.org/viewvc?rev=1813496&view=rev
Log:
When detecting if we have a "wraparound change", do not require the source axis to be "wraparound"
too.
Example: conversion of dates on temporal axis (infinite span toward past and future) to a
month in a cyclic 12-months average temperature.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jdk9/JDK9.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Envelopes.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -21,7 +21,7 @@ package org.apache.sis.geometry;
  * support Java2D (e.g. Android),  or applications that do not need it may want to avoid
to
  * force installation of the Java2D module (e.g. JavaFX/SWT).
  */
-import java.util.List;
+import java.util.Set;
 import org.opengis.geometry.Envelope;
 import org.opengis.geometry.DirectPosition;
 import org.opengis.geometry.MismatchedDimensionException;
@@ -724,13 +724,13 @@ poles:  for (int i=0; i<dimension; i++,
          * to reduce the risk of discontinuities. If the user really wants unconditional
wrap around, (s)he can call
          * GeneralEnvelope.normalize().
          */
-        final List<Integer> wrapAroundChanges;
+        final Set<Integer> wrapAroundChanges;
         if (isOperationComplete && operation instanceof AbstractCoordinateOperation)
{
             wrapAroundChanges = ((AbstractCoordinateOperation) operation).getWrapAroundChanges();
         } else {
             wrapAroundChanges = CoordinateOperations.wrapAroundChanges(sourceCRS, targetCS);
         }
-        transformed.normalize(wrapAroundChanges);
+        transformed.normalize(targetCS, 0, wrapAroundChanges.size(), wrapAroundChanges.iterator());
         if (warning != null) {
             recoverableException(Envelopes.class, warning);
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/GeneralEnvelope.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -21,8 +21,8 @@ package org.apache.sis.geometry;
  * support Java2D (e.g. Android),  or applications that do not need it may want to avoid
to
  * force installation of the Java2D module (e.g. JavaFX/SWT).
  */
-import java.util.List;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.io.Serializable;
 import java.lang.reflect.Field;
 import org.opengis.referencing.cs.RangeMeaning;
@@ -809,7 +809,7 @@ public class GeneralEnvelope extends Arr
                          */
                         final double min, max;
                         final double csSpan = getSpan(getAxis(crs, i));
-                        if (span1 >= csSpan || isNegativeZero(span1)) {
+                        if (span1 >= csSpan || isNegativeZero(span1)) {       // Negative
zero if [+0 … -0] range.
                             min = min0;
                             max = max0;
                         } else if (span0 >= csSpan || isNegativeZero(span0)) {
@@ -889,63 +889,68 @@ public class GeneralEnvelope extends Arr
      * @see AbstractDirectPosition#normalize()
      */
     public boolean normalize() {
-        return normalize(null);
+        if (crs == null) {
+            return false;
+        }
+        final int beginIndex = beginIndex();
+        return normalize(crs.getCoordinateSystem(), beginIndex, endIndex() - beginIndex,
null);
     }
 
     /**
-     * Normalizes only the dimensions in the given list, or all dimensions if the list is
null.
-     * This is used for normalizing the result of a coordinate operation where a wrap around
axis
-     * does not necessarily means that the ordinates need to be normalized along that axis.
+     * Normalizes only the dimensions returned by the given iterator, or all dimensions if
the iterator is null.
+     * This is used for normalizing the result of a coordinate operation where a wrap around
axis does not
+     * necessarily means that the ordinates need to be normalized along that axis.
+     *
+     * @param  cs          the coordinate system of this envelope CRS (as an argument because
sometime already known).
+     * @param  beginIndex  index of the first ordinate value in {@link #ordinates} array.
Non-zero for sub-envelopes.
+     * @param  count       number of coordinates, i.e. this envelope dimensions.
+     * @param  dimensions  the dimensions to check for normalization, or {@code null} for
all dimensions.
+     * @return {@code true} if this envelope has been modified as a result of this method
call.
      */
-    final boolean normalize(final List<Integer> dimensions) {
+    final boolean normalize(final CoordinateSystem cs, final int beginIndex, final int count,
final Iterator<Integer> dimensions) {
         boolean changed = false;
-        if (crs != null) {
-            final int d = ordinates.length >>> 1;
-            final int beginIndex = beginIndex();
-            final int count = (dimensions != null) ? dimensions.size() : endIndex() - beginIndex;
-            final CoordinateSystem cs = crs.getCoordinateSystem();
-            for (int j=0; j<count; j++) {
-                final int i = (dimensions != null) ? dimensions.get(j) : j;
-                final int iLower = beginIndex + i;
-                final int iUpper = iLower + d;
-                final CoordinateSystemAxis axis = cs.getAxis(i);
-                final double  minimum = axis.getMinimumValue();
-                final double  maximum = axis.getMaximumValue();
-                final RangeMeaning rm = axis.getRangeMeaning();
-                if (RangeMeaning.EXACT.equals(rm)) {
-                    if (ordinates[iLower] < minimum) {ordinates[iLower] = minimum; changed
= true;}
-                    if (ordinates[iUpper] > maximum) {ordinates[iUpper] = maximum; changed
= true;}
-                } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
-                    final double csSpan = maximum - minimum;
-                    if (csSpan > 0 && csSpan < Double.POSITIVE_INFINITY) {
-                        double o1 = ordinates[iLower];
-                        double o2 = ordinates[iUpper];
-                        if (Math.abs(o2-o1) >= csSpan) {
-                            /*
-                             * If the range exceed the CS span, then we have to replace it
by the
-                             * full span, otherwise the range computed by the "else" block
is too
-                             * small. The full range will typically be [-180 … 180]°.
 However we
-                             * make a special case if the two bounds are multiple of the
CS span,
-                             * typically [0 … 360]°. In this case the [0 … -0]°
range matches the
-                             * original values and is understood by GeneralEnvelope as a
range
-                             * spanning all the world.
-                             */
-                            if (o1 != minimum || o2 != maximum) {
-                                if ((o1 % csSpan) == 0 && (o2 % csSpan) == 0) {
-                                    ordinates[iLower] = +0.0;
-                                    ordinates[iUpper] = -0.0;
-                                } else {
-                                    ordinates[iLower] = minimum;
-                                    ordinates[iUpper] = maximum;
-                                }
-                                changed = true;
+        final int d = ordinates.length >>> 1;
+        for (int j=0; j<count; j++) {
+            final int i = (dimensions != null) ? dimensions.next() : j;
+            final int iLower = beginIndex + i;
+            final int iUpper = iLower + d;
+            final CoordinateSystemAxis axis = cs.getAxis(i);
+            final double  minimum = axis.getMinimumValue();
+            final double  maximum = axis.getMaximumValue();
+            final RangeMeaning rm = axis.getRangeMeaning();
+            if (RangeMeaning.EXACT.equals(rm)) {
+                if (ordinates[iLower] < minimum) {ordinates[iLower] = minimum; changed
= true;}
+                if (ordinates[iUpper] > maximum) {ordinates[iUpper] = maximum; changed
= true;}
+            } else if (RangeMeaning.WRAPAROUND.equals(rm)) {
+                final double csSpan = maximum - minimum;
+                if (csSpan > 0 && csSpan < Double.POSITIVE_INFINITY) {
+                    double o1 = ordinates[iLower];
+                    double o2 = ordinates[iUpper];
+                    if (Math.abs(o2-o1) >= csSpan) {
+                        /*
+                         * If the range exceed the CS span, then we have to replace it by
the
+                         * full span, otherwise the range computed by the "else" block is
too
+                         * small. The full range will typically be [-180 … 180]°.  However
we
+                         * make a special case if the two bounds are multiple of the CS span,
+                         * typically [0 … 360]°. In this case the [0 … -0]° range
matches the
+                         * original values and is understood by GeneralEnvelope as a range
+                         * spanning all the world.
+                         */
+                        if (o1 != minimum || o2 != maximum) {
+                            if ((o1 % csSpan) == 0 && (o2 % csSpan) == 0) {
+                                ordinates[iLower] = +0.0;
+                                ordinates[iUpper] = -0.0;
+                            } else {
+                                ordinates[iLower] = minimum;
+                                ordinates[iUpper] = maximum;
                             }
-                        } else {
-                            o1 = Math.floor((o1 - minimum) / csSpan) * csSpan;
-                            o2 = Math.floor((o2 - minimum) / csSpan) * csSpan;
-                            if (o1 != 0) {ordinates[iLower] -= o1; changed = true;}
-                            if (o2 != 0) {ordinates[iUpper] -= o2; changed = true;}
+                            changed = true;
                         }
+                    } else {
+                        o1 = Math.floor((o1 - minimum) / csSpan) * csSpan;
+                        o2 = Math.floor((o2 - minimum) / csSpan) * csSpan;
+                        if (o1 != 0) {ordinates[iLower] -= o1; changed = true;}
+                        if (o2 != 0) {ordinates[iUpper] -= o2; changed = true;}
                     }
                 }
             }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/geometry/Shapes2D.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.geometry;
 
-import java.util.List;
+import java.util.Set;
 import java.awt.geom.Point2D;
 import java.awt.geom.Line2D;
 import java.awt.geom.Ellipse2D;
@@ -582,7 +582,7 @@ public final class Shapes2D extends Stat
          * than what would be possible with GeneralEnvelope or Envelope2D, but we try to
limit the situation where
          * this expansion is applied.
          */
-        final List<Integer> wrapAroundChanges;
+        final Set<Integer> wrapAroundChanges;
         if (operation instanceof AbstractCoordinateOperation) {
             wrapAroundChanges = ((AbstractCoordinateOperation) operation).getWrapAroundChanges();
         } else {

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/CoordinateOperations.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -16,7 +16,7 @@
  */
 package org.apache.sis.internal.referencing;
 
-import java.util.List;
+import java.util.Set;
 import java.util.Objects;
 import java.util.Collections;
 import javax.measure.UnitConverter;
@@ -63,7 +63,7 @@ public final class CoordinateOperations
      * The last decimal value is 10 (binary {@code 1010}); we don't need to cache more.
      */
     @SuppressWarnings({"unchecked", "rawtypes"})
-    private static final List<Integer>[] CACHE = new List[11];
+    private static final Set<Integer>[] CACHE = new Set[11];
 
     /**
      * The system-wide default factory.
@@ -123,11 +123,11 @@ public final class CoordinateOperations
      * uses the [0 … 360]° range, or the converse.
      *
      * @param  op  the coordinate operation for which to get "wrap around" target dimensions.
-     * @return list of target dimensions where "wrap around" may happen, or an empty list
if none.
+     * @return target dimensions where "wrap around" may happen, or an empty set if none.
      *
      * @see AbstractCoordinateOperation#getWrapAroundChanges()
      */
-    public static List<Integer> wrapAroundChanges(final CoordinateOperation op) {
+    public static Set<Integer> wrapAroundChanges(final CoordinateOperation op) {
         if (op instanceof AbstractCoordinateOperation) {
             return ((AbstractCoordinateOperation) op).getWrapAroundChanges();
         } else if (op != null) {
@@ -138,7 +138,7 @@ public final class CoordinateOperations
                 return wrapAroundChanges(source, target.getCoordinateSystem());
             }
         }
-        return Collections.emptyList();
+        return Collections.emptySet();
     }
 
     /**
@@ -148,9 +148,9 @@ public final class CoordinateOperations
      *
      * @param  source  the source of the coordinate operation.
      * @param  target  the target of the coordinate operation.
-     * @return list of target dimensions where "wrap around" may happen.
+     * @return target dimensions where "wrap around" may happen, or an empty set if none.
      */
-    public static List<Integer> wrapAroundChanges(CoordinateReferenceSystem source,
final CoordinateSystem target) {
+    public static Set<Integer> wrapAroundChanges(CoordinateReferenceSystem source,
final CoordinateSystem target) {
         long changes = changes(source.getCoordinateSystem(), target);
         while (source instanceof GeneralDerivedCRS) {
             source = ((GeneralDerivedCRS) source).getBaseCRS();
@@ -163,7 +163,7 @@ public final class CoordinateOperations
              * the object should be okay ("published" in memory model terminology) even if
we did not synchronized.
              * The reference however may not be visible in the array, but we will check later
in a synchronized block.
              */
-            final List<Integer> existing = CACHE[(int) changes];
+            final Set<Integer> existing = CACHE[(int) changes];
             if (existing != null) {
                 return existing;
             }
@@ -179,10 +179,10 @@ public final class CoordinateOperations
             indices[i] = dim;
             r &= ~(1L << dim);
         }
-        final List<Integer> dimensions = JDK9.listOf(indices);
+        final Set<Integer> dimensions = JDK9.setOf(indices);
         if (useCache) {
             synchronized (CACHE) {
-                final List<Integer> existing = CACHE[(int) changes];
+                final Set<Integer> existing = CACHE[(int) changes];
                 if (existing != null) {
                     return existing;
                 }
@@ -194,66 +194,65 @@ public final class CoordinateOperations
 
     /**
      * Returns the packed indices of target dimensions where ordinate values may need to
be wrapped around.
-     * This method matches source and target coordinate system axes having {@link RangeMeaning#WRAPAROUND},
-     * then verifies if the range of values changed (taking unit conversions in account).
A target dimension
-     * {@code i} may need to "wrap around" the coordinate values if the {@code 1 <<
i} bit is set.
+     * This method matches target coordinate system axes having {@link RangeMeaning#WRAPAROUND}
with source
+     * axes, then verifies if the range of values changed (taking unit conversions in account).
A target
+     * dimension {@code i} may need to "wrap around" the coordinate values if the {@code
1 << i} bit is set.
      * If there is no change, then the value is zero.
      */
     private static long changes(final CoordinateSystem source, final CoordinateSystem target)
{
         long changes = 0;
         if (source != target) {                                 // Optimization for a common
case.
             /*
-             * Get the dimensions of all "wrap around" axes in the source coordinate system.
+             * Get the dimensions of all axes in the source coordinate system as bit fields.
              * We create this list first because we may iterate more than once on those axes
              * and we want to clear the axes that we already matched. We use a bitmask for
-             * efficiency, with the bits of "wrap around" dimensions set to 1.
+             * efficiency, with the bits of dimensions to consider set to 1.
+             *
+             * Note: a previous version was creating a list of "wraparound" axes only. We
removed that filter
+             * because a target wraparound axis may match a source infinite axis. For example
when converting
+             * dates on a temporal axis (with infinite span toward past and future) to months
on a climatology
+             * axis (January to December months without year), the same cycle is repeated
after every 12 months
+             * even if the source axis had no cycle.
              */
-            long isWrapAroundAxis = 0;
-            for (int i=Math.min(Long.SIZE, source.getDimension()); --i >= 0;) {
-                if (isWrapAround(source.getAxis(i))) {
-                    isWrapAroundAxis |= (1 << i);
-                }
-            }
-            if (isWrapAroundAxis != 0) {                        // Loop below is useless
otherwise.
-                /*
-                 * For each "wrap around" axis in the target CRS, search a matching axis
in the source CRS
-                 * which is also "wrap around", is colinear and uses compatible unit of measurement.
There
-                 * is usually at most one "wrap around" axis, but this code is nevertheless
generic enough
-                 * for an arbitrary amount of axes.
-                 */
-                final int dim = Math.min(Long.SIZE, target.getDimension());
-compare:        for (int i=0; i<dim; i++) {
-                    final CoordinateSystemAxis axis = target.getAxis(i);
-                    if (isWrapAround(axis)) {
-                        long candidates = isWrapAroundAxis;
-                        do {
-                            final long mask = Long.lowestOneBit(candidates);
-                            final CoordinateSystemAxis src = source.getAxis(Long.numberOfTrailingZeros(mask));
-                            if (Objects.equals(AxisDirections.absolute(src .getDirection()),
-                                               AxisDirections.absolute(axis.getDirection())))
-                            {
-                                try {
-                                    final UnitConverter c  = src.getUnit().getConverterToAny(axis.getUnit());
-                                    final double minimum   = axis.getMinimumValue();
-                                    final double maximum   = axis.getMaximumValue();
-                                    final double tolerance = (maximum - minimum) * Numerics.COMPARISON_THRESHOLD;
-                                    if (!Numerics.epsilonEqual(c.convert(src.getMinimumValue()),
minimum, tolerance) ||
-                                        !Numerics.epsilonEqual(c.convert(src.getMaximumValue()),
maximum, tolerance))
-                                    {
-                                        changes |= (1 << i);
-                                    }
-                                    isWrapAroundAxis &= ~mask;      // We are done with
this source axis.
-                                    if (isWrapAroundAxis == 0) {
-                                        break compare;              // Useless to continue
if there is no more source axis.
-                                    }
-                                    continue compare;               // Match next pair of
wrap around axes.
-                                } catch (IncommensurableException e) {
-                                    // Ignore (should not happen often). We will try to match
another pair of axes.
+            long isWrapAroundAxis = (1 << source.getDimension()) - 1;
+            /*
+             * For each "wrap around" axis in the target CRS, search a matching axis in the
source CRS
+             * which is also "wrap around", is colinear and uses compatible unit of measurement.
There
+             * is usually at most one "wrap around" axis, but this code is nevertheless generic
enough
+             * for an arbitrary amount of axes.
+             */
+            final int dim = Math.min(Long.SIZE, target.getDimension());
+compare:    for (int i=0; i<dim; i++) {
+                final CoordinateSystemAxis axis = target.getAxis(i);
+                if (isWrapAround(axis)) {
+                    long candidates = isWrapAroundAxis;
+                    do {
+                        final long mask = Long.lowestOneBit(candidates);
+                        final CoordinateSystemAxis src = source.getAxis(Long.numberOfTrailingZeros(mask));
+                        if (Objects.equals(AxisDirections.absolute(src .getDirection()),
+                                           AxisDirections.absolute(axis.getDirection())))
+                        {
+                            try {
+                                final UnitConverter c  = src.getUnit().getConverterToAny(axis.getUnit());
+                                final double minimum   = axis.getMinimumValue();
+                                final double maximum   = axis.getMaximumValue();
+                                final double tolerance = (maximum - minimum) * Numerics.COMPARISON_THRESHOLD;
+                                if (!Numerics.epsilonEqual(c.convert(src.getMinimumValue()),
minimum, tolerance) ||
+                                    !Numerics.epsilonEqual(c.convert(src.getMaximumValue()),
maximum, tolerance))
+                                {
+                                    changes |= (1 << i);
+                                }
+                                isWrapAroundAxis &= ~mask;      // We are done with this
source axis.
+                                if (isWrapAroundAxis == 0) {
+                                    break compare;              // Useless to continue if
there is no more source axis.
                                 }
+                                continue compare;               // Match next pair of wrap
around axes.
+                            } catch (IncommensurableException e) {
+                                // Ignore (should not happen often). We will try to match
another pair of axes.
                             }
-                            candidates &= ~mask;        // Unable to use that axis. Check
if we can use another one.
-                        } while (candidates != 0);
-                    }
+                        }
+                        candidates &= ~mask;        // Unable to use that axis. Check
if we can use another one.
+                    } while (candidates != 0);
                 }
             }
         }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -17,7 +17,7 @@
 package org.apache.sis.referencing.operation;
 
 import java.util.Map;
-import java.util.List;
+import java.util.Set;
 import java.util.Objects;
 import java.util.Collection;
 import java.util.Collections;
@@ -213,12 +213,12 @@ public class AbstractCoordinateOperation
     /**
      * Indices of target dimensions where "wrap around" may happen as a result of this coordinate
operation.
      * This is usually the longitude axis when the source CRS uses the [-180 … +180]°
range and the target
-     * CRS uses the [0 … 360]° range, or the converse. If there is no change, then this
is an empty list.
+     * CRS uses the [0 … 360]° range, or the converse. If there is no change, then this
is an empty set.
      *
      * @see #getWrapAroundChanges()
      * @see #computeTransientFields()
      */
-    private transient List<Integer> wrapAroundChanges;
+    private transient Set<Integer> wrapAroundChanges;
 
     /**
      * Creates a new coordinate operation initialized from the given properties.
@@ -393,7 +393,7 @@ check:      for (int isTarget=0; ; isTar
         if (sourceCRS != null && targetCRS != null) {
             wrapAroundChanges = CoordinateOperations.wrapAroundChanges(sourceCRS, targetCRS.getCoordinateSystem());
         } else {
-            wrapAroundChanges = Collections.emptyList();
+            wrapAroundChanges = Collections.emptySet();
         }
     }
 
@@ -772,7 +772,7 @@ check:      for (int isTarget=0; ; isTar
     /**
      * Returns the indices of target dimensions where "wrap around" may happen as a result
of this coordinate operation.
      * If such change exists, then this is usually the longitude axis when the source CRS
uses the [-180 … +180]° range
-     * and the target CRS uses the [0 … 360]° range, or the converse. If there is no change,
then this is an empty list.
+     * and the target CRS uses the [0 … 360]° range, or the converse. If there is no change,
then this is an empty set.
      *
      * <div class="note"><b>Inverse relationship:</b>
      * sometime the target dimensions returned by this method can be mapped directly to wraparound
axes in source CRS,
@@ -788,18 +788,18 @@ check:      for (int isTarget=0; ; isTar
      * but such matching is not guaranteed to exist since {@code ProjectedCRS} is a special
case of
      * {@code GeneralDerivedCRS} and derived CRS can have rotations.</div>
      *
-     * <p>The default implementation infers this list by inspecting the source and
target coordinate system axes.
+     * <p>The default implementation infers this set by inspecting the source and target
coordinate system axes.
      * It returns the indices of all target axes having {@link org.opengis.referencing.cs.RangeMeaning#WRAPAROUND}
      * and for which the following condition holds: a colinear source axis exists with compatible
unit of measurement,
-     * that source axis also have "wrap around" range, and the range of those source and
target axes are not the same
-     * (taking unit conversions in account).</p>
+     * and the range (taking unit conversions in account) or range meaning of those source
and target axes are not
+     * the same.</p>
      *
      * @return indices of target dimensions where "wrap around" may happen as a result of
this coordinate operation.
      *
      * @since 0.8
      */
     @SuppressWarnings("ReturnOfCollectionOrArrayField")
-    public List<Integer> getWrapAroundChanges() {
+    public Set<Integer> getWrapAroundChanges() {
         return wrapAroundChanges;
     }
 

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jdk9/JDK9.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jdk9/JDK9.java?rev=1813496&r1=1813495&r2=1813496&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jdk9/JDK9.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/jdk9/JDK9.java
[UTF-8] Fri Oct 27 10:02:48 2017
@@ -16,8 +16,11 @@
  */
 package org.apache.sis.internal.jdk9;
 
+import java.util.Arrays;
+import java.util.Set;
 import java.util.List;
 import java.util.Collections;
+import java.util.LinkedHashSet;
 import org.apache.sis.internal.util.UnmodifiableArrayList;
 
 
@@ -52,4 +55,20 @@ public final class JDK9 {
             default: return UnmodifiableArrayList.wrap(elements);
         }
     }
+
+    /**
+     * Placeholder for {@code Set.of(...)}.
+     *
+     * @param  <E>       type of elements.
+     * @param  elements  the elements to put in an unmodifiable set.
+     * @return an unmodifiable set of the given elements.
+     */
+    @SafeVarargs
+    public static <E> Set<E> setOf(final E... elements) {
+        switch (elements.length) {
+            case 0:  return Collections.emptySet();
+            case 1:  return Collections.singleton(elements[0]);
+            default: return Collections.unmodifiableSet(new LinkedHashSet<>(Arrays.asList(elements)));
+        }
+    }
 }



Mime
View raw message