sis-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From desruisse...@apache.org
Subject svn commit: r1726825 - in /sis/branches/JDK8/core: sis-referencing/src/main/java/org/apache/sis/referencing/ sis-referencing/src/main/java/org/apache/sis/referencing/factory/ sis-referencing/src/test/java/org/apache/sis/referencing/ sis-utility/src/mai...
Date Tue, 26 Jan 2016 15:37:27 GMT
Author: desruisseaux
Date: Tue Jan 26 15:37:27 2016
New Revision: 1726825

URL: http://svn.apache.org/viewvc?rev=1726825&view=rev
Log:
Implement IdentifiedObjects.lookup(...) methods.

Modified:
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
    sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
    sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
    sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/CRS.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -132,6 +132,7 @@ public final class CRS extends Static {
      * @throws NoSuchAuthorityCodeException If there is no known CRS associated to the given
code.
      * @throws FactoryException if the CRS creation failed for an other reason.
      *
+     * @see #getAuthorityFactory()
      * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory
      *
      * @category factory
@@ -541,4 +542,34 @@ check:  while (lower != 0 || upper != di
         ArgumentChecks.ensureNonNull("crs", crs);
         return ReferencingUtilities.getGreenwichLongitude(crs.getDatum().getPrimeMeridian(),
NonSI.DEGREE_ANGLE);
     }
+
+    /**
+     * Returns the system-wide authority factory used by {@link #forCode(String)} and other
SIS methods.
+     * By default, this factory is an instance of {@link org.apache.sis.referencing.factory.MultiAuthoritiesFactory}
+     * capable to process at least some EPSG and WMS codes. The set of EPSG codes that are
guaranteed to be supported
+     * is listed in {@link #forCode(String)}. Other authorities may also be supported if
their factories are declared
+     * in the following file:
+     *
+     * {@preformat text
+     *     META-INF/services/org.opengis.referencing.crs.CRSAuthorityFactory
+     * }
+     *
+     * <div class="section">Factories of other kinds</div>
+     * By default the returned factory can also be used as a
+     * {@link org.opengis.referencing.cs.CSAuthorityFactory},
+     * {@link org.opengis.referencing.datum.DatumAuthorityFactory} or
+     * {@link org.opengis.referencing.operation.CoordinateOperationAuthorityFactory}.
+     * However callers are encouraged to verify the type before to cast
+     * since a future SIS version may allow users to set a custom factory.
+     *
+     * @return The system-wide authority factory used by SIS.
+     *
+     * @see #forCode(String)
+     * @see org.apache.sis.referencing.factory.MultiAuthoritiesFactory
+     *
+     * @since 0.7
+     */
+    public static CRSAuthorityFactory getAuthorityFactory() {
+        return AuthorityFactories.ALL;
+    }
 }

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/IdentifiedObjects.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -24,6 +24,7 @@ import java.util.Collection;
 
 import org.opengis.util.NameSpace;
 import org.opengis.util.GenericName;
+import org.opengis.util.FactoryException;
 import org.opengis.metadata.Identifier;
 import org.opengis.metadata.citation.Citation;
 import org.opengis.referencing.IdentifiedObject;
@@ -31,11 +32,15 @@ import org.opengis.referencing.operation
 
 import org.apache.sis.util.Static;
 import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.logging.Logging;
 import org.apache.sis.util.iso.DefaultNameSpace;
-import org.apache.sis.metadata.iso.citation.Citations; // For javadoc.
+import org.apache.sis.internal.system.Loggers;
+import org.apache.sis.internal.metadata.NameMeaning;
 import org.apache.sis.internal.metadata.NameToIdentifier;
+import org.apache.sis.metadata.iso.citation.Citations;
+import org.apache.sis.referencing.factory.IdentifiedObjectFinder;
 
-import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
 import static org.apache.sis.internal.util.Citations.iterator;
 import static org.apache.sis.internal.util.Citations.identifierMatches;
 
@@ -46,7 +51,7 @@ import static org.apache.sis.internal.ut
  * @author  Martin Desruisseaux (IRD, Geomatys)
  * @author  Guilhem Legal (Geomatys)
  * @since   0.4
- * @version 0.5
+ * @version 0.7
  * @module
  *
  * @see CRS
@@ -99,8 +104,8 @@ public final class IdentifiedObjects ext
      * @return An view of the identified object as an immutable map.
      */
     public static Map<String,?> getProperties(final IdentifiedObject object, final
String... excludes) {
-        ensureNonNull("object", object);
-        ensureNonNull("excludes", excludes);
+        ArgumentChecks.ensureNonNull("object", object);
+        ArgumentChecks.ensureNonNull("excludes", excludes);
         return new Properties(object, excludes);
     }
 
