sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1826327 [5/5] - in /sis/branches/JDK9: ./ application/sis-console/src/main/java/org/apache/sis/console/ core/sis-build-helper/src/main/resources/org/apache/sis/ core/sis-metadata/ core/sis-metadata/src/main/java/org/apache/sis/internal/jax...
Date Fri, 09 Mar 2018 11:00:28 GMT
Modified: sis/branches/JDK9/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/pom.xml?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/pom.xml (original)
+++ sis/branches/JDK9/pom.xml Fri Mar  9 11:00:27 2018
@@ -429,7 +429,7 @@ Apache SIS is a free software, Java lang
       <dependency>
         <groupId>javax</groupId>
         <artifactId>javaee-api</artifactId>
-        <version>7.0</version>
+        <version>8.0</version>
         <scope>provided</scope>
       </dependency>
       <dependency>
@@ -499,7 +499,7 @@ Apache SIS is a free software, Java lang
          The last properties in this list depend on the Apache SIS branch.
        =================================================================== -->
   <properties>
-    <netcdf.version>4.6.10</netcdf.version>
+    <netcdf.version>4.6.11</netcdf.version>
     <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
     <website.encoding>UTF-8</website.encoding>
     <website.locale>en</website.locale>
@@ -579,7 +579,7 @@ Apache SIS is a free software, Java lang
       <plugin>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
-        <version>2.20.1</version>
+        <version>2.21.0</version>
         <configuration>
           <includes>
             <include>**/*TestSuite.java</include>
@@ -875,20 +875,6 @@ Apache SIS is a free software, Java lang
           <relativizeDecorationLinks>false</relativizeDecorationLinks>
         </configuration>
       </plugin>
-
-      <!-- Dependencies requires for the SIS FindBugs configuration file. -->
-      <plugin>
-        <groupId>org.codehaus.mojo</groupId>
-        <artifactId>findbugs-maven-plugin</artifactId>
-        <version>3.0.5</version>
-        <dependencies>
-          <dependency>
-            <groupId>org.apache.sis.core</groupId>
-            <artifactId>sis-build-helper</artifactId>
-            <version>${sis.plugin.version}</version>
-          </dependency>
-        </dependencies>
-      </plugin>
     </plugins>
 
     <!-- Following plugins are used only by some specific modules. -->

Modified: sis/branches/JDK9/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GridGeometry.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GridGeometry.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GridGeometry.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-geotiff/src/main/java/org/apache/sis/storage/geotiff/GridGeometry.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -16,8 +16,14 @@
  */
 package org.apache.sis.storage.geotiff;
 
+import java.util.Arrays;
+import java.util.Set;
+import java.util.Map;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
 import java.util.Collection;
 import java.util.Collections;
+import org.opengis.geometry.Envelope;
 import org.opengis.util.FactoryException;
 import org.opengis.metadata.quality.DataQuality;
 import org.opengis.metadata.spatial.GeolocationInformation;
@@ -25,6 +31,7 @@ import org.opengis.referencing.operation
 import org.opengis.referencing.operation.TransformException;
 import org.opengis.referencing.crs.CoordinateReferenceSystem;
 import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.transform.MathTransforms;
 import org.apache.sis.referencing.operation.transform.LinearTransform;
 import org.apache.sis.referencing.operation.builder.LocalizationGridBuilder;
 import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
@@ -67,7 +74,7 @@ import org.apache.sis.math.Vector;
  * are considered equivalent.
  *
  * @author  Martin Desruisseaux (Geomatys)
- * @version 0.8
+ * @version 1.0
  * @since   0.8
  * @module
  */
@@ -90,34 +97,161 @@ final class GridGeometry extends Abstrac
     GridGeometry(final String name, final CoordinateReferenceSystem crs, final Vector modelTiePoints)
             throws FactoryException, TransformException
     {
-        super(Collections.singletonMap(NAME_KEY, name), null, crs, null, localizationGrid(modelTiePoints));
+        super(Collections.singletonMap(NAME_KEY, name), null, crs, null, localizationGrid(modelTiePoints,
null));
     }
 
     /**
      * Builds a localization grid from the given GeoTIFF tie points.
-     * This is a workaround for RFE #4093999 in Sun's bug database
-     * ("Relax constraint on placement of this()/super() call in constructors").
+     * This method may invoke itself recursively.
+     *
+     * @param  modelTiePoints  the model tie points read from GeoTIFF file.
+     * @param  addTo           if non-null, add the transform result to this map.
      */
