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 2013/11/08 23:27:49 UTC
svn commit: r1540210 [1/2] - in /sis/trunk: ./
application/sis-console/src/main/resources/org/apache/sis/console/
core/sis-metadata/src/main/java/org/apache/sis/metadata/
core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/
core/sis-meta...
Author: desruisseaux
Date: Fri Nov 8 22:27:48 2013
New Revision: 1540210
URL: http://svn.apache.org/r1540210
Log:
Merge from the JDK6 branch.
Added:
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
- copied unchanged from r1540209, sis/branches/JDK6/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentificationTest.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
- copied unchanged from r1540209, sis/branches/JDK6/core/sis-utility/src/main/java/org/apache/sis/math/DecimalFunctions.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
- copied unchanged from r1540209, sis/branches/JDK6/core/sis-utility/src/test/java/org/apache/sis/math/DecimalFunctionsTest.java
Modified:
sis/trunk/ (props changed)
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java
sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/MathFunctions.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/math/StatisticsFormat.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/AngleFormat.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/measure/Units.java
sis/trunk/core/sis-utility/src/main/java/org/apache/sis/util/Numbers.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/util/DoubleDoubleTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/internal/util/NumericsTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/math/MathFunctionsTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/math/StatisticsTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/measure/UnitsTest.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/TestUtilities.java
sis/trunk/core/sis-utility/src/test/java/org/apache/sis/test/suite/UtilityTestSuite.java
sis/trunk/storage/sis-netcdf/src/test/java/org/apache/sis/storage/netcdf/MetadataReaderTest.java
Propchange: sis/trunk/
------------------------------------------------------------------------------
Merged /sis/branches/JDK7:r1535870-1540208
Merged /sis/branches/JDK6:r1535871-1540209
Modified: sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties [ISO-8859-1] (original)
+++ sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options.properties [ISO-8859-1] Fri Nov 8 22:27:48 2013
@@ -4,6 +4,6 @@ locale=The locale to use for the command
timezone=The timezone for the dates to be formatted.
encoding=The encoding to use for the command output.
colors=Whether colorized output shall be enabled.
-brief=Whether the output should contains only brief information.
-verbose=Whether the output should contains more detailed information.
+brief=Reduce the output to only brief information.
+verbose=Request the output to contain more detailed information.
help=Lists the options available for a specific command.
Modified: sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties
URL: http://svn.apache.org/viewvc/sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties [ISO-8859-1] (original)
+++ sis/trunk/application/sis-console/src/main/resources/org/apache/sis/console/Options_fr.properties [ISO-8859-1] Fri Nov 8 22:27:48 2013
@@ -4,6 +4,6 @@ locale=Les paramètres régionaux à uti
timezone=Le fuseau horaire des dates à écrire.
encoding=L\u2019encodage des caractères à utiliser pour la sortie de la commande.
colors=Indique si l\u2019affichage peut être en couleurs.
-brief=Indique si la sortie de la commande ne doit contenir que de brèves informations.
-verbose=Indique si la sortie de la commande doit contenir des informations plus détaillées.
+brief=Indique que la sortie de la commande ne doit contenir que de brèves informations.
+verbose=Indique que la sortie de la commande doit contenir des informations plus détaillées.
help=Liste les options disponibles pour une commande spécifique.
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/PropertyComparator.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -18,7 +18,7 @@ package org.apache.sis.metadata;
import java.util.Comparator;
import java.util.Map;
-import java.util.IdentityHashMap;
+import java.util.HashMap;
import java.lang.reflect.Method;
import javax.xml.bind.annotation.XmlType;
@@ -43,7 +43,7 @@ import org.opengis.annotation.Obligation
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.4
* @module
*/
final class PropertyComparator implements Comparator<Method> {
@@ -63,29 +63,51 @@ final class PropertyComparator implement
static final String SET = "set";
/**
- * Methods specified in the {@link XmlType} annotation, or {@code null} if none.
- */
- private final String[] order;
-
- /**
- * Indices of methods in the {@link #order} array, created when first needed.
+ * Methods and property names specified in the {@link XmlType} annotation.
+ * Entries description:
+ *
+ * <ul>
+ * <li>Keys in this map are either {@link String} or {@link Method} instances:
+ * <ul>
+ * <li>{@code String} keys property names as given by {@link XmlType#propOrder()}.
+ * They are computed at construction time and do not change after construction.</li>
+ * <li>{@code Method} keys will be added after construction, only as needed.</li>
+ * </ul>
+ * </li>
+ *
+ * <li>Key is associated to an index that specify its position in descending order.
+ * For example the property associated to integer 0 shall be sorted last.
+ * This descending order is only an implementation convenience.</li>
+ * </ul>
*/
- private Map<Method,Integer> indices;
+ private final Map<Object,Integer> order;
/**
* Creates a new comparator for the given implementation class.
*
* @param implementation The implementation class, or {@code null} if unknown.
*/
- PropertyComparator(final Class<?> implementation) {
- if (implementation != null) {
+ PropertyComparator(Class<?> implementation) {
+ order = new HashMap<Object,Integer>();
+ while (implementation != null) {
final XmlType xml = implementation.getAnnotation(XmlType.class);
if (xml != null) {
- order = xml.propOrder();
- return;
+ final String[] propOrder = xml.propOrder();
+ for (int i=propOrder.length; --i>=0;) {
+ /*
+ * Add the entries in reverse order because we are iterating from the child class to
+ * the parent class, and we want the properties in the parent class to be sorted first.
+ * If duplicated properties are found, keep the first occurence (i.e. sort the property
+ * with the most specialized child that declared it).
+ */
+ final Integer old = order.put(propOrder[i], order.size());
+ if (old != null) {
+ order.put(propOrder[i], old);
+ }
+ }
}
+ implementation = implementation.getSuperclass();
}
- order = null;
}
/**
@@ -93,7 +115,7 @@ final class PropertyComparator implement
*/
@Override
public int compare(final Method m1, final Method m2) {
- int c = indexOf(m1) - indexOf(m2);
+ int c = indexOf(m2) - indexOf(m1); // indexOf(…) are sorted in descending order.
if (c == 0) {
final UML a1 = m1.getAnnotation(UML.class);
final UML a2 = m2.getAnnotation(UML.class);
@@ -131,30 +153,21 @@ final class PropertyComparator implement
}
/**
- * Returns the index of the given method, or {@code order.length} if the method is not found.
+ * Returns the index of the given method, or -1 if the method is not found.
+ * If positive, the index returned by this method correspond to a sorting in descending order.
*/
private int indexOf(final Method method) {
- int i = 0;
- if (order != null) {
- if (indices == null) {
- indices = new IdentityHashMap<Method,Integer>();
- } else {
- Integer index = indices.get(method);
- if (index != null) {
- return index;
- }
- }
+ Integer index = order.get(method);
+ if (index == null) {
String name = method.getName();
name = toPropertyName(name, prefix(name).length());
- while (i < order.length) {
- if (name.equals(order[i])) {
- break;
- }
- i++;
+ index = order.get(name);
+ if (index == null) {
+ index = -1;
}
- indices.put(method, i);
+ order.put(method, index);
}
- return i;
+ return index;
}
/**
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -71,11 +71,26 @@ import org.apache.sis.internal.jdk7.Obje
* {@linkplain #getEastBoundLongitude() east bound longitude}, then the box spans the anti-meridian.
* See {@linkplain org.apache.sis.geometry.GeneralEnvelope} for more information on anti-meridian spanning.
*
+ * <blockquote><font size="-1"><b>Note: relationship with Envelope classes</b><br>
+ * The {@link org.apache.sis.geometry} package provides various {@code Envelope} classes serving a simular purpose.
+ * The main difference is that envelopes can be expressed in any {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+ * Coordinate Reference System} (for example using any map projection), may have any number of dimensions, axes may have
+ * any {@linkplain org.apache.sis.referencing.cs.DefaultCoordinateSystemAxis#getDirection() direction} (some maps are south-oriented)
+ * and may use any units of measurement. By contrast, geographic bounding box are restricted to two-dimensional
+ * geographic CRS with latitude and longitude in decimal degrees, inside the [-90 … +90]° and [-180 … +180]° range
+ * respectively, increasing toward north and east respectively, and longitude measured from the <cite>international
+ * reference meridian</cite> (Greenwich on Earth). However {@code GeographicBoundingBox} said nothing about the
+ * {@linkplain org.apache.sis.referencing.datum.DefaultGeodeticDatum geodetic datum}. Consequently this bounding
+ * box should be used only as a convenient way to give an <em>approximate</em> description of a location.
+ * Users can assume a precision of about 0.01° for the latitude and longitude values in this class.
+ * If more precision is desired, an {@code Envelope} should be considered instead.
+ * </font></blockquote>
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Touraïvane (IRD)
* @author Cédric Briançon (Geomatys)
* @since 0.3 (derived from geotk-2.1)
- * @version 0.3
+ * @version 0.4
* @module
*
* @see org.apache.sis.geometry.GeneralEnvelope
Modified: sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/identification/DefaultDataIdentification.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -115,7 +115,7 @@ public class DefaultDataIdentification e
* @param topicCategory The main theme of the dataset, or {@code null} if none.
*/
public DefaultDataIdentification(final Citation citation,
- final InternationalString abstracts,
+ final CharSequence abstracts,
final Locale language,
final TopicCategory topicCategory)
{
Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/PropertyAccessorTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -31,6 +31,11 @@ import org.opengis.metadata.citation.Cit
import org.opengis.metadata.citation.CitationDate;
import org.opengis.metadata.citation.PresentationForm;
import org.opengis.metadata.citation.ResponsibleParty;
+import org.opengis.metadata.distribution.Format;
+import org.opengis.metadata.constraint.Constraints;
+import org.opengis.metadata.identification.*; // Really using almost everything.
+import org.opengis.metadata.maintenance.MaintenanceInformation;
+import org.opengis.metadata.spatial.SpatialRepresentationType;
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.ReferenceSystem;
import org.opengis.referencing.ReferenceIdentifier;
@@ -45,6 +50,7 @@ import org.apache.sis.util.ComparisonMod
import org.apache.sis.util.iso.SimpleInternationalString;
import org.apache.sis.metadata.iso.citation.DefaultCitation;
import org.apache.sis.metadata.iso.citation.HardCodedCitations;
+import org.apache.sis.metadata.iso.identification.DefaultDataIdentification;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
@@ -70,7 +76,7 @@ import static org.apache.sis.metadata.Pr
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.3 (derived from geotk-2.4)
- * @version 0.3
+ * @version 0.4
* @module
*/
@DependsOn(PropertyInformationTest.class)
@@ -174,6 +180,39 @@ public final strictfp class PropertyAcce
}
/**
+ * Tests the constructor with the {@link DefaultDataIdentification} implementation.
+ * The purpose of this test is to ensure that the properties defined in the parent
+ * class are sorted first.
+ */
+ @Test
+ @DependsOnMethod("testConstructor")
+ public void testConstructorWithInheritance() {
+ assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO_19115, DataIdentification.class, DefaultDataIdentification.class),
+ //……Declaring type………………………Method………………………………………………………………………JavaBeans………………………………………………………UML identifier………………………………………Sentence……………………………………………………………Type………………………………………………………………
+ Identification.class, "getCitation", "citation", "citation", "Citation", Citation.class,
+ Identification.class, "getAbstract", "abstract", "abstract", "Abstract", InternationalString.class,
+ Identification.class, "getPurpose", "purpose", "purpose", "Purpose", InternationalString.class,
+ Identification.class, "getCredits", "credits", "credit", "Credits", String[].class,
+ Identification.class, "getStatus", "status", "status", "Status", Progress[].class,
+ Identification.class, "getPointOfContacts", "pointOfContacts", "pointOfContact", "Point of contacts", ResponsibleParty[].class,
+ Identification.class, "getResourceMaintenances", "resourceMaintenances", "resourceMaintenance", "Resource maintenances", MaintenanceInformation[].class,
+ Identification.class, "getGraphicOverviews", "graphicOverviews", "graphicOverview", "Graphic overviews", BrowseGraphic[].class,
+ Identification.class, "getResourceFormats", "resourceFormats", "resourceFormat", "Resource formats", Format[].class,
+ Identification.class, "getDescriptiveKeywords", "descriptiveKeywords", "descriptiveKeywords", "Descriptive keywords", Keywords[].class,
+ Identification.class, "getResourceSpecificUsages", "resourceSpecificUsages", "resourceSpecificUsage", "Resource specific usages", Usage[].class,
+ Identification.class, "getResourceConstraints", "resourceConstraints", "resourceConstraints", "Resource constraints", Constraints[].class,
+ Identification.class, "getAggregationInfo", "aggregationInfo", "aggregationInfo", "Aggregation info", AggregateInformation[].class,
+ DataIdentification.class, "getSpatialRepresentationTypes", "spatialRepresentationTypes", "spatialRepresentationType", "Spatial representation types", SpatialRepresentationType[].class,
+ DataIdentification.class, "getSpatialResolutions", "spatialResolutions", "spatialResolution", "Spatial resolutions", Resolution[].class,
+ DataIdentification.class, "getLanguages", "languages", "language", "Languages", Locale[].class,
+ DataIdentification.class, "getCharacterSets", "characterSets", "characterSet", "Character sets", CharacterSet[].class,
+ DataIdentification.class, "getTopicCategories", "topicCategories", "topicCategory", "Topic categories", TopicCategory[].class,
+ DataIdentification.class, "getEnvironmentDescription", "environmentDescription", "environmentDescription", "Environment description", InternationalString.class,
+ DataIdentification.class, "getExtents", "extents", "extent", "Extents", Extent[].class,
+ DataIdentification.class, "getSupplementalInformation", "supplementalInformation", "supplementalInformation", "Supplemental information", InternationalString.class);
+ }
+
+ /**
* Tests the constructor with a method which override an other method with covariant
* return type. This test may need to be updated if a future GeoAPI release modifies
* the {@link GeographicCRS} interface.
@@ -181,7 +220,7 @@ public final strictfp class PropertyAcce
* @see <a href="http://jira.geotoolkit.org/browse/GEOTK-205">GEOTK-205</a>
*/
@Test
- @DependsOnMethod("testConstructor")
+ @DependsOnMethod("testConstructorWithInheritance")
public void testConstructorWithCovariantReturnType() {
final Class<?> type = GeographicCRS.class;
assertMappingEquals(new PropertyAccessor(HardCodedCitations.ISO, type, type),
Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/metadata/TreeTableFormatTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -195,12 +195,13 @@ public final strictfp class TreeTableFor
final String text = format.format(identification.asTreeTable());
assertMultilinesEquals(
"Data identification\n" +
+ " ├─Descriptive keywords\n" +
+ " │ ├─Keyword (1 of 3)…………… Apple\n" +
+ " │ ├─Keyword (2 of 3)…………… Orange\n" +
+ " │ └─Keyword (3 of 3)…………… Kiwi\n" +
" ├─Topic category (1 of 3)…… Health\n" +
" ├─Topic category (2 of 3)…… Oceans\n" +
- " ├─Topic category (3 of 3)…… Test\n" +
- " └─Descriptive keywords\n" +
- " ├─Keyword (1 of 3)…………… Apple\n" +
- " ├─Keyword (2 of 3)…………… Orange\n" +
- " └─Keyword (3 of 3)…………… Kiwi\n", text);
+ " └─Topic category (3 of 3)…… Test\n",
+ text);
}
}
Modified: sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] (original)
+++ sis/trunk/core/sis-metadata/src/test/java/org/apache/sis/test/suite/MetadataTestSuite.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -31,17 +31,6 @@ import org.junit.BeforeClass;
*/
@Suite.SuiteClasses({
org.apache.sis.internal.metadata.MetadataUtilitiesTest.class,
- org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
- org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
- org.apache.sis.metadata.iso.identification.DefaultKeywordsTest.class,
- org.apache.sis.metadata.iso.identification.DefaultRepresentativeFractionTest.class,
- org.apache.sis.metadata.iso.identification.DefaultResolutionTest.class,
- org.apache.sis.metadata.iso.identification.DefaultBrowseGraphicTest.class,
- org.apache.sis.metadata.iso.spatial.DefaultGeorectifiedTest.class,
- org.apache.sis.metadata.iso.maintenance.DefaultScopeDescriptionTest.class,
- org.apache.sis.metadata.iso.quality.AbstractElementTest.class,
- org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBoxTest.class,
- org.apache.sis.metadata.iso.extent.ExtentsTest.class,
// Classes using Java reflection.
org.apache.sis.metadata.PropertyInformationTest.class,
@@ -58,8 +47,6 @@ import org.junit.BeforeClass;
org.apache.sis.metadata.MetadataStandardTest.class,
org.apache.sis.metadata.PrunerTest.class,
org.apache.sis.metadata.AbstractMetadataTest.class,
- org.apache.sis.metadata.iso.ImmutableIdentifierTest.class,
- org.apache.sis.metadata.iso.AllMetadataTest.class,
// XML marshalling.
org.apache.sis.internal.jaxb.code.CodeListMarshallingTest.class,
@@ -69,6 +56,24 @@ import org.junit.BeforeClass;
org.apache.sis.xml.NilReasonMarshallingTest.class,
org.apache.sis.xml.AnchorMarshallingTest.class,
org.apache.sis.xml.ObjectReferenceMarshallingTest.class,
+
+ // ISO implementations.
+ org.apache.sis.metadata.iso.citation.DefaultCitationDateTest.class,
+ org.apache.sis.metadata.iso.citation.DefaultCitationTest.class,
+ org.apache.sis.metadata.iso.maintenance.DefaultScopeDescriptionTest.class,
+ org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBoxTest.class,
+ org.apache.sis.metadata.iso.extent.ExtentsTest.class,
+ org.apache.sis.metadata.iso.spatial.DefaultGeorectifiedTest.class,
+ org.apache.sis.metadata.iso.identification.DefaultKeywordsTest.class,
+ org.apache.sis.metadata.iso.identification.DefaultRepresentativeFractionTest.class,
+ org.apache.sis.metadata.iso.identification.DefaultResolutionTest.class,
+ org.apache.sis.metadata.iso.identification.DefaultBrowseGraphicTest.class,
+ org.apache.sis.metadata.iso.identification.DefaultDataIdentificationTest.class,
+ org.apache.sis.metadata.iso.quality.AbstractElementTest.class,
+ org.apache.sis.metadata.iso.ImmutableIdentifierTest.class,
+ org.apache.sis.metadata.iso.AllMetadataTest.class,
+
+ // XML marshalling (integration tests).
org.apache.sis.xml.CustomMetadataTest.class,
org.apache.sis.xml.ImageryMarshallingTest.class,
org.apache.sis.xml.MetadataMarshallingTest.class
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Convention.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -246,36 +246,6 @@ public enum Convention {
}
/**
- * Returns the citation for the organization, standard of project that defines this convention.
- *
- * @return The organization, standard or project that defines this convention.
- *
- * @see WKTFormat#getAuthority()
- */
- public Citation getAuthority() {
- return authority;
- }
-
- /**
- * If non-null, {@code PRIMEM} and {@code PARAMETER} values shall unconditionally use the returned units.
- * The standard value is {@code null}, which means that units are inferred from the context as required by the
- * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html#PRIMEM">WKT specification</a>.
- * However some conventions ignore the above WKT specification and use hard-coded units instead.
- *
- * @param <T> The compile-time type specified by the {@code quantity} argument.
- * @param quantity The kind of quantity for which to get the unit.
- * The most typical value for this argument is <code>{@linkplain Angle}.class</code>.
- * @return The unit to use for the given kind of quantity, or {@code null} for inferring the unit in the standard way.
- */
- @SuppressWarnings("unchecked")
- public <T extends Quantity> Unit<T> getForcedUnit(final Class<T> quantity) {
- if (quantity == Angle.class) {
- return (Unit) forcedAngularUnit;
- }
- return null;
- }
-
- /**
* Returns the convention for the organization, standard or project specified by the given citation.
*
* @param authority The organization, standard or project for which to get the convention, or {@code null}.
@@ -314,6 +284,36 @@ public enum Convention {
}
/**
+ * Returns the citation for the organization, standard of project that defines this convention.
+ *
+ * @return The organization, standard or project that defines this convention.
+ *
+ * @see WKTFormat#getAuthority()
+ */
+ public Citation getAuthority() {
+ return authority;
+ }
+
+ /**
+ * If non-null, {@code PRIMEM} and {@code PARAMETER} values shall unconditionally use the returned units.
+ * The standard value is {@code null}, which means that units are inferred from the context as required by the
+ * <a href="http://www.geoapi.org/3.0/javadoc/org/opengis/referencing/doc-files/WKT.html#PRIMEM">WKT specification</a>.
+ * However some conventions ignore the above WKT specification and use hard-coded units instead.
+ *
+ * @param <T> The compile-time type specified by the {@code quantity} argument.
+ * @param quantity The kind of quantity for which to get the unit.
+ * The most typical value for this argument is <code>{@linkplain Angle}.class</code>.
+ * @return The unit to use for the given kind of quantity, or {@code null} for inferring the unit in the standard way.
+ */
+ @SuppressWarnings("unchecked")
+ public <T extends Quantity> Unit<T> getForcedUnit(final Class<T> quantity) {
+ if (quantity == Angle.class) {
+ return (Unit) forcedAngularUnit;
+ }
+ return null;
+ }
+
+ /**
* Makes the given coordinate system conform to this convention. This method is used mostly
* for converting between the legacy (OGC 01-009) {@link GeocentricCRS} axis directions,
* and the new (ISO 19111) directions. Those directions are:
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/io/wkt/Formatter.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -39,7 +39,7 @@ import org.opengis.referencing.operation
import org.opengis.util.CodeList;
import org.apache.sis.measure.Units;
-import org.apache.sis.math.MathFunctions;
+import org.apache.sis.math.DecimalFunctions;
import org.apache.sis.util.Numbers;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.ArgumentChecks;
@@ -705,7 +705,7 @@ public class Formatter {
* a unit conversion). In the case of WGS84 semi-major axis in metres, we still have a
* maximum of 8 fraction digits, which is more than enough.
*/
- numberFormat.setMaximumFractionDigits(MathFunctions.fractionDigitsForValue(number) - 2);
+ numberFormat.setMaximumFractionDigits(DecimalFunctions.fractionDigitsForValue(number) - 2);
numberFormat.setMinimumFractionDigits(1); // Must be after setMaximumFractionDigits(…).
numberFormat.format(number, buffer, dummy);
resetColor();
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/BursaWolfParameters.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -27,10 +27,12 @@ import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.util.Immutable;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.util.Numerics;
+import org.apache.sis.internal.util.DoubleDouble;
import org.apache.sis.referencing.IdentifiedObjects;
import static java.lang.Math.PI;
import static java.lang.Math.abs;
+import static org.apache.sis.util.ArgumentChecks.*;
import static org.apache.sis.referencing.operation.matrix.Matrix4.SIZE;
// Related to JDK7
@@ -159,7 +161,7 @@ public class BursaWolfParameters extends
/**
* The conversion factor from <cite>parts per million</cite> to scale minus one.
*/
- private static final double PPM = 1E+6;
+ static final double PPM = 1E+6;
/**
* The conversion factor from arc-seconds to radians.
@@ -247,6 +249,20 @@ public class BursaWolfParameters extends
this.rZ = rZ;
this.dS = dS;
this.targetDatum = targetDatum;
+ verify();
+ }
+
+ /**
+ * Verifies parameters validity after construction.
+ */
+ private void verify() {
+ ensureFinite("tX", tX);
+ ensureFinite("tY", tY);
+ ensureFinite("tZ", tZ);
+ ensureFinite("rX", rX);
+ ensureFinite("rY", rY);
+ ensureFinite("rZ", rZ);
+ ensureBetween("dS", -PPM, PPM, dS); // For preventing zero or negative value on the matrix diagonal.
}
/**
@@ -264,7 +280,7 @@ public class BursaWolfParameters extends
* @param targetDatum The target datum (usually WGS 84) for this set of parameters, or {@code null} if unspecified.
* @throws IllegalArgumentException if the specified matrix does not meet the conditions.
*
- * @see #getPositionVectorTransformation(boolean)
+ * @see #getPositionVectorTransformation()
*/
public BursaWolfParameters(final Matrix matrix, final double tolerance, final GeodeticDatum targetDatum)
throws IllegalArgumentException
@@ -309,6 +325,7 @@ public class BursaWolfParameters extends
this.rY = rY;
this.rZ = rZ;
this.targetDatum = targetDatum;
+ verify();
}
/**
@@ -362,25 +379,46 @@ public class BursaWolfParameters extends
* This is identified as operation method 1033 in the EPSG database.
*
* {@section Inverse transformation}
- * The inverse transformation can be computed by reversing the sign of the 7 parameters before to use
- * them in the above matrix. Note that both the direct and inverse transformations are approximations.
- * Multiplication of direct and inverse transformation matrices results in a matrix close to the identity,
- * but not necessarily strictly equals.
+ * The inverse transformation can be approximated by reversing the sign of the 7 parameters before to use them
+ * in the above matrix. This is often considered sufficient since <cite>position vector transformations</cite>
+ * are themselves approximations. However Apache SIS will rather use
+ * {@link org.apache.sis.referencing.operation.matrix.MatrixSIS#inverse()} in order to increase the chances
+ * that concatenation of transformations <var>A</var> → <var>B</var> followed by <var>B</var> → <var>A</var>
+ * gives back the identity transform.
*
- * @param inverse If {@code true}, returns the inverse transformation instead.
* @return An affine transform in geocentric space created from this Bursa-Wolf parameters.
*
* @see DefaultGeodeticDatum#getPositionVectorTransformation(GeodeticDatum)
*/
- public Matrix getPositionVectorTransformation(final boolean inverse) {
- final double sgn = inverse ? -1 : +1;
- final double S = 1 + sgn*dS / PPM;
- final double RS = sgn*TO_RADIANS * S;
- return new Matrix4(
- S, -rZ*RS, +rY*RS, sgn*tX,
- +rZ*RS, S, -rX*RS, sgn*tY,
- -rY*RS, +rX*RS, S, sgn*tZ,
- 0, 0, 0, 1);
+ public Matrix getPositionVectorTransformation() {
+ if (isTranslation()) {
+ final Matrix4 matrix = new Matrix4();
+ matrix.m03 = tX;
+ matrix.m13 = tY;
+ matrix.m13 = tZ;
+ return matrix;
+ }
+ /*
+ * Above was an optimization for the common case where the Bursa-Wolf parameters contain only
+ * translation terms. If we have rotation or scale terms, then use double-double arithmetic.
+ */
+ final DoubleDouble RS = DoubleDouble.createSecondsToRadians();
+ final DoubleDouble S = new DoubleDouble(dS);
+ S.divide(PPM, 0);
+ S.add(1, 0); // S = 1 + dS / PPM;
+ RS.multiply(S); // RS = toRadians(1″) * S;
+ final DoubleDouble X = new DoubleDouble(rX); X.multiply(RS);
+ final DoubleDouble Y = new DoubleDouble(rY); Y.multiply(RS);
+ final DoubleDouble Z = new DoubleDouble(rZ); Z.multiply(RS);
+ final DoubleDouble mX = new DoubleDouble( X); mX.negate();
+ final DoubleDouble mY = new DoubleDouble( Y); mY.negate();
+ final DoubleDouble mZ = new DoubleDouble( Z); mZ.negate();
+ final Integer O = 0; // Fetch Integer instance only once.
+ return Matrices.create(4, 4, new Number[] {
+ S, mZ, Y, Double.valueOf(tX),
+ Z, S, mX, Double.valueOf(tY),
+ mY, X, S, Double.valueOf(tZ),
+ O, O, O, 1});
}
/**
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -28,7 +28,9 @@ import org.opengis.referencing.datum.Pri
import org.opengis.referencing.datum.GeodeticDatum;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
+import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
import org.apache.sis.internal.util.CollectionsExt;
+import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.Immutable;
import org.apache.sis.io.wkt.Formatter;
@@ -65,8 +67,8 @@ import org.apache.sis.internal.jdk7.Obje
* instance associated to this {@code DefaultGeodeticDatum}. Only if no datum shift method is found in the database,
* then the {@code BursaWolfParameters} associated to the datum may be used as a fallback.</p>
*
- * <p>The Bursa-Wolf parameters association serves an other purpose: when a CRS is formatted in
- * <cite>Well Known Text</cite> (WKT) format, the formatted string may contain a {@code TOWGS84[…]} element
+ * <p>The Bursa-Wolf parameters association serves an other purpose: when a CRS is formatted in the older
+ * <cite>Well Known Text</cite> (WKT 1) format, the formatted string may contain a {@code TOWGS84[…]} element
* with the parameter values of the transformation to the WGS 84 datum. This element is provided as a help
* for other Geographic Information Systems that support only the <cite>early-binding</cite> approach.
* Apache SIS usually does not need the {@code TOWGS84} element, except as a fallback for datum that
@@ -285,7 +287,7 @@ public class DefaultGeodeticDatum extend
* @param targetDatum The target datum.
* @return An affine transform from {@code this} to {@code target} in geocentric space, or {@code null} if none.
*
- * @see BursaWolfParameters#getPositionVectorTransformation(boolean)
+ * @see BursaWolfParameters#getPositionVectorTransformation()
*/
public Matrix getPositionVectorTransformation(final GeodeticDatum targetDatum) {
ensureNonNull("targetDatum", targetDatum);
@@ -309,7 +311,7 @@ public class DefaultGeodeticDatum extend
if (sourceParam != null) {
for (final BursaWolfParameters candidate : sourceParam) {
if (deepEquals(target, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
- return candidate.getPositionVectorTransformation(false);
+ return candidate.getPositionVectorTransformation();
}
}
}
@@ -320,8 +322,16 @@ public class DefaultGeodeticDatum extend
final BursaWolfParameters[] targetParam = bursaWolf(target);
if (targetParam != null) {
for (final BursaWolfParameters candidate : targetParam) {
- if (deepEquals(source, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) {
- return candidate.getPositionVectorTransformation(true);
+ if (deepEquals(source, candidate.targetDatum, ComparisonMode.IGNORE_METADATA)) try {
+ return MatrixSIS.castOrCopy(candidate.getPositionVectorTransformation()).inverse();
+ } catch (NoninvertibleMatrixException e) {
+ /*
+ * Should never happen because BursaWolfParameters.getPositionVectorTransformation()
+ * is defined in such a way that matrix should always be invertible. If it happen anyway,
+ * search for an other BursaWolfParameters instance. If none are found, returning 'null'
+ * is allowed by this method's contract.
+ */
+ Logging.unexpectedException(DefaultGeodeticDatum.class, "getPositionVectorTransformation", e);
}
}
}
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/AffineTransforms2D.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -25,7 +25,6 @@ import java.awt.geom.RectangularShape;
import java.awt.geom.AffineTransform;
import java.awt.geom.NoninvertibleTransformException;
import org.opengis.referencing.operation.Matrix;
-import org.apache.sis.math.MathFunctions;
import org.apache.sis.util.Static;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.resources.Errors;
@@ -371,10 +370,10 @@ public final class AffineTransforms2D ex
*/
public static int getFlip(final AffineTransform transform) {
ArgumentChecks.ensureNonNull("transform", transform);
- final int scaleX = MathFunctions.sgn(transform.getScaleX());
- final int scaleY = MathFunctions.sgn(transform.getScaleY());
- final int shearX = MathFunctions.sgn(transform.getShearX());
- final int shearY = MathFunctions.sgn(transform.getShearY());
+ final double scaleX = Math.signum(transform.getScaleX());
+ final double scaleY = Math.signum(transform.getScaleY());
+ final double shearX = Math.signum(transform.getShearX());
+ final double shearY = Math.signum(transform.getShearY());
if (scaleX == scaleY && shearX == -shearY) return +1;
if (scaleX == -scaleY && shearX == shearY) return -1;
return 0;
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -20,6 +20,7 @@ import java.util.Arrays;
import org.opengis.referencing.operation.Matrix;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.ArraysExt;
+import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.util.DoubleDouble;
@@ -129,6 +130,7 @@ class GeneralMatrix extends MatrixSIS {
/**
* Creates a new extended precision matrix of the given size.
+ * Matrices elements are initialized to zero (not to the matrix identity).
*
* @param numRow Number of rows.
* @param numCol Number of columns.
@@ -306,6 +308,69 @@ class GeneralMatrix extends MatrixSIS {
}
/**
+ * Sets all matrix elements like {@link #setElements(double)}, but from an array of {@code Number} instead
+ * of {@code double}. The main purpose of this method is to fetch the {@link DoubleDouble#error} terms when
+ * such instances are found.
+ *
+ * <p><b>Restrictions:</b></p>
+ * <ul>
+ * <li>This matrix must use extended-precision elements, as by {@link #createExtendedPrecision(int, int)}.</li>
+ * <li>If this method returns {@code false}, then error terms are <strong>not</strong> initialized - they
+ * may have any values.</li>
+ * </ul>
+ *
+ * @param elements The new matrix elements in a row-major array.
+ * @return {@code true} if at leat one {@link DoubleDouble} instance has been found, in which case all
+ * errors terms have been initialized, or {@code false} otherwise, in which case no error term
+ * has been initialized (this is a <cite>all or nothing</cite> operation).
+ * @throws IllegalArgumentException If the given array does not have the expected length.
+ *
+ * @see Matrices#create(int, int, Number[])
+ */
+ final boolean setElements(final Number[] newValues) {
+ final int numRow = this.numRow; // Protection against accidental changes.
+ final int numCol = this.numCol;
+ final int length = numRow * numCol;
+ if (newValues.length != length) {
+ throw new IllegalArgumentException(Errors.format(
+ Errors.Keys.UnexpectedArrayLength_2, length, newValues.length));
+ }
+ boolean isExtended = false;
+ for (int i=0; i<length; i++) {
+ final Number value = newValues[i];
+ final double element = value.doubleValue();
+ elements[i] = element;
+ final double error;
+ if (value instanceof DoubleDouble) {
+ error = ((DoubleDouble) value).error;
+ /*
+ * If this is the first time that we found an explicit error term, then we need to
+ * initialize all elements before the current one because they were left unitialized
+ * (i.e. we perform lazy initialization).
+ */
+ if (!isExtended) {
+ isExtended = true;
+ for (int j=0; j<i; j++) {
+ elements[j + length] = DoubleDouble.errorForWellKnownValue(elements[j]);
+ }
+ }
+ } else {
+ /*
+ * For any kind of numbers other than DoubleDoube, calculate the error term only if we know
+ * that the final matrix will use extended precision (i.e. we previously found at least one
+ * DoubleDouble instance). Otherwise skip the error calculation since maybe it will be discarded.
+ */
+ if (!isExtended) {
+ continue;
+ }
+ error = DoubleDouble.errorForWellKnownValue(element);
+ }
+ elements[i + length] = error;
+ }
+ return isExtended;
+ }
+
+ /**
* {@inheritDoc}
*
* <p>This method does not check the error terms, because those terms are not visible to the user
Modified: sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -183,6 +183,29 @@ public final class Matrices extends Stat
}
/**
+ * Creates a matrix of size {@code numRow} × {@code numCol} initialized to the given numbers.
+ * The elements array size must be equals to {@code numRow*numCol}. Column indices vary fastest.
+ *
+ * @param numRow Number of rows.
+ * @param numCol Number of columns.
+ * @param elements The matrix elements in a row-major array. Column indices vary fastest.
+ * @return A matrix initialized to the given elements.
+ */
+ public static MatrixSIS create(final int numRow, final int numCol, final Number[] elements) {
+ ArgumentChecks.ensureNonNull("elements", elements);
+ final GeneralMatrix matrix = GeneralMatrix.createExtendedPrecision(numRow, numCol);
+ if (matrix.setElements(elements)) {
+ /*
+ * At least one org.apache.sis.internal.util.DoubleDouble instance has been found,
+ * in which case the matrix uses double-double arithmetic. This case is the main
+ * purpose of this method.
+ */
+ return matrix;
+ }
+ return create(numRow, numCol, matrix.getElements());
+ }
+
+ /**
* Implementation of {@code createTransform(…)} public methods expecting envelopes and/or axis directions.
* Argument validity shall be verified by the caller.
*
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/datum/BursaWolfParametersTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -18,6 +18,8 @@ package org.apache.sis.referencing.datum
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.matrix.Matrices;
+import org.apache.sis.referencing.operation.matrix.Matrix4;
+import org.apache.sis.referencing.operation.matrix.NoninvertibleMatrixException;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.TestCase;
import org.junit.Test;
@@ -35,15 +37,40 @@ import static org.apache.sis.test.Assert
*/
public final strictfp class BursaWolfParametersTest extends TestCase {
/**
- * Tests {@link BursaWolfParameters#getPositionVectorTransformation(boolean)}.
+ * The conversion factor from arc-seconds to radians.
+ */
+ private static final double TO_RADIANS = Math.PI / (180 * 60 * 60);
+
+ /**
+ * Invokes {@link BursaWolfParameters#getPositionVectorTransformation()} and compares
+ * with our own matrix calculated using double arithmetic.
+ */
+ private static MatrixSIS getPositionVectorTransformation(final BursaWolfParameters p) {
+ final double S = 1 + p.dS / BursaWolfParameters.PPM;
+ final double RS = TO_RADIANS * S;
+ final Matrix4 expected = new Matrix4(
+ S, -p.rZ*RS, +p.rY*RS, p.tX,
+ +p.rZ*RS, S, -p.rX*RS, p.tY,
+ -p.rY*RS, +p.rX*RS, S, p.tZ,
+ 0, 0, 0, 1);
+
+ final MatrixSIS matrix = MatrixSIS.castOrCopy(p.getPositionVectorTransformation());
+ assertMatrixEquals("getPositionVectorTransformation", expected, matrix, p.isTranslation() ? 0 : 1E-14);
+ return matrix;
+ }
+
+ /**
+ * Tests {@link BursaWolfParameters#getPositionVectorTransformation()}.
* This test transform a point from WGS72 to WGS84, and conversely,
* as documented in the example section of EPSG operation method 9606.
+ *
+ * @throws NoninvertibleMatrixException Should never happen.
*/
@Test
- public void testGetPositionVectorTransformation() {
+ public void testGetPositionVectorTransformation() throws NoninvertibleMatrixException {
final BursaWolfParameters bursaWolf = new BursaWolfParameters(0, 0, 4.5, 0, 0, 0.554, 0.219, null);
- final MatrixSIS toWGS84 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(false));
- final MatrixSIS toWGS72 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(true));
+ final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
+ final MatrixSIS toWGS72 = getPositionVectorTransformation(bursaWolf).inverse();
final MatrixSIS source = Matrices.create(4, 1, new double[] {3657660.66, 255768.55, 5201382.11, 1});
final MatrixSIS target = Matrices.create(4, 1, new double[] {3657660.78, 255778.43, 5201387.75, 1});
assertMatrixEquals("toWGS84", target, toWGS84.multiply(source), 0.01);
@@ -51,21 +78,21 @@ public final strictfp class BursaWolfPar
}
/**
- * Multiplies the <cite>ED87 to WGS 84</cite> parameters (EPSG:1146) transformation by its inverse,
- * and verify that the result is somewhat close to the identity. This is an internal consistency test.
+ * Multiplies the <cite>ED87 to WGS 84</cite> parameters (EPSG:1146) transformation by its inverse and
+ * verifies that the result is very close to the identity matrix, thanks to the double-double arithmetic.
+ * This is an internal consistency test.
+ *
+ * @throws NoninvertibleMatrixException Should never happen.
*/
@Test
@DependsOnMethod("testGetPositionVectorTransformation")
- public void testP() {
+ public void testProductOfInverse() throws NoninvertibleMatrixException {
final BursaWolfParameters bursaWolf = new BursaWolfParameters(
-82.981, -99.719, -110.709, -0.5076, 0.1503, 0.3898, -0.3143, null);
- final MatrixSIS toWGS84 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(false));
- final MatrixSIS toED87 = MatrixSIS.castOrCopy(bursaWolf.getPositionVectorTransformation(true));
+ final MatrixSIS toWGS84 = getPositionVectorTransformation(bursaWolf);
+ final MatrixSIS toED87 = getPositionVectorTransformation(bursaWolf).inverse();
final MatrixSIS product = toWGS84.multiply(toED87);
- /*
- * The error is below 1E-11 for all elements except the translation terms.
- */
- assertTrue(Matrices.isIdentity(product, 5E-4));
+ assertTrue(Matrices.isIdentity(product, 1E-37));
}
/**
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/GeneralMatrixTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -87,10 +87,10 @@ public final strictfp class GeneralMatri
0.9,
0.1234567,
- // Values below this point are error terms copied from DoubleDouble.ERRORS.
+ // Most values below this point are error terms copied from DoubleDouble.ERRORS.
2.9486522708701687E-19,
-1.9878495670576283E-15,
-2.2204460492503132E-17,
- 0}, elements, STRICT);
+ -2.5483615218035994E-18}, elements, STRICT);
}
}
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatricesTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -19,9 +19,11 @@ package org.apache.sis.referencing.opera
import org.opengis.geometry.Envelope;
import org.opengis.referencing.operation.Matrix;
import org.opengis.referencing.cs.AxisDirection;
+import org.apache.sis.internal.util.DoubleDouble;
import org.apache.sis.geometry.Envelope2D;
import org.apache.sis.geometry.GeneralEnvelope;
import org.apache.sis.util.iso.Types;
+import org.apache.sis.util.ComparisonMode;
import org.apache.sis.test.DependsOnMethod;
import org.apache.sis.test.DependsOn;
import org.apache.sis.test.TestCase;
@@ -50,6 +52,45 @@ import static org.opengis.referencing.cs
})
public final strictfp class MatricesTest extends TestCase {
/**
+ * Tests {@link Matrices#create(int, int, Number[])}.
+ */
+ public void testCreateFromNumbers() {
+ final double SENTINEL_VALUE = Double.MIN_VALUE;
+ final int SIZE = Matrix3.SIZE;
+ final Matrix3 expected = new Matrix3(
+ 1, 2, 3,
+ 0.1, 0.2, 0.3,
+ -1, -2, -3);
+ final Number[] elements = {
+ 1, 2, 3,
+ 0.1, 0.2, 0.3,
+ -1, -2, -3};
+ /*
+ * Mix of Integer and Double objects but without DoubleDouble objects.
+ * The result shall be a matrix using the standard double Java type.
+ */
+ assertEquals(expected, Matrices.create(SIZE, SIZE, elements));
+ /*
+ * Now put some DoubleDouble instances in the diagonal. We set the error term to
+ * Double.MIN_VALUE in order to differentiate them from automatically calculated
+ * error terms. The result shall use double-double arithmetic, and we should be
+ * able to find back our error terms.
+ */
+ for (int i = 0; i < elements.length; i += SIZE+1) {
+ elements[i] = new DoubleDouble(elements[i].doubleValue(), SENTINEL_VALUE);
+ }
+ final MatrixSIS matrix = Matrices.create(SIZE, SIZE, elements);
+ assertInstanceOf("Created with DoubleDouble elements", GeneralMatrix.class, matrix);
+ assertFalse(expected.equals(matrix)); // Because not the same type.
+ assertTrue(Matrices.equals(expected, matrix, ComparisonMode.BY_CONTRACT));
+ final double[] errors = ((GeneralMatrix) matrix).elements;
+ for (int i = 0; i < SIZE*SIZE; i++) {
+ // Only elements on the diagonal shall be our sentinel value.
+ assertEquals((i % (SIZE+1)) == 0, errors[i + SIZE*SIZE] == SENTINEL_VALUE);
+ }
+ }
+
+ /**
* Tests {@link Matrices#createTransform(AxisDirection[], AxisDirection[])} with the same sequence of axes.
* The result shall be an identity matrix.
*
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/MatrixTestCase.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -85,7 +85,7 @@ public abstract strictfp class MatrixTes
* @see SolverTest#TOLERANCE
* @see NonSquareMatrixTest#printStatistics()
*/
- protected static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-12;
+ protected static final double TOLERANCE = DoubleDouble.DISABLED ? STRICT : 1E-11;
/**
* Number of random matrices to try in arithmetic operation tests.
Modified: sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] (original)
+++ sis/trunk/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/matrix/NonSquareMatrixTest.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -75,6 +75,8 @@ public final strictfp class NonSquareMat
/**
* Tests {@link NonSquareMatrix#inverse()} with a non-square matrix.
+ *
+ * @throws NoninvertibleMatrixException Should never happen.
*/
@Override
public void testInverse() throws NoninvertibleMatrixException {
@@ -84,6 +86,8 @@ public final strictfp class NonSquareMat
/**
* Tests {@link NonSquareMatrix#solve(Matrix)} with a non-square matrix.
+ *
+ * @throws NoninvertibleMatrixException Should never happen.
*/
@Override
public void testSolve() throws NoninvertibleMatrixException {
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/system/DelayedRunnable.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -19,7 +19,6 @@ package org.apache.sis.internal.system;
import java.util.concurrent.Delayed;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
-import org.apache.sis.math.MathFunctions;
/**
@@ -70,13 +69,14 @@ public abstract class DelayedRunnable im
* accepts only {@code DelayedRunnable} instances.
*
* @param other The other delayed object to compare with this delayed task.
+ * @return -1 if the other task should happen before this one, +1 if it should happen after, or 0.
*/
@Override
public int compareTo(final Delayed other) {
if (other instanceof Immediate) {
return +1; // "Immediate" tasks always have precedence over delayed ones.
}
- return MathFunctions.sgn(timestamp - ((DelayedRunnable) other).timestamp);
+ return Long.signum(timestamp - ((DelayedRunnable) other).timestamp);
}
/**
@@ -104,6 +104,9 @@ public abstract class DelayedRunnable im
/**
* Returns the delay, which is fixed to 0 in every cases.
+ *
+ * @param unit The unit of the value to return (ignored).
+ * @return The delay, which is fixed to 0.
*/
@Override
public final long getDelay(final TimeUnit unit) {
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/DoubleDouble.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -18,6 +18,7 @@ package org.apache.sis.internal.util;
import java.util.Arrays;
import org.apache.sis.math.MathFunctions;
+import org.apache.sis.math.DecimalFunctions;
// No BigDecimal dependency - see class javadoc
@@ -114,44 +115,31 @@ public final class DoubleDouble extends
public static final double MAX_VALUE = Double.MAX_VALUE / SPLIT;
/**
- * Pre-defined constants frequently used in SIS. SIS often creates matrices for unit conversions,
- * and most conversion factors are defined precisely in base 10. For example the conversion from
- * feet to metre is defined by a factor of exactly 0.3048, which can not be represented precisely
- * as a {@code double}. Consequently if a value of 0.3048 is given, we can assume that the intend
- * was to provide the "feet to metres" conversion factor and complete the double-double instance
- * accordingly.
+ * Pre-defined constants frequently used in SIS, sorted in increasing order. This table contains only
+ * constants that can not be inferred by {@link DecimalFunctions#deltaForDoubleToDecimal(double)},
+ * for example some transcendental values.
*
* <p>Elements in this array shall be sorted in strictly increasing order.
* For any value at index <var>i</var>, the associated error is {@code ERRORS[i]}.
+ *
+ * @see #errorForWellKnownValue(double)
*/
private static final double[] VALUES = {
// Some of the following constants have more fraction digits than necessary. We declare the extra
// digits for documentation purpose, and in order to have identical content than DoubleDoubleTest
// so that a plain copy-and-paste can be performed between those two classes.
- 0.000001,
- 0.00001,
- 0.0001,
- 0.00027777777777777777777777777777777778, // Second to degrees
- 0.001,
+ 0.000004848136811095359935899141023579480, // Arc-second to radians
+ 0.0002777777777777777777777777777777778, // Second to degrees
0.002777777777777777777777777777777778, // 1/360°
- 0.01,
0.01666666666666666666666666666666667, // Minute to degrees
0.01745329251994329576923690768488613, // Degrees to radians
- 0.1,
- 0.201168, // Link to metres
- 0.3048, // Feet to metres
0.785398163397448309615660845819876, // π/4
- 0.9, // Degrees to gradians
- 0.9144, // Yard to metres
1.111111111111111111111111111111111, // Gradian to degrees
1.414213562373095048801688724209698, // √2
1.570796326794896619231321691639751, // π/2
- 1.8288, // Fathom to metres
2.356194490192344928846982537459627, // π * 3/4
- 2.54, // Inch to centimetres
3.14159265358979323846264338327950, // π
6.28318530717958647692528676655901, // 2π
- 20.1168, // Chain to metres
57.2957795130823208767981548141052 // Radians to degrees
};
@@ -168,30 +156,18 @@ public final class DoubleDouble extends
* </ul>
*/
private static final double[] ERRORS = {
- /* 0.000001 */ 4.525188817411374E-23,
- /* 0.00001 */ -8.180305391403131E-22,
- /* 0.0001 */ -4.79217360238593E-21,
+ /* 0.000004… */ 9.320078015422868E-23,
/* 0.000266… */ 2.4093381610788987E-22,
- /* 0.001 */ -2.0816681711721686E-20,
/* 0.002666… */ -1.0601087908747154E-19,
- /* 0.01 */ -2.0816681711721684E-19,
/* 0.016666… */ 2.312964634635743E-19,
/* 0.017453… */ 2.9486522708701687E-19,
- /* 0.1 */ -5.551115123125783E-18,
- /* 0.201168 */ -1.3471890270011499E-17,
- /* 0.3048 */ -1.5365486660812166E-17,
/* 0.785398… */ 3.061616997868383E-17,
- /* 0.9 */ -2.2204460492503132E-17,
- /* 0.9144 */ 9.414691248821328E-18,
/* 1.111111… */ -4.9343245538895844E-17,
/* 1.414213… */ -9.667293313452913E-17,
/* 1.570796… */ 6.123233995736766E-17,
- /* 1.8288 */ 1.8829382497642655E-17,
/* 2.356194… */ 9.184850993605148E-17,
- /* 2.54 */ -3.552713678800501E-17,
/* 3.141592… */ 1.2246467991473532E-16,
/* 6.283185… */ 2.4492935982947064E-16,
- /* 20.1168 */ -1.3471890270011499E-15,
/* 57.295779… */ -1.9878495670576283E-15
};
@@ -213,6 +189,27 @@ public final class DoubleDouble extends
}
/**
+ * Creates a new value initialized to the given value.
+ *
+ * @param other The other value to copy.
+ */
+ public DoubleDouble(final DoubleDouble other) {
+ value = other.value;
+ error = other.error;
+ }
+
+ /**
+ * Creates a new value initialized to the given value and an error term inferred by
+ * {@link #errorForWellKnownValue(double)}.
+ *
+ * @param value The initial value.
+ */
+ public DoubleDouble(final double value) {
+ this.value = value;
+ this.error = errorForWellKnownValue(value);
+ }
+
+ /**
* Creates a new value initialized to the given value and error.
* It is caller's responsibility to ensure that the (value, error) pair is normalized.
*
@@ -235,6 +232,16 @@ public final class DoubleDouble extends
return new DoubleDouble(0.01745329251994329576923690768488613, 2.9486522708701687E-19);
}
+ /**
+ * Returns a new {@code DoubleDouble} instance initialized to the conversion factor
+ * from arc-seconds to radians.
+ *
+ * @return An instance initialized to the 0.000004848136811095359935899141023579480 value.
+ */
+ public static DoubleDouble createSecondsToRadians() {
+ return new DoubleDouble(0.000004848136811095359935899141023579480, 9.320078015422868E-23);
+ }
+
/** @return {@link #value}. */
@Override public double doubleValue() {return value;}
@Override public float floatValue() {return (float) value;}
@@ -242,17 +249,31 @@ public final class DoubleDouble extends
@Override public int intValue() {return (int) longValue();}
/**
- * If the given value is one of the well known constants, returns the error for that value.
- * Otherwise returns 0.
+ * Suggests an {@link #error} for the given value. The {@code DoubleDouble} class contains a hard-coded list
+ * of some frequently used constants, for example for various factors of π. If the given value matches exactly
+ * one of those constants, then its error term is returned. Otherwise this method assumes that the given value
+ * is defined in base 10 (e.g. many unit conversion factors) and tries to compute an error term with
+ * {@link DecimalFunctions#deltaForDoubleToDecimal(double)}.
+ *
+ * {@section Rational}
+ * SIS often creates matrices for unit conversions, and most conversion factors are defined precisely in base 10.
+ * For example the conversion from feet to metres is defined by a factor of exactly 0.3048, which can not be
+ * represented precisely as a {@code double}. Consequently if a value of 0.3048 is given, we can assume that
+ * the intend was to provide the "feet to metres" conversion factor and complete the double-double instance
+ * accordingly.
*
* @param value The value for which to get this error.
* @return The error for the given value, or 0 if unknown. In the later case,
- * the given value is assumed to be the most accurate available representation.
+ * the base 2 representation of the given value is assumed to be accurate enough.
*/
public static double errorForWellKnownValue(final double value) {
if (DISABLED) return 0;
final int i = Arrays.binarySearch(VALUES, Math.abs(value));
- return (i >= 0) ? MathFunctions.xorSign(ERRORS[i], value) : 0;
+ if (i >= 0) {
+ return MathFunctions.xorSign(ERRORS[i], value);
+ }
+ final double delta = DecimalFunctions.deltaForDoubleToDecimal(value);
+ return Double.isNaN(delta) ? 0 : delta;
}
/**
@@ -398,7 +419,7 @@ public final class DoubleDouble extends
}
/**
- * Set this number to {@code -this}.
+ * Sets this number to {@code -this}.
*/
public void negate() {
value = -value;
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/internal/util/Numerics.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -83,11 +83,10 @@ public final class Numerics extends Stat
public static final int SIGNIFICAND_SIZE = 52;
/**
- * A prime number used for hash code computation. Value 31 is often used because
- * some modern compilers can optimize {@code x*31} as {@code (x << 5) - x}
- * (Josh Bloch, <cite>Effective Java</cite>).
+ * Number of bits in the significand (mantissa) part of IEEE 754 {@code float} representation,
+ * <strong>not</strong> including the hidden bit.
*/
- private static final int PRIME_NUMBER = 31;
+ public static final int SIGNIFICAND_SIZE_OF_FLOAT = 23;
/**
* Do not allow instantiation of this class.
@@ -217,7 +216,12 @@ public final class Numerics extends Stat
* @return An updated hash code value.
*/
public static int hash(final float value, final int seed) {
- return seed * PRIME_NUMBER + Float.floatToIntBits(value);
+ /*
+ * Multiplication by prime number produces better hash code distribution.
+ * Value 31 is often used because some modern compilers can optimize x*31
+ * as (x << 5) - x (Josh Bloch, Effective Java).
+ */
+ return 31*seed + Float.floatToIntBits(value);
}
/**
@@ -241,6 +245,102 @@ public final class Numerics extends Stat
* @return An updated hash code value.
*/
public static int hash(final long value, final int seed) {
- return seed * PRIME_NUMBER + (((int) value) ^ ((int) (value >>> 32)));
+ return 31*seed + (((int) value) ^ ((int) (value >>> 32)));
+ }
+
+ /**
+ * Converts a power of 2 to a power of 10, rounded toward negative infinity.
+ * This method is equivalent to the following code, but using only integer arithmetic:
+ *
+ * {@preformat java
+ * return (int) Math.floor(exp2 * LOG10_2);
+ * }
+ *
+ * This method is valid only for arguments in the [-2620 … 2620] range, which is more than enough
+ * for the range of {@code double} exponents. We do not put this method in public API because it
+ * does not check the argument validity.
+ *
+ * {@section Arithmetic notes}
+ * {@code toExp10(getExponent(10ⁿ))} returns <var>n</var> only for {@code n == 0}, and <var>n</var>-1 in all other
+ * cases. This is because 10ⁿ == m × 2<sup>exp2</sup> where the <var>m</var> significand is always greater than 1,
+ * which must be compensated by a smaller {@code exp2} value such as {@code toExp10(exp2) < n}. Note that if the
+ * {@code getExponent(…)} argument is not a power of 10, then the result can be either <var>n</var> or <var>n</var>-1.
+ *
+ * @param exp2 The power of 2 to convert Must be in the [-2620 … 2620] range.
+ * @return The power of 10, rounded toward negative infinity.
+ *
+ * @see org.apache.sis.math.MathFunctions#LOG10_2
+ * @see org.apache.sis.math.MathFunctions#getExponent(double)
+ */
+ public static int toExp10(final int exp2) {
+ /*
+ * Compute:
+ * exp2 × (log10(2) × 2ⁿ) / 2ⁿ
+ * where:
+ * n = 20 (arbitrary value)
+ *
+ * log10(2) × 2ⁿ = 315652.82873335475, which we round to 315653.
+ *
+ * The range of valid values for such approximation is determined
+ * empirically by running the NumericsTest.testToExp10() method.
+ */
+ assert exp2 >= -2620 && exp2 <= 2620 : exp2;
+ return (exp2 * 315653) >> 20;
+ }
+
+ /**
+ * Returns the significand <var>m</var> of the given value such as {@code value = m×2ⁿ}
+ * where <var>n</var> is {@link Math#getExponent(double)} - {@value #SIGNIFICAND_SIZE}.
+ * For any non-NaN values (including infinity), the following relationship holds:
+ *
+ * {@preformat java
+ * assert Math.scalb(getSignificand(value), Math.getExponent(value) - SIGNIFICAND_SIZE) == Math.abs(value);
+ * }
+ *
+ * For negative values, this method behaves as if the value was positive.
+ *
+ * @param value The value for which to get the significand.
+ * @return The significand of the given value.
+ */
+ public static long getSignificand(final double value) {
+ long bits = Double.doubleToRawLongBits(value);
+ final long exponent = bits & (0x7FFL << SIGNIFICAND_SIZE);
+ bits &= (1L << SIGNIFICAND_SIZE) - 1;
+ if (exponent != 0) {
+ bits |= (1L << SIGNIFICAND_SIZE);
+ } else {
+ /*
+ * Sub-normal value: compensate for the fact that Math.getExponent(value) returns
+ * Double.MIN_EXPONENT - 1 in this case, while we would need Double.MIN_EXPONENT.
+ */
+ bits <<= 1;
+ }
+ return bits;
+ }
+
+ /**
+ * Returns the significand <var>m</var> of the given value such as {@code value = m×2ⁿ} where
+ * <var>n</var> is {@link Math#getExponent(float)} - {@value #SIGNIFICAND_SIZE_OF_FLOAT}.
+ * For any non-NaN positive values (including infinity), the following relationship holds:
+ *
+ * {@preformat java
+ * assert Math.scalb(getSignificand(value), Math.getExponent(value) - SIGNIFICAND_SIZE_OF_FLOAT) == value;
+ * }
+ *
+ * For negative values, this method behaves as if the value was positive.
+ *
+ * @param value The value for which to get the significand.
+ * @return The significand of the given value.
+ */
+ public static int getSignificand(final float value) {
+ int bits = Float.floatToRawIntBits(value);
+ final int exponent = bits & (0xFF << SIGNIFICAND_SIZE_OF_FLOAT);
+ bits &= (1L << SIGNIFICAND_SIZE_OF_FLOAT) - 1;
+ if (exponent != 0) {
+ bits |= (1L << SIGNIFICAND_SIZE_OF_FLOAT);
+ } else {
+ bits <<= 1;
+ }
+ return bits;
}
}
Modified: sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java
URL: http://svn.apache.org/viewvc/sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java?rev=1540210&r1=1540209&r2=1540210&view=diff
==============================================================================
--- sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] (original)
+++ sis/trunk/core/sis-utility/src/main/java/org/apache/sis/io/CompoundFormat.java [UTF-8] Fri Nov 8 22:27:48 2013
@@ -391,7 +391,7 @@ public abstract class CompoundFormat<T>
if (!Locale.ROOT.equals(locale)) {
format = DateFormat.getDateTimeInstance(DateFormat.DEFAULT, DateFormat.DEFAULT, locale);
} else {
- format = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.ROOT);
+ format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
}
format.setTimeZone(getTimeZone());
return format;
@@ -405,6 +405,8 @@ public abstract class CompoundFormat<T>
/**
* Returns a clone of this format.
+ *
+ * @return A clone of this format.
*/
@Override
public CompoundFormat<T> clone() {