@@ -366,6 +371,139 @@ public final class IdentifiedObjects ext
     }
 
     /**
+     * Looks up a URN, such as {@code "urn:ogc:def:crs:EPSG:8.2:4326"}, of the specified
object.
+     * This method searches in all {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory
geodetic
+     * authority factories} known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE
+     * approximatively equals} to the specified object. If such an object is found, then
the URN for the given
+     * authority is returned. Otherwise or if there is ambiguity, this method returns {@code
null}.
+     *
+     * <p><strong>Note that this method checks the identifier validity.</strong>
+     * If the given object declares explicitly an identifier, then this method will instantiate
an object from the
+     * authority factory using that identifier and compare it with the given object. If the
comparison fails, then
+     * this method returns {@code null}. Consequently this method may return {@code null}
even if the given object
+     * declares explicitly its identifier. If the declared identifier is wanted unconditionally,
use the following
+     * pattern instead:
+     *
+     * {@preformat java
+     *     String urn = toURN(object.getClass(), getIdentifier(object, authority));
+     * }
+     *
+     * @param  object The object (usually a {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+     *         coordinate reference system}) whose identifier is to be found, or {@code null}.
+     * @param  authority The authority for the identifier to return, or {@code null} for
+     *         the first identifier regardless its authority.
+     * @return The identifier, or {@code null} if none was found without ambiguity or if
the given object was null.
+     * @throws FactoryException if an error occurred during the search.
+     *
+     * @see #newFinder()
+     * @see #toURN(Class, Identifier)
+     *
+     * @since 0.7
+     */
+    public static String lookupURN(final IdentifiedObject object, final Citation authority)
throws FactoryException {
+        String urn = null;
+        if (object != null) {
+            for (final IdentifiedObject candidate : newFinder().find(object)) {
+                final Identifier id = getIdentifier(candidate, authority);
+                if (id != null) {
+                    final String previous = urn;
+                    urn = NameMeaning.toURN(candidate.getClass(), id.getCodeSpace(), id.getVersion(),
id.getCode());
+                    if (previous != null && !previous.equals(urn)) {
+                        return null;
+                    }
+                }
+            }
+        }
+        return urn;
+    }
+
+    /**
+     * Looks up an EPSG code, such as {@code 4326}, of the specified object. This method
searches in EPSG factories
+     * known to SIS for an object {@linkplain org.apache.sis.util.ComparisonMode#APPROXIMATIVE
approximatively equals}
+     * to the specified object. If such an object is found, then its EPSG identifier is returned.
+     * Otherwise or if there is ambiguity, this method returns {@code null}.
+     *
+     * <p><strong>Note that this method checks the identifier validity.</strong>
+     * If the given object declares explicitly an identifier, then this method will instantiate
an object from the
+     * EPSG factory using that identifier and compare it with the given object. If the comparison
fails, then this
+     * method returns {@code null}. Consequently this method may return {@code null} even
if the given object
+     * declares explicitly its identifier. If the declared identifier is wanted unconditionally,
use the following
+     * pattern instead:
+     *
+     * {@preformat java
+     *     String code = toString(getIdentifier(object, Citations.EPSG));
+     * }
+     *
+     * @param  object The object (usually a {@linkplain org.apache.sis.referencing.crs.AbstractCRS
+     *         coordinate reference system}) whose EPSG code is to be found, or {@code null}.
+     * @return The EPSG code, or {@code null} if none was found without ambiguity or if the
given object was null.
+     * @throws FactoryException if an error occurred during the search.
+     *
+     * @see #newFinder()
+     *
+     * @since 0.7
+     */
+    public static Integer lookupEPSG(final IdentifiedObject object) throws FactoryException
{
+        Integer code = null;
+        if (object != null) {
+            for (final IdentifiedObject candidate : newFinder().find(object)) {
+                final Identifier id = getIdentifier(candidate, Citations.EPSG);
+                if (id != null) try {
+                    Integer previous = code;
+                    code = Integer.valueOf(id.getCode());
+                    if (previous != null && !previous.equals(code)) {
+                        return null;
+                    }
+                } catch (NumberFormatException e) {
+                    Logging.recoverableException(Logging.getLogger(Loggers.CRS_FACTORY),
IdentifiedObjects.class, "lookupEPSG", e);
+                }
+            }
+        }
+        return code;
+    }
+
+    /**
+     * Creates a finder which can be used for looking up unidentified objects.
+     * This method is an alternative to {@code lookup(…)} methods when more control are
desired.
+     *
+     * <div class="note"><b>Example 1: be lenient regarding axis order</b><br>
+     * By default, {@code lookup(…)} methods require that objects in the dataset have their
axes in the
+     * same order than the given object. For relaxing this condition, one can use the following
Java code:
+     *
+     * {@preformat java
+     *     IdentifiedObjectFinder finder = IdentifiedObjects.newFinder();
+     *     finder.setIgnoringAxes(true);
+     *     IdentifiedObject found = finder.findSingleton(object);
+     * }
+     *
+     * This example assumes that at most one object from the dataset will match the given
object.
+     * If more than one object may match, then the call to {@code findSingleton(…)} should
be replaced
+     * by {@code find(…)}.</div>
+     *
+     * <div class="note"><b>Example 2: extend the search to deprecated definitions</b><br>
+     * By default, {@code lookup(…)} methods exclude deprecated objects from the search.
+     * To search also among deprecated objects, one can use the following Java code:
+     *
+     * {@preformat java
+     *     IdentifiedObjectFinder finder = IdentifiedObjects.newFinder();
+     *     finder.setSearchDomain(IdentifiedObjectFinder.Domain.ALL_DATASET);
+     *     Set<IdentifiedObject> found = finder.find(object);
+     * }
+     *
+     * This example does not use the {@code findSingleton(…)} convenience method on the
assumption
+     * that the search may find both deprecated and non-deprecated objects.</div>
+     *
+     * @return A finder to use for looking up unidentified objects.
+     * @throws FactoryException if the finder can not be created.
+     *
+     * @see org.apache.sis.referencing.factory.GeodeticAuthorityFactory#newIdentifiedObjectFinder()
+     * @see IdentifiedObjectFinder#find(IdentifiedObject)
+     */
+    public static IdentifiedObjectFinder newFinder() throws FactoryException {
+        return AuthorityFactories.ALL.newIdentifiedObjectFinder();
+    }
+
+    /**
      * Returns {@code true} if either the {@linkplain AbstractIdentifiedObject#getName()
primary name} or at least
      * one {@linkplain AbstractIdentifiedObject#getAlias() alias} matches the given string
according heuristic rules.
      * If the given object is an instance of {@link AbstractIdentifiedObject}, then this
method delegates to its
@@ -404,12 +542,66 @@ public final class IdentifiedObjects ext
             // We really need to delegate to the overridden method.
             return ((AbstractIdentifiedObject) object).isHeuristicMatchForName(name);
         } else {
-            ensureNonNull("object", object);
+            ArgumentChecks.ensureNonNull("object", object);
             return NameToIdentifier.isHeuristicMatchForName(object.getName(), object.getAlias(),
name);
         }
     }
 
     /**
+     * Returns the URN of the given identifier, or {@code null} if no valid URN can be formed.
+     * The given type should be assignable to one of the given types:
+     *
+     * <table class="sis">
+     *   <caption>Recognized object types in URN</caption>
+     *   <tr><th>Interface</th>                                       
             <th>Type in URN</th>         <th>Meaning</th></tr>
+     *   <tr><td>{@link org.opengis.referencing.cs.CoordinateSystemAxis}</td>
      <td>axis</td>                <td>Coordinate system axe definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.operation.CoordinateOperation}</td>
<td>coordinateOperation</td> <td>Coordinate operation definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.crs.CoordinateReferenceSystem}</td>
<td>crs</td>                 <td>Coordinate reference system definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.cs.CoordinateSystem}</td>
          <td>cs</td>                  <td>Coordinate system definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.Datum}</td>     
             <td>datum</td>               <td>Datum definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.Ellipsoid}</td> 
             <td>ellipsoid</td>           <td>Ellipsoid definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.datum.PrimeMeridian}</td>
          <td>meridian</td>            <td>Prime meridian definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.operation.OperationMethod}</td>
    <td>method</td>              <td>Operation method definition</td></tr>
+     *   <tr><td>{@link org.opengis.parameter.ParameterDescriptor}</td>
            <td>parameter</td>           <td>Operation parameter definition</td></tr>
+     *   <tr><td>{@link org.opengis.referencing.ReferenceSystem}</td> 
             <td>referenceSystem</td>     <td>Value reference system definition</td></tr>
+     *   <tr><td>{@link javax.measure.unit.Unit}</td>                 
             <td>uom</td>                 <td>Unit of measure definition</td></tr>
+     * </table>
+     *
+     * In addition, the identifier codespace shall be one of the following authorities:
+     *
+     * <table class="sis">
+     *   <caption>Recognized authorities in URN</caption>
+     *   <tr><th>Namespace</th> <th>Authority</th>        
<th>Description</th></tr>
+     *   <tr><td>OGC</td>       <td>{@code "EPSG"}</td>   
<td>EPSG dataset</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "OGC"}</td>    
<td>Open Geospatial Consortium</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "OGC-WFS"}</td>
<td>OGC Web Feature Service</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "SI"}</td>     
<td>Système International d'Unités</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "UCUM"}</td>   
<td>Unified Code for Units of Measure</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "UNSD"}</td>   
<td>United Nations Statistics Division</td></tr>
+     *   <tr><td>OGC</td>       <td>{@code "USNO"}</td>   
<td>United States Naval Observatory</td></tr>
+     * </table>
+     *
+     * The reason why the authorities are restricted to the above white list is because this
method formats a URN
+     * in the OGC namespace. Consequently the URN should use only components recognized by
the OGC Naming Authority.
+     *
+     * @param  type A type assignable to one of the types listed in above table.
+     * @param  identifier The identifier for which to format a URN, or {@code null}.
+     * @return The URN for the given identifier, or {@code null} if the given identifier
was null
+     *         or can not be formatted by this method.
+     *
+     * @see #lookupURN(IdentifiedObject, Citation)
+     *
+     * @since 0.7
+     */
+    public static String toURN(final Class<?> type, final Identifier identifier) {
+        ArgumentChecks.ensureNonNull("type", type);
+        if (identifier == null) {
+            return null;
+        }
+        return NameMeaning.toURN(type, identifier.getCodeSpace(), identifier.getVersion(),
identifier.getCode());
+    }
+
+    /**
      * Returns a string representation of the given identifier.
      * This method applies the following rules:
      *

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticAuthorityFactory.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -1149,7 +1149,7 @@ public abstract class GeodeticAuthorityF
     }
 
     /**
-     * Returns a finder which can be used for looking up unidentified objects.
+     * Creates a finder which can be used for looking up unidentified objects.
      * The finder tries to fetch a fully {@linkplain AbstractIdentifiedObject identified
object}
      * from an incomplete one, for example from an object without "{@code ID[…]}" or
      * "{@code AUTHORITY[…]}" element in <cite>Well Known Text</cite>.

Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -1419,7 +1419,7 @@ public class MultiAuthoritiesFactory ext
     }
 
     /**
-     * Returns a finder which can be used for looking up unidentified objects.
+     * Creates a finder which can be used for looking up unidentified objects.
      * The default implementation delegates the lookups to the underlying factories.
      *
      * @return A finder to use for looking up unidentified objects.

Modified: sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/test/java/org/apache/sis/referencing/CRSTest.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -50,7 +50,11 @@ public final strictfp class CRSTest exte
      * Asserts that the result of {@link CRS#forCode(String)} is the given CRS.
      */
     private static void verifyForCode(final SingleCRS expected, final String code) throws
