You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2019/01/09 10:18:27 UTC

[sis] branch geoapi-4.0 updated: Add a SampleDimension.Builder.remove(String) method.

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


The following commit(s) were added to refs/heads/geoapi-4.0 by this push:
     new 4ec01d8  Add a SampleDimension.Builder.remove(String) method.
4ec01d8 is described below

commit 4ec01d83d5c52cc852498ebe15b7dcbfda1102f9
Author: Martin Desruisseaux <ma...@geomatys.com>
AuthorDate: Wed Jan 9 11:18:04 2019 +0100

    Add a SampleDimension.Builder.remove(String) method.
---
 .../org/apache/sis/coverage/SampleDimension.java   | 41 ++++++++++++++++------
 .../main/java/org/apache/sis/coverage/ToNaN.java   | 31 +++++++++++++---
 .../apache/sis/coverage/SampleDimensionTest.java   | 15 ++++++++
 3 files changed, 73 insertions(+), 14 deletions(-)

diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
index 7cda99c..8bf397f 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/SampleDimension.java
@@ -20,11 +20,12 @@ import java.util.List;
 import java.util.ArrayList;
 import java.util.Set;
 import java.util.TreeSet;
-import java.util.Optional;
+import java.util.Iterator;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.Locale;
 import java.util.Objects;
+import java.util.Optional;
 import java.io.Serializable;
 import javax.measure.Unit;
 import org.opengis.util.GenericName;
@@ -512,11 +513,6 @@ public class SampleDimension implements Serializable {
         private GenericName dimensionName;
 
         /**
-         * The background value, or {@code null} if unspecified.
-         */
-        private Number background;
-
-        /**
          * The categories for the sample dimension to create.
          * This list is modified by the following methods:
          *
@@ -524,6 +520,7 @@ public class SampleDimension implements Serializable {
          *   <li>{@link #setBackground(CharSequence, Number)}</li>
          *   <li>{@link #addQualitative(CharSequence, NumberRange)}</li>
          *   <li>{@link #addQuantitative(CharSequence, NumberRange, MathTransform1D, Unit)}</li>
+         *   <li>{@link #remove(String)}</li>
          *   <li>{@link #clear()}</li>
          * </ul>
          */
@@ -646,8 +643,8 @@ public class SampleDimension implements Serializable {
                 name = Vocabulary.formatInternational(Vocabulary.Keys.FillValue);
             }
             final NumberRange<?> samples = range(sample.getClass(), sample, sample);
-            background = samples.getMinValue();
-            toNaN.background = background.doubleValue();
+            // Use of 'getMinValue()' below shall be consistent with this.remove(…).
+            toNaN.background = samples.getMinValue();
             categories.add(new Category(name, samples, null, null, toNaN));
             return this;
         }
@@ -928,6 +925,31 @@ public class SampleDimension implements Serializable {
         }
 
         /**
+         * Removes and returns the first category having the given name.
+         * Category names are compared using their {@link InternationalString#toString()} representation.
+         * If no category has the given name, then this method returns {@code null}.
+         * If more than one category has the given name, then only the first occurrence is removed.
+         *
+         * @param  name  name of the category to remove.
+         * @return the removed category, or {@code null} if none.
+         *
+         * @see Category#getName()
+         */
+        public Category remove(final String name) {
+            ArgumentChecks.ensureNonNull("name", name);
+            for (final Iterator<Category> it = categories.iterator(); it.hasNext();) {
+                final Category c = it.next();
+                if (name.equals(c.name.toString())) {
+                    it.remove();
+                    // Use of 'c.minimum' shall be consistent with 'this.setBackground(…)'.
+                    toNaN.remove(c.minimum, c.converse.minimum);
+                    return c;
+                }
+            }
+            return null;
+        }
+
+        /**
          * Returns {@code true} if the given range intersects the range of a previously added category.
          * This method can be invoked before to add a new category for checking if it would cause a range collision.
          *
@@ -960,7 +982,7 @@ defName:    if (name == null) {
                 }
                 name = createLocalName(Vocabulary.formatInternational(Vocabulary.Keys.Untitled));
             }
-            return new SampleDimension(name, background, categories);
+            return new SampleDimension(name, toNaN.background, categories);
         }
 
         /**
@@ -970,7 +992,6 @@ defName:    if (name == null) {
          */
         public void clear() {
             dimensionName = null;
-            background    = null;
             categories.clear();
             toNaN.clear();
         }
