Author: desruisseaux Date: Mon Oct 16 10:01:46 2017 New Revision: 1812269 URL: http://svn.apache.org/viewvc?rev=1812269&view=rev Log: Merge from JDK8 branch.
Added: sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java - copied unchanged from r1812266, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/TestFactorySource.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java - copied unchanged from r1812266, sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/test/integration/CoordinateReferenceSystemTest.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jdk8/BinaryOperator.java (with props) Modified: sis/branches/JDK7/ (props changed) sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultExtent.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/NameMeaningTest.java sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/AuthorityFactoryProxy.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/ProjectionException.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombinerTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ReferencingUtilitiesTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/ServicesForMetadataTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/internal/referencing/provider/DatumShiftTestCase.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/cs/CodesTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/AuthorityFactoryMock.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2001.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2002.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2003.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2004.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2005.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2006.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2007.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2008.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/GIGS2009.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactoryTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGFactoryTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/factory/sql/EPSGInstallerTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationFinderTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/referencing/operation/CoordinateOperationRegistryTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/integration/ConsistencyTest.java sis/branches/JDK7/core/sis-referencing/src/test/java/org/apache/sis/test/suite/ReferencingTestSuite.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/jaxb/PrimitiveTypeProperties.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/system/DefaultFactories.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/util/ArraysExt.java sis/branches/JDK7/core/sis-utility/src/main/java/org/apache/sis/xml/NilReason.java sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/converter/PathConverterTest.java sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/internal/util/DefinitionURITest.java sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/measure/RangeTest.java sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/test/Assume.java sis/branches/JDK7/core/sis-utility/src/test/java/org/apache/sis/xml/OGCNamespacePrefixMapperTest.java sis/branches/JDK7/storage/sis-gdal/src/test/java/org/apache/sis/storage/gdal/PJTest.java sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/internal/storage/folder/StoreTest.java sis/branches/JDK7/storage/sis-storage/src/test/java/org/apache/sis/storage/StorageConnectorTest.java Propchange: sis/branches/JDK7/ ------------------------------------------------------------------------------ --- svn:mergeinfo (original) +++ svn:mergeinfo Mon Oct 16 10:01:46 2017 @@ -1,5 +1,5 @@ /sis/branches/Android:1430670-1480699 /sis/branches/JDK6:1394913-1508480 -/sis/branches/JDK8:1584960-1811544 +/sis/branches/JDK8:1584960-1812266 /sis/branches/JDK9:1773327-1803064 /sis/trunk:1394364-1508466,1519089-1519674 Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/AxisDirections.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -429,22 +429,22 @@ public final class AxisDirections extend * Returns the angular unit of the specified coordinate system. * The preference will be given to the longitude axis, if found. * - * @param cs the coordinate system from which to get the angular unit, or {@code null}. - * @param unit the default unit to return if no angular unit is found. + * @param cs the coordinate system from which to get the angular unit, or {@code null}. + * @param fallback the default unit to return if no angular unit is found. * @return the angular unit, of {@code unit} if no angular unit was found. * * @see org.apache.sis.internal.referencing.ReferencingUtilities#getUnit(CoordinateSystem) * * @since 0.6 */ - public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> unit) { + public static Unit<Angle> getAngularUnit(final CoordinateSystem cs, Unit<Angle> fallback) { if (cs != null) { for (int i = cs.getDimension(); --i>=0;) { final CoordinateSystemAxis axis = cs.getAxis(i); if (axis != null) { // Paranoiac check. final Unit<?> candidate = axis.getUnit(); if (Units.isAngular(candidate)) { - unit = candidate.asType(Angle.class); + fallback = candidate.asType(Angle.class); if (AxisDirection.EAST.equals(absolute(axis.getDirection()))) { break; // Found the longitude axis. } @@ -452,7 +452,7 @@ public final class AxisDirections extend } } } - return unit; + return fallback; } /** Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/EllipsoidalHeightCombiner.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -17,6 +17,8 @@ package org.apache.sis.internal.metadata; import java.util.Map; +import java.util.HashMap; +import org.opengis.metadata.extent.Extent; import org.opengis.referencing.crs.CRSFactory; import org.opengis.referencing.crs.CoordinateReferenceSystem; import org.opengis.referencing.crs.GeodeticCRS; @@ -32,6 +34,8 @@ import org.opengis.referencing.datum.Ver import org.opengis.referencing.operation.Conversion; import org.opengis.referencing.operation.CoordinateOperationFactory; import org.opengis.util.FactoryException; +import org.apache.sis.metadata.iso.extent.Extents; +import org.apache.sis.util.ArgumentChecks; import org.apache.sis.util.ArraysExt; @@ -204,4 +208,27 @@ public class EllipsoidalHeightCombiner { } return null; } + + /** + * Suggests properties for a compound CRS made of the given elements. + * This method builds a default CRS name and domain of validity. + * + * @param components the components for which to get a default set of properties. + * @return suggested properties in a modifiable map. Callers can modify the returned map. + */ + public static Map<String,Object> properties(final CoordinateReferenceSystem... components) { + final StringBuilder name = new StringBuilder(40); + Extent domain = null; + for (int i=0; i<components.length; i++) { + final CoordinateReferenceSystem crs = components[i]; + ArgumentChecks.ensureNonNullElement("components", i, crs); + if (i != 0) name.append(" + "); + name.append(crs.getName().getCode()); + domain = Extents.intersection(domain, crs.getDomainOfValidity()); + } + final Map<String,Object> properties = new HashMap<>(2); + properties.put(CoordinateReferenceSystem.NAME_KEY, name.toString()); + properties.put(CoordinateReferenceSystem.DOMAIN_OF_VALIDITY_KEY, domain); + return properties; + } } Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/NameMeaning.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -29,19 +29,20 @@ import org.opengis.referencing.operation import org.opengis.util.InternationalString; import org.opengis.metadata.citation.Citation; import org.apache.sis.util.Static; +import org.apache.sis.internal.util.Utilities; import org.apache.sis.internal.util.Constants; import org.apache.sis.internal.util.DefinitionURI; import org.apache.sis.metadata.iso.citation.Citations; /** - * The meaning of some part of URN in the {@code "ogc"} namespace. + * The meaning of some parts of URN in the {@code "ogc"} namespace. * The meaning are defined by <cite>OGC Naming Authority</cite> (OGCNA) or other OGC sources. * * @author Martin Desruisseaux (IRD, Geomatys) - * @version 0.7 + * @version 0.8 * - * @see org.apache.sis.internal.util.DefinitionURI + * @see DefinitionURI * @see <a href="http://www.opengeospatial.org/ogcna">http://www.opengeospatial.org/ogcna</a> * @see <a href="http://portal.opengeospatial.org/files/?artifact_id=24045">Definition identifier URNs in OGC namespace</a> * @@ -71,7 +72,7 @@ public final class NameMeaning extends S /** * The object types for instances of {@link #CLASSES}. - * See {@link org.apache.sis.internal.util.DefinitionURI} javadoc for a list of object types in URN. + * See {@link DefinitionURI} javadoc for a list of object types in URN. * * <p>Types not yet listed (waiting to see if there is a use for them):</p> * @@ -142,8 +143,10 @@ public final class NameMeaning extends S /** * Formats the given identifier using the {@code "ogc:urn:def:"} syntax with possible heuristic changes to - * the given values. This method delegates to {@link DefinitionURI#format(String, String, String, String)} - * after "fixing" the given values using some heuristic knowledge about the meaning of URN. + * the given values. The identifier code space, version and code are appended omitting any characters that + * are not valid for a Unicode identifier. If some information are missing in the given identifier, then + * this method returns {@code null}. This method tries to "fix" the given values using some heuristic + * knowledge about the meaning of URN. * * @param type the object type. * @param authority the authority as one of the values documented in {@link DefinitionURI} javadoc. @@ -151,49 +154,67 @@ public final class NameMeaning extends S * @param code the code. * @return an identifier using the URN syntax, or {@code null} if a mandatory information is missing. * - * @see DefinitionURI#format(String, String, String, String) - * * @since 0.7 */ public static String toURN(final Class<?> type, final String authority, String version, String code) { - if (type != null && authority != null && code != null) { - final String key = authority.toUpperCase(Locale.US); - String codeSpace = AUTHORITIES.get(key); - if (codeSpace == null) { - /* - * If the given authority is not one of the authorities that we expected for the OGC namespace, - * verify if we can related it to one of the specifications enumerated in the Citations class. - * For example if the user gave us "OGP" as the authority, we will replace that by "IOGP" (the - * new name for that organization). - */ - final Citation c = Citations.fromName(key); - codeSpace = Citations.getCodeSpace(c); - if (AUTHORITIES.get(codeSpace) == null) { - return null; // Not an authority that we recognize for the OGC namespace. - } - version = getVersion(c); // Unconditionally overwrite the user-specified version. + if (type == null || authority == null || code == null) { + return null; + } + final String key = authority.toUpperCase(Locale.US); + String codeSpace = AUTHORITIES.get(key); + if (codeSpace == null) { + /* + * If the given authority is not one of the authorities that we expected for the OGC namespace, + * verify if we can related it to one of the specifications enumerated in the Citations class. + * For example if the user gave us "OGP" as the authority, we will replace that by "IOGP" (the + * new name for that organization). + */ + final Citation c = Citations.fromName(key); + codeSpace = Citations.getCodeSpace(c); + if (AUTHORITIES.get(codeSpace) == null) { + return null; // Not an authority that we recognize for the OGC namespace. + } + version = getVersion(c); // Unconditionally overwrite the user-specified version. + /* + * If the above lines resulted in a change of codespace, we may need to concatenate the authority + * with the code for preserving information. The main use case is WMS codes like "CRS:84": + * + * 1) Citations.fromName("CRS") gave us Citations.WMS (version 1.3) as the authority. + * 2) getCodeSpace(Citations.WMS) gave us "OGC", which is indeed the codespace used in URN. + * 3) OGC Naming Authority – Procedures (OGC-09-046r2) said that "CRS:84" should be formatted + * as "urn:ogc:def:crs:OGC:1.3:CRS84". We already got the "OGC" and "1.3" parts with above + * steps, the last part is to replace "84" by "CRS84". + */ + if (!authority.equals(codeSpace) && !code.startsWith(authority)) { + code = authority + code; // Intentionally no ':' separator. + } + } + final StringBuilder buffer = new StringBuilder(DefinitionURI.PREFIX); +loop: for (int p=0; ; p++) { + final String part; + switch (p) { + case 0: part = toObjectType(type); break; + case 1: part = codeSpace; break; + case 2: part = version; break; + case 3: part = code; break; + default: break loop; + } + if (!Utilities.appendUnicodeIdentifier(buffer.append(DefinitionURI.SEPARATOR), '\u0000', part, ".-", false)) { /* - * If the above lines resulted in a chance of codespace, we may need to concatenate the authority - * with the code for preserving information. The main use case is WMS codes like "CRS:84": - * - * 1) Citations.fromName("CRS") gave us Citations.WMS (version 1.3) as the authority. - * 2) getCodeSpace(Citations.WMS) gave us "OGC", which is indeed the codespace used in URN. - * 3) OGC Naming Authority – Procedures (OGC-09-046r2) said that "CRS:84" should be formatted - * as "urn:ogc:def:crs:OGC:1.3:CRS84". We already got the "OGC" and "1.3" parts with above - * steps, the last part is to replace "84" by "CRS84". + * Only the version (p = 2) is optional. All other fields are mandatory. + * If no character has been added for a mandatory field, we can not build a URN. */ - if (!authority.equals(codeSpace) && !code.startsWith(authority)) { - code = authority + code; // Intentionally no ':' separator. + if (p != 2) { + return null; } } - return DefinitionURI.format(toObjectType(type), codeSpace, version, code); } - return null; + return buffer.toString(); } /** * Returns the "object type" part of an OGC URN for the given class, or {@code null} if unknown. - * See {@link org.apache.sis.internal.util.DefinitionURI} javadoc for a list of object types in URN. + * See {@link DefinitionURI} javadoc for a list of object types in URN. * * @param type the class for which to get the URN type. * @return the URN type, or {@code null} if unknown. Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/ReferencingServices.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -505,6 +505,8 @@ public class ReferencingServices extends * If the given properties are empty and the {@code mtFactory} is the system default, then this method * returns the system default {@code CoordinateOperationFactory} instead of creating a new one. * + * <p>It is okay to set all parameters to {@code null} in order to get the system default factory.</p> + * * @param properties the default properties. * @param mtFactory the math transform factory to use. * @param crsFactory the factory to use if the operation factory needs to create CRS for intermediate steps. Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/citation/Citations.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -251,7 +251,7 @@ public final class Citations extends Sta * <ul> * <li><a href="http://www.opengeospatial.org/standards/ct">Coordinate Transformation Service</a></li> * <li><a href="http://www.opengeospatial.org/standards/wms">Web Map Service</a></li> - * <li>Definition identifier URNs in OGC namespace</li> + * <li><a href="http://portal.opengeospatial.org/files/?artifact_id=24045">Definition identifier URNs in OGC namespace</a></li> * </ul> * * We do not commit to a particular OGC specification in order to keep the flexibility to change the Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultExtent.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultExtent.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultExtent.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultExtent.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -16,6 +16,8 @@ */ package org.apache.sis.metadata.iso.extent; +import java.util.Set; +import java.util.LinkedHashSet; import java.util.Collection; import javax.xml.bind.annotation.XmlType; import javax.xml.bind.annotation.XmlElement; @@ -29,9 +31,17 @@ import org.opengis.metadata.extent.Geogr import org.opengis.referencing.operation.TransformException; import org.opengis.util.InternationalString; import org.apache.sis.util.iso.Types; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.collection.Containers; +import org.apache.sis.metadata.AbstractMetadata; import org.apache.sis.metadata.iso.ISOMetadata; import org.apache.sis.metadata.TitleProperty; import org.apache.sis.internal.metadata.ReferencingServices; +import org.apache.sis.xml.NilObject; +import org.apache.sis.xml.NilReason; + +// Branch-dependent imports +import org.apache.sis.internal.jdk8.BinaryOperator; /** @@ -74,7 +84,7 @@ import org.apache.sis.internal.metadata. * @author Martin Desruisseaux (IRD, Geomatys) * @author Touraïvane (IRD) * @author Cédric Briançon (Geomatys) - * @version 0.3 + * @version 0.8 * * @see Extents#getGeographicBoundingBox(Extent) * @see org.apache.sis.referencing.AbstractReferenceSystem#getDomainOfValidity() @@ -289,6 +299,85 @@ public class DefaultExtent extends ISOMe */ public void addElements(final Envelope envelope) throws TransformException { checkWritePermission(); + ArgumentChecks.ensureNonNull("envelope", envelope); ReferencingServices.getInstance().addElements(envelope, this); } + + /** + * Sets this extent to the intersection of this extent with the specified one. + * This method computes the intersections of all geographic, vertical and temporal elements in this extent + * with all geographic, vertical and temporal elements in the other extent, ignoring duplicated results. + * + * @param other the extent to intersect with this extent. + * @throws IllegalArgumentException if two elements to intersect are not compatible (e.g. mismatched + * {@linkplain DefaultGeographicBoundingBox#getInclusion() bounding box inclusion status} or + * mismatched {@linkplain DefaultVerticalExtent#getVerticalCRS() vertical datum}). + * @throws UnsupportedOperationException if a {@code TemporalFactory} is required but no implementation + * has been found on the classpath. + * + * @see Extents#intersection(Extent, Extent) + * @see org.apache.sis.geometry.GeneralEnvelope#intersect(Envelope) + * + * @since 0.8 + */ + public void intersect(final Extent other) { + checkWritePermission(); + ArgumentChecks.ensureNonNull("other", other); + final InternationalString od = other.getDescription(); + if (od != null && !(description instanceof NilObject)) { + if (description == null || (od instanceof NilObject)) { + description = od; + } else if (!description.equals(od)) { + description = NilReason.MISSING.createNilObject(InternationalString.class); + } + } + geographicElements = intersect(GeographicExtent.class, geographicElements, other.getGeographicElements(), new BinaryOperator<GeographicExtent>() {@Override public GeographicExtent apply(GeographicExtent e1, GeographicExtent e2) {return Extents.intersection(e1, e2);}}); + verticalElements = intersect(VerticalExtent.class, verticalElements, other.getVerticalElements(), new BinaryOperator<VerticalExtent> () {@Override public VerticalExtent apply(VerticalExtent e1, VerticalExtent e2) {return Extents.intersection(e1, e2);}}); + temporalElements = intersect(TemporalExtent.class, temporalElements, other.getTemporalElements(), new BinaryOperator<TemporalExtent> () {@Override public TemporalExtent apply(TemporalExtent e1, TemporalExtent e2) {return Extents.intersection(e1, e2);}}); + } + + /** + * Computes the intersections of all elements in the given {@code sources} collection will all elements + * in the given {@code targets} collection. If one of those collections is null or empty, this method + * returns all elements of the other collection (may be {@code targets} itself). + * + * @param <T> compile-time value of {@code type} argument. + * @param type the type of elements in the collections. + * @param targets the elements in this {@code DefaultExtent}. Also the collection where results will be stored. + * @param sources the elements from the other {@code Extent} to intersect with this extent. + * @param intersect the function computing intersections. + * @return the intersection results. May be the same instance than {@code targets} with elements replaced. + */ + private <T> Collection<T> intersect(final Class<T> type, Collection<T> targets, Collection<? extends T> sources, final BinaryOperator<T> intersect) { + if (!Containers.isNullOrEmpty(sources)) { + if (!Containers.isNullOrEmpty(targets)) { + final Set<T> results = new LinkedHashSet<>(Containers.hashMapCapacity(targets.size())); + T empty = null; + for (final T target : targets) { + for (final T source : sources) { + final T e = intersect.apply(target, source); + results.add(e); + /* + * If the two elements do not intersect, remember the value created by the intersection method + * for meaning "no intersection". We remember only the first value since we always create the + * same value for meaning "no intersection". + */ + if (empty == null && e != source && e != target && (e instanceof AbstractMetadata) && ((AbstractMetadata) e).isEmpty()) { + empty = e; + } + } + } + /* + * Remove the "no intersection" value, unless this is the only result. + */ + results.remove(null); + if (results.size() > 1) { + results.remove(empty); + } + sources = results; + } + targets = writeCollection(sources, targets, type); + } + return targets; + } } Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultGeographicBoundingBox.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -536,7 +536,7 @@ public class DefaultGeographicBoundingBo ArgumentChecks.ensureNonNull("box", box); setBounds(box.getWestBoundLongitude(), box.getEastBoundLongitude(), box.getSouthBoundLatitude(), box.getNorthBoundLatitude()); - setInclusion(box.getInclusion()); // Set only on success. + setInclusion(box.getInclusion()); // Set only on success. } /* @@ -650,6 +650,7 @@ public class DefaultGeographicBoundingBo */ public void add(final GeographicBoundingBox box) { checkWritePermission(); + ArgumentChecks.ensureNonNull("box", box); double λmin = box.getWestBoundLongitude(); double λmax = box.getEastBoundLongitude(); double φmin = box.getSouthBoundLatitude(); @@ -707,6 +708,7 @@ public class DefaultGeographicBoundingBo */ public void intersect(final GeographicBoundingBox box) throws IllegalArgumentException { checkWritePermission(); + ArgumentChecks.ensureNonNull("box", box); if (getInclusion(getInclusion()) != getInclusion(box.getInclusion())) { throw new IllegalArgumentException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1, "inclusion")); } Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultTemporalExtent.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -31,6 +31,8 @@ import org.opengis.referencing.operation import org.apache.sis.metadata.iso.ISOMetadata; import org.apache.sis.internal.util.TemporalUtilities; import org.apache.sis.internal.metadata.ReferencingServices; +import org.apache.sis.xml.NilObject; +import org.apache.sis.xml.NilReason; /** @@ -60,7 +62,7 @@ import org.apache.sis.internal.metadata. * @author Martin Desruisseaux (IRD, Geomatys) * @author Touraïvane (IRD) * @author Cédric Briançon (Geomatys) - * @version 0.3 + * @version 0.8 * @since 0.3 * @module */ @@ -242,4 +244,49 @@ public class DefaultTemporalExtent exten checkWritePermission(); ReferencingServices.getInstance().setBounds(envelope, this); } + + /** + * Sets this temporal extent to the intersection of this extent with the specified one. + * If there is no intersection between the two extents, then this method sets the temporal primitive to nil. + * If either this extent or the specified extent has nil primitive, then the intersection result will also be nil. + * + * @param other the temporal extent to intersect with this extent. + * @throws UnsupportedOperationException if no implementation of {@code TemporalFactory} has been found + * on the classpath. + * + * @see Extents#intersection(TemporalExtent, TemporalExtent) + * @see org.apache.sis.geometry.GeneralEnvelope#intersect(Envelope) + * + * @since 0.8 + */ + public void intersect(final TemporalExtent other) { + checkWritePermission(); + final TemporalPrimitive ot = other.getExtent(); + if (ot != null && !(extent instanceof NilObject)) { + if (extent == null || (ot instanceof NilObject)) { + extent = ot; + } else { + Date t0 = getTime(extent, true); + Date t1 = getTime(extent, false); + Date h0 = getTime(ot, true); + Date h1 = getTime(ot, false); + boolean changed = false; + if (h0 != null && (t0 == null || h0.after(t0))) { + t0 = h0; + changed = true; + } + if (h1 != null && (t1 == null || h1.before(t1))) { + t1 = h1; + changed = true; + } + if (changed) { + if (t0 != null && t1 != null && t0.after(t1)) { + extent = NilReason.MISSING.createNilObject(TemporalPrimitive.class); + } else { + setBounds(t0, t1); + } + } + } + } + } } Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/DefaultVerticalExtent.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -21,12 +21,20 @@ import javax.xml.bind.annotation.XmlElem import javax.xml.bind.annotation.XmlRootElement; import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; import org.opengis.geometry.Envelope; +import org.opengis.util.FactoryException; import org.opengis.referencing.crs.VerticalCRS; +import org.opengis.referencing.operation.MathTransform1D; import org.opengis.referencing.operation.TransformException; +import org.opengis.geometry.MismatchedReferenceSystemException; import org.opengis.metadata.extent.VerticalExtent; import org.apache.sis.metadata.iso.ISOMetadata; import org.apache.sis.internal.jaxb.gco.GO_Real; import org.apache.sis.internal.metadata.ReferencingServices; +import org.apache.sis.math.MathFunctions; +import org.apache.sis.util.resources.Errors; +import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.Utilities; +import org.apache.sis.xml.NilReason; /** @@ -55,7 +63,7 @@ import org.apache.sis.internal.metadata. * @author Martin Desruisseaux (IRD, Geomatys) * @author Touraïvane (IRD) * @author Cédric Briançon (Geomatys) - * @version 0.3 + * @version 0.8 * @since 0.3 * @module */ @@ -241,4 +249,118 @@ public class DefaultVerticalExtent exten checkWritePermission(); ReferencingServices.getInstance().setBounds(envelope, this); } + + /** + * Sets this vertical extent to the intersection of this extent with the specified one. + * The {@linkplain org.apache.sis.referencing.crs.DefaultVerticalCRS#getDatum() vertical datum} + * must be the same (ignoring metadata) for both extents; this method does not perform datum shift. + * However this method can perform unit conversions. + * + * <p>If there is no intersection between the two extents, then this method sets both minimum and + * maximum values to {@linkplain Double#NaN}. If either this extent or the specified extent has NaN + * bounds, then the corresponding bounds of the intersection result will also be NaN.</p> + * + * @param other the vertical extent to intersect with this extent. + * @throws MismatchedReferenceSystemException if the two extents do not use the same datum, ignoring metadata. + * + * @see Extents#intersection(VerticalExtent, VerticalExtent) + * @see org.apache.sis.geometry.GeneralEnvelope#intersect(Envelope) + * + * @since 0.8 + */ + public void intersect(final VerticalExtent other) throws MismatchedReferenceSystemException { + checkWritePermission(); + ArgumentChecks.ensureNonNull("other", other); + Double min = other.getMinimumValue(); + Double max = other.getMaximumValue(); + try { + final MathTransform1D cv = getConversionFrom(other.getVerticalCRS()); + if (isReversing(cv, min, max)) { + Double tmp = min; + min = max; + max = tmp; + } + /* + * If minimumValue is NaN, keep it unchanged (because x > minimumValue is false) + * in order to preserve the NilReason. Conversely if min is NaN, then we want to + * take it without conversion for preserving its NilReason. + */ + if (min != null) { + if (minimumValue == null || min.isNaN() || (min = convert(cv, min)) > minimumValue) { + minimumValue = min; + } + } + if (max != null) { + if (maximumValue == null || max.isNaN() || (max = convert(cv, max)) < maximumValue) { + maximumValue = max; + } + } + } catch (UnsupportedOperationException | FactoryException | ClassCastException | TransformException e) { + throw new MismatchedReferenceSystemException(Errors.format(Errors.Keys.IncompatiblePropertyValue_1, "verticalCRS"), e); + } + if (minimumValue != null && maximumValue != null && minimumValue > maximumValue) { + minimumValue = maximumValue = NilReason.MISSING.createNilObject(Double.class); + } + } + + /** + * Returns the conversion from the given CRS to the CRS of this extent, or {@code null} if none or unknown. + * The returned {@code MathTransform1D} may apply unit conversions or axis direction reversal, but usually + * not datum shift. + * + * @param source the CRS from which to perform the conversions, or {@code null} if unknown. + * @return the conversion from {@code source}, or {@code null} if none or unknown. + * @throws UnsupportedOperationException if the {@code sis-referencing} module is not on the classpath. + * @throws FactoryException if the coordinate operation factory is not available. + * @throws ClassCastException if the conversion is not an instance of {@link MathTransform1D}. + */ + private MathTransform1D getConversionFrom(final VerticalCRS source) throws FactoryException { + if (!Utilities.equalsIgnoreMetadata(verticalCRS, source) && verticalCRS != null && source != null) { + final MathTransform1D cv = (MathTransform1D) ReferencingServices.getInstance() + .getCoordinateOperationFactory(null, null, null, null) + .createOperation(source, verticalCRS).getMathTransform(); + if (!cv.isIdentity()) { + return cv; + } + } + return null; + } + + /** + * Returns {@code true} if the given conversion seems to change the axis direction. + * This happen for example with conversions from "Elevation" axis to "Depth" axis. + * In case of doubt, this method returns {@code false}. + * + * <div class="note"><b>Note about alternatives:</b> + * we could compare axis directions instead, but it would not work with user-defined directions + * or user-defined unit conversions with negative scale factor (should never happen, but we are + * paranoiac). We could compare the minimum and maximum values after conversions, but it would + * not work if one or both values are {@code null} or {@code NaN}. Since we want to preserve + * {@link NilReason}, we still need to know if axes are reversed in order to put the nil reason + * in the right location.</div> + * + * @param cv the conversion computed by {@link #getConversionFrom(VerticalCRS)} (may be {@code null}). + * @param sample the minimum or the maximum value. + * @param other the minimum or maximum value at the opposite bound. + * @return {@code true} if the axis direction is reversed at the given value. + */ + private static boolean isReversing(final MathTransform1D cv, Double sample, final Double other) throws TransformException { + if (cv == null) { + return false; + } + if (sample == null || sample.isNaN()) { + sample = other; + } else if (other != null && !other.isNaN()) { + sample = (sample + other) / 2; + } + return MathFunctions.isNegative(cv.derivative(sample != null ? sample : Double.NaN)); + } + + /** + * Converts the given value with the given transform if non-null. This converter can generally + * not perform datum shift; the operation is merely unit conversion and change of axis direction. + */ + private static Double convert(MathTransform1D tr, Double value) throws TransformException { + return (tr != null) ? tr.transform(value) : value; + } } Modified: sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/main/java/org/apache/sis/metadata/iso/extent/Extents.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -29,6 +29,8 @@ import org.opengis.metadata.extent.Tempo import org.opengis.metadata.extent.BoundingPolygon; import org.opengis.metadata.extent.GeographicExtent; import org.opengis.metadata.extent.GeographicBoundingBox; +import org.opengis.metadata.extent.GeographicDescription; +import org.opengis.geometry.MismatchedReferenceSystemException; import org.opengis.referencing.cs.CoordinateSystemAxis; import org.opengis.referencing.cs.AxisDirection; import org.opengis.referencing.crs.VerticalCRS; @@ -45,6 +47,7 @@ import org.apache.sis.measure.Range; import org.apache.sis.util.resources.Vocabulary; import org.apache.sis.util.resources.Errors; import org.apache.sis.util.ArgumentChecks; +import org.apache.sis.util.ComparisonMode; import org.apache.sis.util.Static; import static java.lang.Math.*; @@ -437,33 +440,6 @@ public final class Extents extends Stati } /** - * Returns the intersection of the given geographic bounding boxes. If any of the arguments is {@code null}, - * then this method returns the other argument (which may be null). Otherwise this method returns a box which - * is the intersection of the two given boxes. - * - * <p>This method never modify the given boxes, but may return directly one of the given arguments if it - * already represents the intersection result.</p> - * - * @param b1 the first bounding box, or {@code null}. - * @param b2 the second bounding box, or {@code null}. - * @return the intersection (may be any of the {@code b1} or {@code b2} argument if unchanged), - * or {@code null} if the two given boxes are null. - * @throws IllegalArgumentException if the {@linkplain DefaultGeographicBoundingBox#getInclusion() inclusion status} - * is not the same for both boxes. - * - * @see DefaultGeographicBoundingBox#intersect(GeographicBoundingBox) - * - * @since 0.4 - */ - public static GeographicBoundingBox intersection(final GeographicBoundingBox b1, final GeographicBoundingBox b2) { - if (b1 == null) return b2; - if (b2 == null || b2 == b1) return b1; - final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox(b1); - box.intersect(b2); - return box; - } - - /** * Returns an <em>estimation</em> of the area (in square metres) of the given bounding box. * Since {@code GeographicBoundingBox} provides only approximative information (for example * it does not specify the datum), the value returned by this method is also approximative. @@ -497,4 +473,145 @@ public final class Extents extends Stati max(0, sin(toRadians(box.getNorthBoundLatitude())) - sin(toRadians(box.getSouthBoundLatitude()))); } + + /** + * Returns the intersection of the given geographic bounding boxes. If any of the arguments is {@code null}, + * then this method returns the other argument (which may be null). Otherwise this method returns a box which + * is the intersection of the two given boxes. + * + * <p>This method never modify the given boxes, but may return directly one of the given arguments if it + * already represents the intersection result.</p> + * + * @param b1 the first bounding box, or {@code null}. + * @param b2 the second bounding box, or {@code null}. + * @return the intersection (may be any of the {@code b1} or {@code b2} argument if unchanged), + * or {@code null} if the two given boxes are null. + * @throws IllegalArgumentException if the {@linkplain DefaultGeographicBoundingBox#getInclusion() inclusion status} + * is not the same for both boxes. + * + * @see DefaultGeographicBoundingBox#intersect(GeographicBoundingBox) + * + * @since 0.4 + */ + public static GeographicBoundingBox intersection(final GeographicBoundingBox b1, final GeographicBoundingBox b2) { + if (b1 == null) return b2; + if (b2 == null || b2 == b1) return b1; + final DefaultGeographicBoundingBox box = new DefaultGeographicBoundingBox(b1); + box.intersect(b2); + if (box.equals(b1, ComparisonMode.BY_CONTRACT)) return b1; + if (box.equals(b2, ComparisonMode.BY_CONTRACT)) return b2; + return box; + } + + /** + * May compute an intersection between the given geographic extents. + * Current implementation supports only {@link GeographicBoundingBox}; + * all other kinds are handled as if they were {@code null}. + * + * <p>We may improve this method in future Apache SIS version, but it is not yet clear how. + * For example how to handle {@link GeographicDescription} or {@link BoundingPolygon}? + * This method should not be public before we find a better contract.</p> + */ + static GeographicExtent intersection(final GeographicExtent e1, final GeographicExtent e2) { + return intersection(e1 instanceof GeographicBoundingBox ? (GeographicBoundingBox) e1 : null, + e2 instanceof GeographicBoundingBox ? (GeographicBoundingBox) e2 : null); + } + + /** + * Returns the intersection of the given vertical extents. If any of the arguments is {@code null}, + * then this method returns the other argument (which may be null). Otherwise this method returns a + * vertical extent which is the intersection of the two given extents. + * + * <p>This method never modify the given extents, but may return directly one of the given arguments + * if it already represents the intersection result.</p> + * + * <div class="section">Advantage and inconvenient of this method</div> + * This method can not intersect extents defined with different datums because height transformations + * generally require the geodetic positions (latitudes and longitudes) of the heights to transform. + * For more general transformations, it is better to convert all extent components into a single envelope, + * then {@linkplain org.apache.sis.geometry.Envelopes#transform(CoordinateOperation, Envelope) transform + * the envelope at once}. On the other hand, this {@code intersect(…)} method preserves better + * the {@link org.apache.sis.xml.NilReason} (if any). + * + * @param e1 the first extent, or {@code null}. + * @param e2 the second extent, or {@code null}. + * @return the intersection (may be any of the {@code e1} or {@code e2} argument if unchanged), + * or {@code null} if the two given extents are null. + * @throws MismatchedReferenceSystemException if the two extents do not use the same datum, ignoring metadata. + * + * @see DefaultVerticalExtent#intersect(VerticalExtent) + * + * @since 0.8 + */ + public static VerticalExtent intersection(final VerticalExtent e1, final VerticalExtent e2) { + if (e1 == null) return e2; + if (e2 == null || e2 == e1) return e1; + final DefaultVerticalExtent extent = new DefaultVerticalExtent(e1); + extent.intersect(e2); + if (extent.equals(e1, ComparisonMode.BY_CONTRACT)) return e1; + if (extent.equals(e2, ComparisonMode.BY_CONTRACT)) return e2; + return extent; + } + + /** + * Returns the intersection of the given temporal extents. If any of the arguments is {@code null}, + * then this method returns the other argument (which may be null). Otherwise this method returns a + * temporal extent which is the intersection of the two given extents. + * + * <p>This method never modify the given extents, but may return directly one of the given arguments + * if it already represents the intersection result.</p> + * + * @param e1 the first extent, or {@code null}. + * @param e2 the second extent, or {@code null}. + * @return the intersection (may be any of the {@code e1} or {@code e2} argument if unchanged), + * or {@code null} if the two given extents are null. + * @throws UnsupportedOperationException if no implementation of {@code TemporalFactory} has been found + * on the classpath. + * + * @see DefaultTemporalExtent#intersect(TemporalExtent) + * + * @since 0.8 + */ + public static TemporalExtent intersection(final TemporalExtent e1, final TemporalExtent e2) { + if (e1 == null) return e2; + if (e2 == null || e2 == e1) return e1; + final DefaultTemporalExtent extent = new DefaultTemporalExtent(e1); + extent.intersect(e2); + if (extent.equals(e1, ComparisonMode.BY_CONTRACT)) return e1; + if (extent.equals(e2, ComparisonMode.BY_CONTRACT)) return e2; + return extent; + } + + /** + * Returns the intersection of the given extents. If any of the arguments is {@code null}, + * then this method returns the other argument (which may be null). Otherwise this method + * returns an extent which is the intersection of all geographic, vertical and temporal + * elements in the two given extents. + * + * <p>This method never modify the given extents, but may return directly one of the given + * arguments if it already represents the intersection result.</p> + * + * @param e1 the first extent, or {@code null}. + * @param e2 the second extent, or {@code null}. + * @return the intersection (may be any of the {@code e1} or {@code e2} argument if unchanged), + * or {@code null} if the two given extents are null. + * @throws IllegalArgumentException if two elements to intersect are not compatible (e.g. mismatched + * {@linkplain DefaultGeographicBoundingBox#getInclusion() bounding box inclusion status} or + * mismatched {@linkplain DefaultVerticalExtent#getVerticalCRS() vertical datum}). + * @throws UnsupportedOperationException if a {@code TemporalFactory} is required but no implementation + * has been found on the classpath. + * + * @see DefaultExtent#intersect(Extent) + * + * @since 0.8 + */ + public static Extent intersection(final Extent e1, final Extent e2) { + if (e1 == null) return e2; + if (e2 == null || e2 == e1) return e1; + final DefaultExtent extent = new DefaultExtent(e1); + extent.intersect(e2); + if (extent.equals(e1, ComparisonMode.BY_CONTRACT)) return e1; + if (extent.equals(e2, ComparisonMode.BY_CONTRACT)) return e2; + return extent; + } } Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/NameMeaningTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/NameMeaningTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/NameMeaningTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/NameMeaningTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -16,10 +16,14 @@ */ package org.apache.sis.internal.metadata; +import javax.measure.Unit; import org.opengis.referencing.cs.*; import org.opengis.referencing.crs.*; import org.opengis.referencing.datum.*; import org.opengis.referencing.ReferenceSystem; +import org.opengis.referencing.operation.OperationMethod; +import org.opengis.referencing.operation.CoordinateOperation; +import org.opengis.parameter.ParameterDescriptor; import org.apache.sis.test.DependsOnMethod; import org.apache.sis.test.TestCase; import org.junit.Test; @@ -41,19 +45,23 @@ public final strictfp class NameMeaningT */ @Test public void testToObjectType() { - assertEquals("crs", NameMeaning.toObjectType(GeographicCRS .class)); - assertEquals("crs", NameMeaning.toObjectType(ProjectedCRS .class)); - assertEquals("crs", NameMeaning.toObjectType(VerticalCRS .class)); - assertEquals("crs", NameMeaning.toObjectType(TemporalCRS .class)); - assertEquals("datum", NameMeaning.toObjectType(GeodeticDatum .class)); - assertEquals("datum", NameMeaning.toObjectType(VerticalDatum .class)); - assertEquals("datum", NameMeaning.toObjectType(TemporalDatum .class)); - assertEquals("ellipsoid", NameMeaning.toObjectType(Ellipsoid .class)); - assertEquals("meridian", NameMeaning.toObjectType(PrimeMeridian .class)); - assertEquals("cs", NameMeaning.toObjectType(EllipsoidalCS .class)); - assertEquals("cs", NameMeaning.toObjectType(CartesianCS .class)); - assertEquals("axis", NameMeaning.toObjectType(CoordinateSystemAxis.class)); - assertEquals("referenceSystem", NameMeaning.toObjectType(ReferenceSystem .class)); + assertEquals("crs", NameMeaning.toObjectType(GeographicCRS .class)); + assertEquals("crs", NameMeaning.toObjectType(ProjectedCRS .class)); + assertEquals("crs", NameMeaning.toObjectType(VerticalCRS .class)); + assertEquals("crs", NameMeaning.toObjectType(TemporalCRS .class)); + assertEquals("datum", NameMeaning.toObjectType(GeodeticDatum .class)); + assertEquals("datum", NameMeaning.toObjectType(VerticalDatum .class)); + assertEquals("datum", NameMeaning.toObjectType(TemporalDatum .class)); + assertEquals("ellipsoid", NameMeaning.toObjectType(Ellipsoid .class)); + assertEquals("meridian", NameMeaning.toObjectType(PrimeMeridian .class)); + assertEquals("cs", NameMeaning.toObjectType(EllipsoidalCS .class)); + assertEquals("cs", NameMeaning.toObjectType(CartesianCS .class)); + assertEquals("axis", NameMeaning.toObjectType(CoordinateSystemAxis.class)); + assertEquals("referenceSystem", NameMeaning.toObjectType(ReferenceSystem .class)); + assertEquals("coordinateOperation", NameMeaning.toObjectType(CoordinateOperation .class)); + assertEquals("method", NameMeaning.toObjectType(OperationMethod .class)); + assertEquals("parameter", NameMeaning.toObjectType(ParameterDescriptor .class)); + assertEquals("uom", NameMeaning.toObjectType(Unit .class)); } /** @@ -64,7 +72,9 @@ public final strictfp class NameMeaningT @Test @DependsOnMethod("testToObjectType") public void testToURN() { + assertEquals("urn:ogc:def:crs:EPSG::4326", NameMeaning.toURN(GeodeticCRS.class, "EPSG", null, "4326")); assertEquals("urn:ogc:def:crs:OGC:1.3:CRS84", NameMeaning.toURN(GeographicCRS.class, "CRS", null, "84")); assertEquals("urn:ogc:def:datum:EPSG::6326", NameMeaning.toURN(GeodeticDatum.class, "EPSG", null, "6326")); + assertNull ("Authority is not optional.", NameMeaning.toURN(GeographicCRS.class, null, null, "4326")); } } Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/internal/metadata/sql/TestDatabase.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -16,12 +16,9 @@ */ package org.apache.sis.internal.metadata.sql; -import java.nio.file.Files; -import java.nio.file.Path; import java.sql.SQLException; import javax.sql.DataSource; import org.apache.sis.util.Debug; -import org.apache.sis.internal.system.DataDirectory; import static org.junit.Assume.*; @@ -77,21 +74,6 @@ public final strictfp class TestDatabase } /** - * Returns the path to the directory of the given name in {@code $SIS_DATA/Databases}. - * If the directory is not found, then the test will be interrupted by an {@code org.junit.Assume} statement. - * - * @param name the name of the sub-directory. - * @return the path to the given sub-directory. - */ - public static Path directory(final String name) { - Path dir = DataDirectory.DATABASES.getDirectory(); - assumeNotNull("$SIS_DATA/Databases directory not found.", dir); - dir = dir.resolve(name); - assumeTrue("Specified directory not found.", Files.isDirectory(dir)); - return dir; - } - - /** * Creates a Derby database in memory. If no Derby or JavaDB driver is not found, * then the test will be interrupted by an {@code org.junit.Assume} statement. * Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/DefaultExtentTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -17,12 +17,16 @@ package org.apache.sis.metadata.iso.extent; import java.net.URL; +import java.util.Arrays; import java.io.IOException; import javax.xml.bind.JAXBException; +import org.opengis.metadata.extent.Extent; +import org.apache.sis.util.iso.SimpleInternationalString; import org.apache.sis.xml.IdentifierSpace; +import org.apache.sis.xml.Namespaces; +import org.apache.sis.xml.NilObject; import org.apache.sis.test.XMLTestCase; import org.apache.sis.test.DependsOn; -import org.apache.sis.xml.Namespaces; import org.junit.Test; import static org.apache.sis.test.Assert.*; @@ -34,7 +38,7 @@ import static org.apache.sis.test.TestUt * * @author Cédric Briançon (Geomatys) * @author Martin Desruisseaux (Geomatys) - * @version 0.6 + * @version 0.8 * @since 0.3 * @module */ @@ -58,6 +62,40 @@ public final strictfp class DefaultExten } /** + * Tests {@link DefaultExtent#intersect(Extent)}. + */ + @Test + public void testIntersect() { + final DefaultGeographicBoundingBox bounds1 = new DefaultGeographicBoundingBox(10, 20, 30, 40); + final DefaultGeographicBoundingBox bounds2 = new DefaultGeographicBoundingBox(16, 18, 31, 42); + final DefaultGeographicBoundingBox clip = new DefaultGeographicBoundingBox(15, 25, 26, 32); + final DefaultGeographicBoundingBox expected1 = new DefaultGeographicBoundingBox(15, 20, 30, 32); + final DefaultGeographicBoundingBox expected2 = new DefaultGeographicBoundingBox(16, 18, 31, 32); + final DefaultExtent e1 = new DefaultExtent("Somewhere", bounds1, null, null); + final DefaultExtent e2 = new DefaultExtent("Somewhere", clip, null, null); + e1.getGeographicElements().add(bounds2); + e1.intersect(e2); + assertEquals("description", "Somewhere", e1.getDescription().toString()); + assertFalse("isNil(description)", e1.getDescription() instanceof NilObject); + assertArrayEquals("geographicElements", new DefaultGeographicBoundingBox[] { + expected1, expected2 + }, e1.getGeographicElements().toArray()); + /* + * Change the description and test again. That description should be considered missing + * because we have a mismatch. Also change abounding box in such a way that there is no + * intersection. That bounding box should be omitted. + */ + bounds2.setBounds(8, 12, 33, 35); + e1.setGeographicElements(Arrays.asList(bounds1, bounds2)); + e2.setDescription(new SimpleInternationalString("Somewhere else")); + e1.intersect(e2); + assertTrue("isNil(description)", e1.getDescription() instanceof NilObject); + assertArrayEquals("geographicElements", new DefaultGeographicBoundingBox[] { + expected1 + }, e1.getGeographicElements().toArray()); + } + + /** * Tests the (un)marshalling of a {@code <gmd:EX_Extent>} object. * This test opportunistically tests setting {@code "gml:id"} value. * Modified: sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-metadata/src/test/java/org/apache/sis/metadata/iso/extent/ExtentsTest.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -23,7 +23,10 @@ import javax.measure.Unit; import javax.measure.UnitConverter; import javax.measure.IncommensurableException; import org.opengis.geometry.DirectPosition; +import org.opengis.metadata.extent.Extent; +import org.opengis.metadata.extent.VerticalExtent; import org.opengis.metadata.extent.GeographicBoundingBox; +import org.opengis.referencing.operation.TransformException; import org.apache.sis.measure.Units; import org.apache.sis.measure.MeasurementRange; import org.apache.sis.test.mock.VerticalCRSMock; @@ -47,7 +50,7 @@ import static org.junit.Assert.*; * @since 0.4 * @module */ -@DependsOn(DefaultGeographicBoundingBoxTest.class) +@DependsOn({DefaultGeographicBoundingBoxTest.class, DefaultExtentTest.class}) public final strictfp class ExtentsTest extends TestCase { /** * One minute of angle, in degrees. @@ -97,13 +100,45 @@ public final strictfp class ExtentsTest * Tests {@link Extents#intersection(GeographicBoundingBox, GeographicBoundingBox)}. */ @Test - public void testIntersection() { + public void testGeographicIntersection() { final GeographicBoundingBox b1 = new DefaultGeographicBoundingBox(10, 20, 30, 40); final GeographicBoundingBox b2 = new DefaultGeographicBoundingBox(15, 25, 26, 32); - assertEquals(new DefaultGeographicBoundingBox(15, 20, 30, 32), Extents.intersection(b1, b2)); - assertSame(b1, Extents.intersection(b1, null)); + assertEquals("intersect", new DefaultGeographicBoundingBox(15, 20, 30, 32), Extents.intersection(b1, b2)); + assertSame(b1, Extents.intersection(b1, null)); assertSame(b2, Extents.intersection(null, b2)); - assertNull( Extents.intersection(null, null)); + assertNull( Extents.intersection((GeographicBoundingBox) null, (GeographicBoundingBox) null)); + } + + /** + * Tests {@link Extents#intersection(VerticalExtent, VerticalExtent)}. + * This test does not perform any unit conversion, because it would require the use of different CRS. + * For a test with unit conversion, see {@code ServicesForMetadataTest.testVerticalIntersection()} in + * {@code sis-referencing} module. + * + * @throws TransformException should never happen since we do not test transformation in this class. + */ + @Test + public void testVerticalIntersection() throws TransformException { + final VerticalExtent e1 = new DefaultVerticalExtent(10, 20, null); + final VerticalExtent e2 = new DefaultVerticalExtent(15, 25, null); + assertEquals("intersect", new DefaultVerticalExtent(15, 20, null), Extents.intersection(e1, e2)); + assertSame(e1, Extents.intersection(e1, null)); + assertSame(e2, Extents.intersection(null, e2)); + assertNull( Extents.intersection((VerticalExtent) null, (VerticalExtent) null)); + } + + /** + * Tests {@link Extents#intersection(Extent, Extent)}. + * This test is subject to the same limitation than {@link #testVerticalIntersection()}. + */ + @Test + public void testExtentIntersection() { + final Extent e1 = new DefaultExtent(null, new DefaultGeographicBoundingBox(10, 20, 30, 40), new DefaultVerticalExtent(10, 20, null), null); + final Extent e2 = new DefaultExtent(null, new DefaultGeographicBoundingBox(15, 25, 26, 32), new DefaultVerticalExtent(15, 25, null), null); + assertEquals( new DefaultExtent(null, new DefaultGeographicBoundingBox(15, 20, 30, 32), new DefaultVerticalExtent(15, 20, null), null), Extents.intersection(e1, e2)); + assertSame(e1, Extents.intersection(e1, null)); + assertSame(e2, Extents.intersection(null, e2)); + assertNull( Extents.intersection((Extent) null, (Extent) null)); } /** Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/jaxb/referencing/Code.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -170,7 +170,7 @@ public final class Code { Identifier fallback = null; for (final Identifier identifier : identifiers) { final String code = identifier.getCode(); - if (code == null) continue; // Paranoiac check. + if (code == null) continue; // Paranoiac check. if (code.regionMatches(true, 0, "urn:", 0, 4)) { return new Code(identifier); } Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ReferencingUtilities.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -297,15 +297,14 @@ public final class ReferencingUtilities * </ul></div> * * @param object the identified object to view as a properties map. - * @param excludes the keys of properties to exclude from the map. * @return a view of the identified object properties. * * @see IdentifiedObjects#getProperties(IdentifiedObject, String...) * * @since 0.7 */ - public static Map<String,?> getPropertiesForModifiedCRS(final IdentifiedObject object, final String... excludes) { - final Map<String,?> properties = IdentifiedObjects.getProperties(object, excludes); + public static Map<String,?> getPropertiesForModifiedCRS(final IdentifiedObject object) { + final Map<String,?> properties = IdentifiedObjects.getProperties(object, IdentifiedObject.IDENTIFIERS_KEY); final Identifier id = (Identifier) properties.get(IdentifiedObject.NAME_KEY); if (id != null) { String name = id.getCode(); Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -68,6 +68,11 @@ public final class Resources extends Ind public static final short AmbiguousEllipsoid_1 = 1; /** + * Can not create objects of type ‘{0}’ from combined URI. + */ + public static final short CanNotCombineUriAsType_1 = 79; + + /** * Can not compute the coordinate operation derivative. */ public static final short CanNotComputeDerivative = 2; @@ -78,7 +83,7 @@ public final class Resources extends Ind public static final short CanNotConcatenateTransforms_2 = 3; /** - * Can not create an object of group “{1}” as an instance of class ‘{0}’. + * Can not create an object of type “{1}” as an instance of class ‘{0}’. */ public static final short CanNotCreateObjectAsInstanceOf_2 = 4; @@ -98,6 +103,11 @@ public final class Resources extends Ind public static final short CanNotMapAxisToDirection_1 = 6; /** + * Can not parse component {1} in the combined {0,choice,0#URN|1#URL}. + */ + public static final short CanNotParseCombinedReference_2 = 78; + + /** * Target dimension {0} depends on excluded source dimensions. */ public static final short CanNotSeparateTargetDimension_1 = 7; @@ -427,6 +437,11 @@ public final class Resources extends Ind public static final short SingularMatrix = 63; /** + * Combined URI contains unexpected components. + */ + public static final short UnexpectedComponentInURI = 80; + + /** * Unexpected dimension for a coordinate system of type ‘{0}’. */ public static final short UnexpectedDimensionForCS_1 = 64; Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources.properties [ISO-8859-1] Mon Oct 16 10:01:46 2017 @@ -42,12 +42,14 @@ NonConformCRS_3 = The # # Error messages (to be used in exceptions) # -CanNotConcatenateTransforms_2 = Can not concatenate transforms \u201c{0}\u201d and \u201c{1}\u201d. +CanNotCombineUriAsType_1 = Can not create objects of type \u2018{0}\u2019 from combined URI. CanNotComputeDerivative = Can not compute the coordinate operation derivative. -CanNotCreateObjectAsInstanceOf_2 = Can not create an object of group \u201c{1}\u201d as an instance of class \u2018{0}\u2019. +CanNotConcatenateTransforms_2 = Can not concatenate transforms \u201c{0}\u201d and \u201c{1}\u201d. +CanNotCreateObjectAsInstanceOf_2 = Can not create an object of type \u201c{1}\u201d as an instance of class \u2018{0}\u2019. CanNotInferGridSizeFromValues_1 = Can not infer a grid size from the given values in {0} range. CanNotInstantiateGeodeticObject_1 = Can not instantiate geodetic object for \u201c{0}\u201d. CanNotMapAxisToDirection_1 = Can not map an axis from the specified coordinate system to the \u201c{0}\u201d direction. +CanNotParseCombinedReference_2 = Can not parse component {1} in the combined {0,choice,0#URN|1#URL}. CanNotSeparateTargetDimension_1 = Target dimension {0} depends on excluded source dimensions. CanNotTransformEnvelopeToGeodetic = Can not transform envelope to a geodetic reference system. CanNotUseGeodeticParameters_2 = Can not use the {0} geodetic parameters: {1} @@ -96,6 +98,7 @@ NoSuchOperationMethod_1 = No o ParameterNotFound_2 = No parameter named \u201c{1}\u201d has been found in \u201c{0}\u201d. RecursiveCreateCallForCode_2 = Recursive call while creating an object of type \u2018{0}\u2019 for code \u201c{1}\u201d. SingularMatrix = Matrix is singular. +UnexpectedComponentInURI = Combined URI contains unexpected components. UnexpectedDimensionForCS_1 = Unexpected dimension for a coordinate system of type \u2018{0}\u2019. UnitlessParameter_1 = Parameter \u201c{0}\u201d does not expect unit. UnknownAuthority_1 = Authority \u201c{0}\u201d is unknown. Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/Resources_fr.properties [ISO-8859-1] Mon Oct 16 10:01:46 2017 @@ -47,13 +47,15 @@ NonConformCRS_3 = La d # # Error messages (to be used in exceptions) # -CanNotConcatenateTransforms_2 = Les transformations \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb ne peuvent pas \u00eatre combin\u00e9es. +CanNotCombineUriAsType_1 = Ne peut pas cr\u00e9er d\u2019objets de type \u2018{0}\u2019 \u00e0 partir d\u2019un URI combin\u00e9. CanNotComputeDerivative = La d\u00e9riv\u00e9 de l\u2019op\u00e9ration sur les coordonn\u00e9es ne peut pas \u00eatre calcul\u00e9e. -CanNotCreateObjectAsInstanceOf_2 = Ne peut pas cr\u00e9er un objet du groupe \u00ab\u202f{1}\u202f\u00bb comme une instance de la classe \u2018{0}\u2019. +CanNotConcatenateTransforms_2 = Les transformations \u00ab\u202f{0}\u202f\u00bb et \u00ab\u202f{1}\u202f\u00bb ne peuvent pas \u00eatre combin\u00e9es. +CanNotCreateObjectAsInstanceOf_2 = Ne peut pas cr\u00e9er un objet du type \u00ab\u202f{1}\u202f\u00bb comme une instance de la classe \u2018{0}\u2019. CanNotInferGridSizeFromValues_1 = Ne peut pas inf\u00e9rer une taille de grille \u00e0 partir des valeurs donn\u00e9es dans la plage {0}. CanNotInstantiateGeodeticObject_1 = Ne peut pas cr\u00e9er l\u2019objet g\u00e9od\u00e9tique pour \u00ab\u202f{0}\u202f\u00bb. CanNotMapAxisToDirection_1 = Aucun axe du syst\u00e8me de coordonn\u00e9es sp\u00e9cifi\u00e9 n\u2019a pu \u00eatre associ\u00e9 \u00e0 la direction \u00ab\u202f{0}\u202f\u00bb. CanNotSeparateTargetDimension_1 = La dimension de destination {0} d\u00e9pend de dimensions sources qui ont \u00e9t\u00e9 exclues. +CanNotParseCombinedReference_2 = Ne peut pas d\u00e9coder la composante {1} dans l\u2019{0,choice,0#URN|1#URL} combin\u00e9. CanNotTransformEnvelopeToGeodetic = Ne peut pas transformer l\u2019enveloppe vers un r\u00e9f\u00e9rentiel g\u00e9od\u00e9sique. CanNotUseGeodeticParameters_2 = Ne peut pas utiliser les param\u00e8tres g\u00e9od\u00e9siques {0}\u202f: {1} ColinearAxisDirections_2 = Les directions d\u2019axes {0} et {1} sont colin\u00e9aires. @@ -101,6 +103,7 @@ NoSuchOperationMethod_1 = Aucu ParameterNotFound_2 = Aucun param\u00e8tre nomm\u00e9 \u00ab\u202f{1}\u202f\u00bb n\u2019a \u00e9t\u00e9 trouv\u00e9 dans \u00ab\u202f{0}\u202f\u00bb. RecursiveCreateCallForCode_2 = Appels r\u00e9cursifs lors de la cr\u00e9ation d\u2019un objet de type \u2018{0}\u2019 pour le code \u00ab\u202f{1}\u202f\u00bb. SingularMatrix = La matrice est singuli\u00e8re. +UnexpectedComponentInURI = L\u2019URI combin\u00e9 contient des composantes qui n\u2019\u00e9taient pas attendues. UnexpectedDimensionForCS_1 = Dimension inattendue pour un syst\u00e8me de coordonn\u00e9es de type \u2018{0}\u2019. UnitlessParameter_1 = Le param\u00e8tre \u00ab\u202f{0}\u202f\u00bb n\u2019attend pas d\u2019unit\u00e9. UnknownAuthority_1 = L\u2019autorit\u00e9 \u00ab\u202f{0}\u202f\u00bb n\u2019est pas reconnue. Modified: sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java URL: http://svn.apache.org/viewvc/sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java?rev=1812269&r1=1812268&r2=1812269&view=diff ============================================================================== --- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] (original) +++ sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/internal/referencing/ServicesForMetadata.java [UTF-8] Mon Oct 16 10:01:46 2017 @@ -664,6 +664,8 @@ public final class ServicesForMetadata e * If the given properties are empty and the {@code mtFactory} is the system default, then this method * returns the system default {@code CoordinateOperationFactory} instead of creating a new one. * + * <p>It is okay to set all parameters to {@code null} in order to get the system default factory.</p> + * * @param properties the default properties. * @param mtFactory the math transform factory to use. * @param crsFactory the factory to use if the operation factory needs to create CRS for intermediate steps.