sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject [sis] 03/03: Moved the "reduce" method for keeping it close to "compound".
Date Thu, 03 Jan 2019 19:05:09 GMT
This is an automated email from the ASF dual-hosted git repository.

desruisseaux pushed a commit to branch geoapi-4.0
in repository https://gitbox.apache.org/repos/asf/sis.git

commit 5bdc8570d0f93df290ae89f63ceeeaa849f6257f
Author: Martin Desruisseaux <martin.desruisseaux@geomatys.com>
AuthorDate: Thu Jan 3 19:56:28 2019 +0100

    Moved the "reduce" method for keeping it close to "compound".
---
 .../main/java/org/apache/sis/referencing/CRS.java  | 172 +++++++++++----------
 1 file changed, 88 insertions(+), 84 deletions(-)

diff --git a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
index 8218765..e91666d 100644
--- a/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
+++ b/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
@@ -932,6 +932,93 @@ public final class CRS extends Static {
     }
 
     /**
+     * Gets or creates a coordinate reference system with a subset of the dimensions of the
given CRS.
+     * This method can be used for dimensionality reduction.
+     *
+     * @param  crs         the CRS to reduce the dimensionality, or {@code null} if none.
+     * @param  dimensions  the dimensions to retain. The dimensions will be taken in increasing
order, ignoring duplicated values.
+     * @return a coordinate reference system for the given dimensions. May be the given {@code
crs}, which may be {@code null}.
+     * @throws IllegalArgumentException if the given array is empty or if the array contains
invalid indices.
+     * @throws FactoryException if the geodetic factory failed to create a compound CRS.
+     *
+     * @see #getComponentAt(CoordinateReferenceSystem, int, int)
+     * @see #compound(CoordinateReferenceSystem...)
+     *
+     * @since 1.0
+     */
+    public static CoordinateReferenceSystem reduce(final CoordinateReferenceSystem crs, final
int... dimensions) throws FactoryException {
+        ArgumentChecks.ensureNonNull("dimensions", dimensions);
+        if (crs == null) {
+            return null;
+        }
+        final int dimension = ReferencingUtilities.getDimension(crs);
+        long selected = 0;
+        for (final int d : dimensions) {
+            if (d < 0 || d >= dimension) {
+                throw new IndexOutOfBoundsException(Errors.format(Errors.Keys.IndexOutOfBounds_1,
d));
+            }
+            if (d >= Long.SIZE) {
+                throw new IllegalArgumentException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1,
d));
+            }
+            selected |= (1L << d);
+        }
+        if (selected == 0) {
+            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"dimensions"));
+        }
+        final List<CoordinateReferenceSystem> components = new ArrayList<>(Long.bitCount(selected));
+        reduce(0, crs, dimension, selected, components);
+        return compound(components.toArray(new CoordinateReferenceSystem[components.size()]));
+    }
+
+    /**
+     * Adds the components of reduced CRS into the given list.
+     * This method may invoke itself recursively for walking through compound CRS.
+     *
+     * @param  previous    number of dimensions of previous CRS.
+     * @param  crs         the CRS for which to select components.
+     * @param  dimension   number of dimensions of {@code crs}.
+     * @param  selected    bitmask of dimensions to select.
+     * @param  addTo       where to add CRS components.
+     * @return new bitmask after removal of dimensions of the components added to {@code
addTo}.
+     */
+    private static long reduce(int previous, final CoordinateReferenceSystem crs, int dimension,
long selected,
+            final List<CoordinateReferenceSystem> addTo) throws FactoryException
+    {
+        final long current = (Numerics.bitmask(dimension) - 1) << previous;
+        final long intersect = selected & current;
+        if (intersect != 0) {
+            if (intersect == current) {
+                addTo.add(crs);
+                selected &= ~current;
+            } else if (crs instanceof CompoundCRS) {
+                for (final CoordinateReferenceSystem component : ((CompoundCRS) crs).getComponents())
{
+                    dimension = ReferencingUtilities.getDimension(component);
+                    selected = reduce(previous, component, dimension, selected, addTo);
+                    if ((selected & current) == 0) break;           // Stop if it would
be useless to continue.
+                    previous += dimension;
+                }
+            } else if (dimension == 3 && crs instanceof SingleCRS) {
+                final Datum datum = ((SingleCRS) crs).getDatum();
+                if (datum instanceof GeodeticDatum) {
+                    final boolean isVertical = Long.bitCount(intersect) == 1;           
   // Presumed for now, verified later.
+                    final int verticalDimension = Long.numberOfTrailingZeros((isVertical
? intersect : ~intersect) >>> previous);
+                    final CoordinateSystemAxis verticalAxis = crs.getCoordinateSystem().getAxis(verticalDimension);
+                    if (AxisDirections.isVertical(verticalAxis.getDirection())) try {
+                        addTo.add(new EllipsoidalHeightSeparator((GeodeticDatum) datum).separate((SingleCRS)
crs, isVertical));
+                        selected &= ~current;
+                    } catch (IllegalArgumentException | ClassCastException e) {
+                        throw new FactoryException(Resources.format(Resources.Keys.CanNotSeparateCRS_1,
crs.getName()));
+                    }
+                }
+            }
+        }
+        if ((selected & current) != 0) {
+            throw new FactoryException(Resources.format(Resources.Keys.CanNotSeparateCRS_1,
crs.getName()));
+        }
+        return selected;
+    }
+
+    /**
      * Returns {@code true} if the given CRS is horizontal. The current implementation considers
a
      * CRS as horizontal if it is two-dimensional and comply with one of the following conditions:
      *
@@ -1254,6 +1341,7 @@ public final class CRS extends Static {
      *         or can not be decomposed for dimensions in the [{@code lower} … {@code upper}]
range.
      * @throws IndexOutOfBoundsException if the given index are out of bounds.
      *
+     * @see #reduce(CoordinateReferenceSystem, int...)
      * @see org.apache.sis.geometry.GeneralEnvelope#subEnvelope(int, int)
      *
      * @since 0.5
@@ -1287,90 +1375,6 @@ check:  while (lower != 0 || upper != dimension) {
     }
 
     /**
-     * Gets or creates a coordinate reference system with a subset of the dimensions of the
given CRS.
-     * This method can be used for dimensionality reduction.
-     *
-     * @param  crs         the CRS to reduce the dimensionality, or {@code null} if none.
-     * @param  dimensions  the dimensions to retain. The dimensions will be taken in increasing
order, ignoring duplicated values.
-     * @return a coordinate reference system for the given dimensions. May be the given {@code
crs}, which may be {@code null}.
-     * @throws IllegalArgumentException if the given array is empty or if the array contains
invalid indices.
-     * @throws FactoryException if the geodetic factory failed to create a compound CRS.
-     *
-     * @since 1.0
-     */
-    public static CoordinateReferenceSystem reduce(final CoordinateReferenceSystem crs, final
int... dimensions) throws FactoryException {
-        ArgumentChecks.ensureNonNull("dimensions", dimensions);
-        if (crs == null) {
-            return null;
-        }
-        final int dimension = ReferencingUtilities.getDimension(crs);
-        if (dimension > Long.SIZE) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1,
dimension));
-        }
-        long selected = 0;
-        for (final int d : dimensions) {
-            if (d < 0 || d >= dimension) {
-                throw new IndexOutOfBoundsException(Errors.format(Errors.Keys.IndexOutOfBounds_1,
d));
-            }
-            selected |= (1L << d);
-        }
-        if (selected == 0) {
-            throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1,
"dimensions"));
-        }
-        final List<CoordinateReferenceSystem> components = new ArrayList<>(Long.bitCount(selected));
-        reduce(0, crs, dimension, selected, components);
-        return compound(components.toArray(new CoordinateReferenceSystem[components.size()]));
-    }
-
-    /**
-     * Adds the components of reduced CRS into the given list.
-     * This method may invoke itself recursively for walking through compound CRS.
-     *
-     * @param  previous    number of dimensions of previous CRS.
-     * @param  crs         the CRS for which to select components.
-     * @param  dimension   number of dimensions of {@code crs}.
-     * @param  selected    bitmask of dimensions to select.
-     * @param  addTo       where to add CRS components.
-     * @return new bitmask after removal of dimensions of the components added to {@code
addTo}.
-     */
-    private static long reduce(int previous, final CoordinateReferenceSystem crs, int dimension,
long selected,
-            final List<CoordinateReferenceSystem> addTo) throws FactoryException
-    {
-        final long current = (Numerics.bitmask(dimension) - 1) << previous;
-        final long intersect = selected & current;
-        if (intersect != 0) {
-            if (intersect == current) {
-                addTo.add(crs);
-                selected &= ~current;
-            } else if (crs instanceof CompoundCRS) {
-                for (final CoordinateReferenceSystem component : ((CompoundCRS) crs).getComponents())
{
-                    dimension = ReferencingUtilities.getDimension(component);
-                    selected = reduce(previous, component, dimension, selected, addTo);
-                    if ((selected & current) == 0) break;           // Stop if it would
be useless to continue.
-                    previous += dimension;
-                }
-            } else if (dimension == 3 && crs instanceof SingleCRS) {
-                final Datum datum = ((SingleCRS) crs).getDatum();
-                if (datum instanceof GeodeticDatum) {
-                    final boolean isVertical = Long.bitCount(intersect) == 1;           
   // Presumed for now, verified later.
-                    final int verticalDimension = Long.numberOfTrailingZeros((isVertical
? intersect : ~intersect) >>> previous);
-                    final CoordinateSystemAxis verticalAxis = crs.getCoordinateSystem().getAxis(verticalDimension);
-                    if (AxisDirections.isVertical(verticalAxis.getDirection())) try {
-                        addTo.add(new EllipsoidalHeightSeparator((GeodeticDatum) datum).separate((SingleCRS)
crs, isVertical));
-                        selected &= ~current;
-                    } catch (IllegalArgumentException | ClassCastException e) {
-                        throw new FactoryException(Resources.format(Resources.Keys.CanNotSeparateCRS_1,
crs.getName()));
-                    }
-                }
-            }
-        }
-        if ((selected & current) != 0) {
-            throw new FactoryException(Resources.format(Resources.Keys.CanNotSeparateCRS_1,
crs.getName()));
-        }
-        return selected;
-    }
-
-    /**
      * Returns the Greenwich longitude of the prime meridian of the given CRS in degrees.
      * If the prime meridian uses an other unit than degrees, then the value will be converted.
      *


Mime
View raw message