diff --git a/core/sis-raster/src/main/java/org/apache/sis/coverage/ToNaN.java b/core/sis-raster/src/main/java/org/apache/sis/coverage/ToNaN.java
index ab49274..ea274e8 100644
--- a/core/sis-raster/src/main/java/org/apache/sis/coverage/ToNaN.java
+++ b/core/sis-raster/src/main/java/org/apache/sis/coverage/ToNaN.java
@@ -38,14 +38,14 @@ final class ToNaN extends HashSet<Integer> implements DoubleToIntFunction {
     /**
      * The value which should be assigned ordinal 0 if that ordinal value is available.
      * For performance reason, the background value should be assigned ordinal 0 when possible.
+     * This is {@code null} if unspecified.
      */
-    double background;
+    Number background;
 
     /**
      * To be constructed only from this package.
      */
     ToNaN() {
-        background = Double.NaN;
     }
 
     /**
@@ -55,7 +55,14 @@ final class ToNaN extends HashSet<Integer> implements DoubleToIntFunction {
     @Override
     public void clear() {
         super.clear();
-        background = Double.NaN;
+        background = null;
+    }
+
+    /**
+     * Returns {@code true} if the specified value is the background value.
+     */
+    private boolean isBackground(final double value) {
+        return (background != null) && (value == background.doubleValue());
     }
 
     /**
@@ -68,7 +75,7 @@ final class ToNaN extends HashSet<Integer> implements DoubleToIntFunction {
      */
     @Override
     public int applyAsInt(final double value) {
-        if (value == background && add(0)) {
+        if (isBackground(value) && add(0)) {
             return 0;
         }
         /*
@@ -99,4 +106,20 @@ search: if (!add(ordinal)) {
         }
         return ordinal;
     }
+
+    /**
+     * Removes the NaN value which has been reserved for a qualitative category.
+     * This method does nothing if {@code converted} is not a NaN value, i.e. if
+     * the category is quantitative instead than qualitative.
+     *
+     * @param  value      the real value of the presumed qualitative category.
+     * @param  converted  the converted value, which should be one of NaN values.
+     */
+    void remove(final double value, final double converted) {
+        if (Double.isNaN(converted) && super.remove(MathFunctions.toNanOrdinal((float) converted))) {
+            if (isBackground(value)) {
+                background = null;
+            }
+        }
+    }
 }
diff --git a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
index 913c7f5..95df262 100644
--- a/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
+++ b/core/sis-raster/src/test/java/org/apache/sis/coverage/SampleDimensionTest.java
@@ -113,4 +113,19 @@ public final strictfp class SampleDimensionTest extends TestCase {
         assertSame("forConvertedValues", dimension, dimension.forConvertedValues(true));
         assertSame("forConvertedValues", dimension, dimension.forConvertedValues(false));
     }
+
+    /**
+     * Tests a few builder methods not tested by other methods in this class.
+     */
+    @Test
+    public void testBuilder() {
+        final SampleDimension.Builder builder = new SampleDimension.Builder()
+                .setBackground (null,      0)
+                .addQualitative("Clouds",  1)
+                .addQualitative("Lands", 255);
+        assertEquals(3, builder.categories.size());
+        assertNotNull(builder.remove("Clouds"));
+        assertEquals(2, builder.categories.size());
+        assertNull(builder.remove("Clouds"));
+    }
 }