FactoryException {
-        assertTrue(code, Utilities.deepEquals(expected, CRS.forCode(code), ComparisonMode.IGNORE_METADATA));
+        final CoordinateReferenceSystem actual = CRS.forCode(code);
+        assertTrue(code, Utilities.deepEquals(expected, actual, ComparisonMode.DEBUG));
+        if (!EPSGFactoryFallback.FORCE_HARDCODED) {
+            assertSame(code, expected, actual);
+        }
     }
 
     /**
@@ -64,6 +68,7 @@ public final strictfp class CRSTest exte
     public void testForEpsgCode() throws FactoryException {
         verifyForCode(CommonCRS.WGS84 .geographic(),   "EPSG:4326");
         verifyForCode(CommonCRS.WGS84 .geographic(),   "urn:ogc:def:crs:EPSG::4326");
+        verifyForCode(CommonCRS.WGS84 .geographic(),   "urn:x-ogc:def:crs:EPSG::4326");
         verifyForCode(CommonCRS.WGS84 .geographic(),   "http://www.opengis.net/gml/srs/epsg.xml#4326");
         verifyForCode(CommonCRS.WGS72 .geographic(),   "EPSG:4322");
         verifyForCode(CommonCRS.SPHERE.geographic(),   "EPSG:4047");
@@ -100,6 +105,8 @@ public final strictfp class CRSTest exte
         verifyForCode(CommonCRS.WGS84.normalizedGeographic(), "CRS:84");
         verifyForCode(CommonCRS.NAD83.normalizedGeographic(), "CRS:83");
         verifyForCode(CommonCRS.NAD27.normalizedGeographic(), "CRS:27");
+        verifyForCode(CommonCRS.WGS84.normalizedGeographic(), "http://www.opengis.net/gml/srs/crs.xml#84");
+        verifyForCode(CommonCRS.NAD83.normalizedGeographic(), "http://www.opengis.net/gml/srs/crs.xml#83");
     }
 
     /**

Modified: sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java?rev=1726825&r1=1726824&r2=1726825&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
[UTF-8] (original)
+++ sis/branches/JDK8/core/sis-utility/src/main/java/org/apache/sis/internal/util/DefinitionURI.java
[UTF-8] Tue Jan 26 15:37:27 2016
@@ -240,6 +240,9 @@ public final class DefinitionURI {
             upper = uri.indexOf(separator, lower);
             if (upper < 0) {
                 upper = uri.length();
+                if (lower > upper) {
+                    return result;        // Happen if a component is missing.
+                }
             }
             switch (p) {
                 /*



Mime
View raw message