-    private static MathTransform localizationGrid(final Vector modelTiePoints) throws FactoryException,
TransformException {
+    private static MathTransform localizationGrid(final Vector modelTiePoints, final Map<Envelope,MathTransform>
addTo)
+            throws FactoryException, TransformException
+    {
         final int size = modelTiePoints.size();
         final int n = size / RECORD_LENGTH;
-        final LocalizationGridBuilder grid = new LocalizationGridBuilder(
-                modelTiePoints.subSampling(0, RECORD_LENGTH, n),
-                modelTiePoints.subSampling(1, RECORD_LENGTH, n));
-
-        final LinearTransform sourceToGrid = grid.getSourceToGrid();
-        final double[] ordinates = new double[2];
-        for (int i=0; i<size; i += RECORD_LENGTH) {
-            ordinates[0] = modelTiePoints.doubleValue(i);
-            ordinates[1] = modelTiePoints.doubleValue(i+1);
-            sourceToGrid.transform(ordinates, 0, ordinates, 0, 1);
-            grid.setControlPoint((int) Math.round(ordinates[0]),
-                                 (int) Math.round(ordinates[1]),
-                                 modelTiePoints.doubleValue(i+3),
-                                 modelTiePoints.doubleValue(i+4));
+        if (n == 0) return null;
+        final Vector x = modelTiePoints.subSampling(0, RECORD_LENGTH, n);
+        final Vector y = modelTiePoints.subSampling(1, RECORD_LENGTH, n);
+        try {
+            final LocalizationGridBuilder grid = new LocalizationGridBuilder(x, y);
+            final LinearTransform sourceToGrid = grid.getSourceToGrid();
+            final double[] ordinates = new double[2];
+            for (int i=0; i<size; i += RECORD_LENGTH) {
+                ordinates[0] = modelTiePoints.doubleValue(i);
+                ordinates[1] = modelTiePoints.doubleValue(i+1);
+                sourceToGrid.transform(ordinates, 0, ordinates, 0, 1);
+                grid.setControlPoint(Math.toIntExact(Math.round(ordinates[0])),
+                                     Math.toIntExact(Math.round(ordinates[1])),
+                                     modelTiePoints.doubleValue(i+3),
+                                     modelTiePoints.doubleValue(i+4));
+            }
+            grid.setDesiredPrecision(PRECISION);
+            final MathTransform tr = grid.create(null);
+            if (addTo != null && addTo.put(grid.getSourceEnvelope(), tr) != null)
{
+                throw new FactoryException();       // Should never happen. If it does, we
have a bug in our algorithm.
+            }
+            return tr;
+        } catch (ArithmeticException | FactoryException e) {
+            /*
+             * May happen when the model tie points are not distributed on a regular grid.
+             * For example Sentinel 1 images may have tie points spaced by 1320 pixels on
the X axis,
+             * except the very last point which is only 1302 pixels after the previous one.
We try to
+             * handle such grids by splitting them in two parts: one grid for the columns
where points
+             * are spaced by 1320 pixels and one grid for the last column. Such splitting
needs to be
+             * done horizontally and vertically, which result in four grids:
+             *
+             *    ┌──────────────────┬───┐
+             *    │                  │   │
+             *    │         0        │ 1 │
+             *    │                  │   │
+             *    ├──────────────────┼───┤
splitY
+             *    │         2        │ 3 │
+             *    └──────────────────┴───┘
+             *                    splitX
+             */
+            final Set<Double> uniques = new HashSet<>(100);
+            final double splitX = threshold(x, uniques);
+            final double splitY = threshold(y, uniques);
+            if (Double.isNaN(splitX) && Double.isNaN(splitY)) {
+                throw e;                                            // Can not do better.
Report the failure.
+            }
+            final int[][] indices = new int[4][size];
+            final int[]   lengths = new int[4];
+            for (int i=0; i<size;) {
+                final double px = modelTiePoints.doubleValue(i  );
+                final double py = modelTiePoints.doubleValue(i+1);
+                int part = 0;                                       // Number of the part
where to add current point.
+                if (px > splitX) part  = 1;                         // Point will be added
to part #1 or #3.
+                if (py > splitY) part |= 2;                         // Point will be added
to part #2 or #3.
+                int parts = 1 << part;                              // Bitmask of the
parts where to add the point.
+                if (px == splitX) parts |= 1 << (part | 1);         // Add also the
point to part #1 or #3.
+                if (py == splitY) parts |= 1 << (part | 2);         // Add also the
point to part #2 or #3.
+                if (parts == 0b0111) {
+                    parts = 0b1111;                                 // Add also the point
to part #3.
+                    assert px == splitX && py == splitY;
+                }
+                final int upper = i + RECORD_LENGTH;
+                do {
+                    part = Integer.numberOfTrailingZeros(parts);
+                    @SuppressWarnings("MismatchedReadAndWriteOfArray")
+                    final int[] tileIndices = indices[part];
+                    int k = lengths[part];
+                    for (int j=i; j<upper; j++) {
+                        tileIndices[k++] = j;
+                    }
+                    lengths[part] = k;
+                } while ((parts &= ~(1 << part)) != 0);            // Clear the
bit of the part we processed.
+                i = upper;
+            }
+            /*
+             * At this point, we finished to collect indices of the points to use for parts
#0, 1, 2 and 3.
+             * Verify that each part has less points than the initial vector (otherwise it
would be a bug),
+             * and identify which part is the biggest one. This is usually part #0.
+             */
+            int maxLength   = 0;
+            int largestPart = 0;
+            for (int i=0; i<indices.length; i++) {
+                final int length = lengths[i];
+                if (length >= size) throw e;                        // Safety against
infinite recursivity.
+                indices[i] = Arrays.copyOf(indices[i], length);
+                if (length > maxLength) {
+                    maxLength = length;
+                    largestPart = i;
+                }
+            }
+            /*
+             * The biggest part will define the global transform. All other parts will define
a specialization
+             * valid only in a sub-area. Put those information in a map for MathTransforms.specialize(…).
+             */
+            MathTransform global = null;
+            final Map<Envelope,MathTransform> specialization = new LinkedHashMap<>(4);
+            for (int i=0; i<indices.length; i++) {
+                final Vector sub = modelTiePoints.pick(indices[i]);
+                if (i == largestPart) {
+                    global = localizationGrid(sub, null);
+                } else {
+                    localizationGrid(sub, specialization);
+                }
+            }
+            return MathTransforms.specialize(global, specialization);
+        }
+    }
+
+    /**
+     * Finds the value at which the increment in localization grid seems to change.
+     * This is used when not all tie points in a GeoTIFF images are distributed on
+     * a regular grid (e.g. Sentinel 1 image). This method tells where to split in
+     * two grids.
+     *
+     * @param  values   the x or y vector of tie points pixel coordinates.
+     * @param  uniques  an initially empty set to be used for this method internal working.
+     * @return value after which a different step is used, or {@code NaN} if none.
+     *         The value returned by this method should be included in the first grid.
+     */
+    private static double threshold(final Vector values, final Set<Double> uniques)
{
+        final int n = values.size();
+        for (int i=0; i<n; i++) {
+            uniques.add(values.doubleValue(i));
+        }
+        final Double[] array = uniques.toArray(new Double[uniques.size()]);
+        uniques.clear();
+        int i = array.length;
+        if (i >= 3) {
+            Arrays.sort(array);
+            double value;
+            final double inc = array[--i] - (value = array[--i]);
+            do {
+                final double lower = array[--i];
+                if (value - lower != inc) {
+                    return value;
+                }
+                value = lower;
+            } while (i > 0);
         }
-        grid.setDesiredPrecision(PRECISION);
-        return grid.create(null);
+        return Double.NaN;
     }
 
     /**

Modified: sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/internal/storage/MetadataBuilder.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -2625,13 +2625,14 @@ parse:      for (int i = 0; i < length;)
 
     /**
      * Adds a URL to a more complete description of the metadata.
+     * Storage location is:
      *
      * <ul>
      *   <li>{@code metadata/metadataLinkage/linkage}
      *     with {@code function} set to {@link OnLineFunction#COMPLETE_METADATA}</li>
      * </ul>
      *
-     * @param  link
+     * @param  link  URL to a more complete description of the metadata, or {@code null}.
      */
     public final void addCompleteMetadata(final URI link) {
         if (link != null) {

Modified: sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-storage/src/main/java/org/apache/sis/storage/Resource.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -41,7 +41,7 @@ import org.opengis.metadata.Metadata;
  * </div>
  *
  * @author  Johann Sorel (Geomatys)
- * @version 0.8
+ * @version 1.0
  *
  * @see Aggregate#components()
  *
@@ -103,4 +103,46 @@ public interface Resource {
      * @see DataStore#getMetadata()
      */
     Metadata getMetadata() throws DataStoreException;
+
+    /**
+     * Registers a listener that is notified each time a change occurs in the resource content
or structure.
+     * The resource will call the {@link ChangeListener#changeOccured(ChangeEvent)}
+     * method when a new event matching the {@code eventType} is produced.
+     *
+     * <p>Registering a listener for a given {@code eventType} also register the listener
for all sub-types.
+     * The same listener can be added multiple times for different even type.
+     * Adding many times the same listener with the same even type has no effect:
+     * the listener will only be called once per event.</p>
+     *
+     * @todo When adding a listener to an aggregate, should the listener be added to all
components?
+     *       In other words, should listeners in a tree node also listen to events from all
children?
+     *
+     * <p>The resource is not required to keep a reference to the listener.
+     * For example the resource may discard a listener if no event of the given type happen
on this resource.</p>
+     *
+     * @param  <T>        compile-time value of the {@code eventType} argument.
+     * @param  listener   listener to notify about changes.
+     * @param  eventType  type of {@linkplain ChangeEvent} to listen (can not be {@code null}).
+     */
+    //TODO: remove comment when implemented on all resources.
+    //<T extends ChangeEvent> void addListener(ChangeListener<? super T> listener,
Class<T> eventType);
+
+    /**
+     * Unregisters a listener previously added to this resource for the given type of events.
+     * The {@code eventType} must be the exact same class than the one given to the {@code
addListener(…)} method.
+     *
+     * <div class="note"><b>Example:</b>
+     * if the same listener has been added for {@code ChangeEvent} and {@code StructuralChangeEvent},
that listener
+     * will be notified only once for all {@code ChangeEvent}s. If that listener is removed
for {@code ChangeEvent},
+     * then the listener will still receive {@code StructuralChangeEvent}s.</div>
+     *
+     * <p>Calling multiple times this method with the same listener and event type
or a listener
+     * which is unknown to this resource will have no effect and will not raise an exception.</p>
+     *
+     * @param  <T>        compile-time value of the {@code eventType} argument.
+     * @param  listener   listener to stop notifying about changes.
+     * @param  eventType  type of {@linkplain ChangeEvent} which were listened (can not be
{@code null}).
+     */
+    //TODO: remove comment when implemented on all resources.
+    //<T extends ChangeEvent> void removeListener(ChangeListener<? super T> listener,
Class<T> eventType);
 }

Modified: sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/StoreTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/StoreTest.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/StoreTest.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/xml/StoreTest.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -24,6 +24,7 @@ import org.opengis.metadata.citation.*;
 import org.apache.sis.xml.Namespaces;
 import org.apache.sis.storage.StorageConnector;
 import org.apache.sis.storage.DataStoreException;
+import org.apache.sis.internal.jaxb.LegacyNamespaces;
 import org.apache.sis.test.DependsOn;
 import org.apache.sis.test.TestCase;
 import org.junit.Test;
@@ -49,8 +50,8 @@ public final strictfp class StoreTest ex
     public static final String XML =
             "<?xml version=\"1.0\" standalone=\"yes\"?>\n" +
             "<gmd:MD_Metadata\n" +
-            "  xmlns:gmd = \"" + Namespaces.GMD + "\"\n"  +
-            "  xmlns:gco = \"" + Namespaces.GCO + "\"\n"  +
+            "  xmlns:gmd = \"" + LegacyNamespaces.GMD + "\"\n"  +
+            "  xmlns:gco = \"" + LegacyNamespaces.GCO + "\"\n"  +
             "  xmlns:xsi = \"" + Namespaces.XSI + "\"\n>" +
             "  <gmd:language>\n" +
             "    <gmd:LanguageCode codeListValue=\"eng\">English</gmd:LanguageCode>\n"
+

Modified: sis/branches/JDK9/storage/sis-xmlstore/pom.xml
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/pom.xml?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/pom.xml (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/pom.xml Fri Mar  9 11:00:27 2018
@@ -117,6 +117,15 @@ Read and write files in the GPX format.
       <artifactId>esri-geometry-api</artifactId>
       <scope>test</scope>
     </dependency>
+
+    <!-- Test dependencies -->
+    <dependency>
+      <groupId>org.apache.sis.core</groupId>
+      <artifactId>sis-metadata</artifactId>
+      <version>${project.version}</version>
+      <type>test-jar</type>
+      <scope>test</scope>
+    </dependency>
   </dependencies>
 
 </project>

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/FormattedWriter.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/FormattedWriter.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/FormattedWriter.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/FormattedWriter.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -19,7 +19,6 @@ package org.apache.sis.internal.storage.
 import java.util.Arrays;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.stream.XMLStreamException;
-import org.apache.sis.internal.util.StreamWriterDelegate;
 
 
 /**

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/NamespaceEraser.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/NamespaceEraser.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/NamespaceEraser.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/main/java/org/apache/sis/internal/storage/xml/stream/NamespaceEraser.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -19,7 +19,6 @@ package org.apache.sis.internal.storage.
 import javax.xml.XMLConstants;
 import javax.xml.stream.XMLStreamWriter;
 import javax.xml.stream.XMLStreamException;
-import org.apache.sis.internal.util.StreamWriterDelegate;
 
 
 /**

Modified: sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java?rev=1826327&r1=1826326&r2=1826327&view=diff
==============================================================================
--- sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
[UTF-8] (original)
+++ sis/branches/JDK9/storage/sis-xmlstore/src/test/java/org/apache/sis/internal/storage/gpx/WriterTest.java
[UTF-8] Fri Mar  9 11:00:27 2018
@@ -36,7 +36,7 @@ import org.junit.BeforeClass;
 import org.junit.AfterClass;
 import org.junit.Test;
 
-import static org.apache.sis.test.Assert.*;
+import static org.apache.sis.test.MetadataAssert.*;
 
 // Branch-dependent imports
 import org.opengis.feature.Feature;



Mime
View raw message