You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@sis.apache.org by de...@apache.org on 2016/03/30 17:21:47 UTC
svn commit: r1737124 - in
/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing:
CRS.java factory/GeodeticObjectFactory.java
operation/AbstractCoordinateOperation.java package-info.java
Author: desruisseaux
Date: Wed Mar 30 15:21:47 2016
New Revision: 1737124
URL: http://svn.apache.org/viewvc?rev=1737124&view=rev
Log:
Added convenience method and javadoc about how to perform a map projection.
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/factory/GeodeticObjectFactory.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.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=1737124&r1=1737123&r2=1737124&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] Wed Mar 30 15:21:47 2016
@@ -44,6 +44,7 @@ import org.opengis.metadata.extent.Exten
import org.opengis.metadata.extent.GeographicBoundingBox;
import org.opengis.referencing.operation.CoordinateOperation;
import org.apache.sis.internal.metadata.AxisDirections;
+import org.apache.sis.internal.referencing.PositionalAccuracyConstant;
import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.referencing.cs.DefaultVerticalCS;
@@ -51,6 +52,7 @@ import org.apache.sis.referencing.cs.Def
import org.apache.sis.referencing.crs.DefaultGeographicCRS;
import org.apache.sis.referencing.crs.DefaultVerticalCRS;
import org.apache.sis.referencing.crs.DefaultCompoundCRS;
+import org.apache.sis.referencing.operation.AbstractCoordinateOperation;
import org.apache.sis.referencing.operation.CoordinateOperationContext;
import org.apache.sis.referencing.operation.DefaultCoordinateOperationFactory;
import org.apache.sis.referencing.factory.UnavailableFactoryException;
@@ -66,13 +68,32 @@ import static java.util.Collections.sing
/**
* Static methods working on {@linkplain CoordinateReferenceSystem Coordinate Reference Systems}.
- * The methods defined in this class can be grouped in two categories:
+ * The methods defined in this class can be grouped in three categories:
*
* <ul>
* <li>Factory methods, the most notable one being {@link #forCode(String)}.</li>
* <li>Methods providing information, like {@link #isHorizontalCRS(CoordinateReferenceSystem)}.</li>
+ * <li>Finding coordinate operations between a source and a target CRS.</li>
* </ul>
*
+ * <div class="section">Usage example</div>
+ * The most frequently used methods in this class are {@link #forCode forCode(…)}, {@link #fromWKT fromWKT(…)}
+ * and {@link #findOperation findOperation(…)}. An usage example is like below:
+ *
+ * {@preformat java
+ * CoordinateReferenceSystem sourceCRS = CRS.forCode("EPSG:4326"); // WGS 84
+ * CoordinateReferenceSystem sourceCRS = CRS.forCode("EPSG:3395"); // WGS 84 / World Mercator
+ * CoordinateOperation operation = CRS.findOperation(sourceCRS, targetCRS, null);
+ * if (CRS.getLinearAccuracy(operation) < 100) {
+ * // If the accuracy is less than 100 metres (or any other threshold at application choice)
+ * // maybe the operation is not suitable. Decide here what to do (throw an exception, etc).
+ * }
+ * MathTransform mt = operation.getMathTransform();
+ * DirectPosition position = new DirectPosition2D(20, 30); // 20°N 30°E (watchout axis order!)
+ * position = operation.transform(position, position);
+ * System.out.println(position);
+ * }
+ *
* <div class="section">Note on kinds of CRS</div>
* The {@link #getSingleComponents(CoordinateReferenceSystem)} method decomposes an arbitrary CRS into a flat
* list of single components. In such flat list, vertical and temporal components can easily be identified by
@@ -218,14 +239,142 @@ public final class CRS extends Static {
}
/**
+ * Creates a coordinate reference system object from a XML string.
+ * Note that the given argument is the XML document itself, <strong>not</strong> a URL to a XML document.
+ * For reading XML documents from readers or input streams,
+ * see static methods in the {@link org.apache.sis.xml.XML} class.
+ *
+ * @param xml Coordinate reference system encoded in XML format.
+ * @return The unmarshalled Coordinate Reference System.
+ * @throws FactoryException if the object creation failed.
+ *
+ * @see org.apache.sis.xml.XML#unmarshal(String)
+ *
+ * @since 0.7
+ */
+ public static CoordinateReferenceSystem fromXML(final String xml) throws FactoryException {
+ ArgumentChecks.ensureNonNull("text", xml);
+ return DefaultFactories.forBuildin(CRSFactory.class).createFromXML(xml);
+ }
+
+ /**
+ * Finds a mathematical operation that transforms or converts coordinates from the given source to the
+ * given target coordinate reference system. If an estimation of the geographic area containing the points
+ * to transform is known, it can be specified for helping this method to find a better suited operation.
+ *
+ * <div class="note"><b>Note:</b>
+ * the area of interest is just one aspect that may affect the coordinate operation.
+ * Other aspects are the time of interest (because some coordinate operations take in account the
+ * plate tectonics movement) or the desired accuracy. For more control on the coordinate operation
+ * to create, see {@link CoordinateOperationContext}.</div>
+ *
+ * After the caller received a {@code CoordinateOperation} instance, the following methods can be invoked
+ * for checking if the operation suits the caller's needs:
+ *
+ * <ul>
+ * <li>{@link #getGeographicBoundingBox(CoordinateOperation)}
+ * for checking if the operation is valid in the caller's area of interest.</li>
+ * <li>{@link #getLinearAccuracy(CoordinateOperation)}
+ * for checking if the operation has sufficient accuracy for caller's purpose.</li>
+ * </ul>
+ *
+ * @param sourceCRS the CRS of source coordinates.
+ * @param targetCRS the CRS of target coordinates.
+ * @param areaOfInterest the area of interest, or {@code null} if none.
+ * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}.
+ * @throws FactoryException if the operation can not be created.
+ *
+ * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
+ *
+ * @since 0.7
+ */
+ public static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS,
+ final GeographicBoundingBox areaOfInterest)
+ throws FactoryException
+ {
+ ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
+ ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
+ CoordinateOperationContext context = null;
+ if (areaOfInterest != null) {
+ final DefaultGeographicBoundingBox bbox = DefaultGeographicBoundingBox.castOrCopy(areaOfInterest);
+ if (bbox.isEmpty()) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "areaOfInterest"));
+ }
+ context = new CoordinateOperationContext();
+ context.setGeographicBoundingBox(bbox);
+ }
+ return CoordinateOperations.factory.createOperation(sourceCRS, targetCRS, context);
+ }
+
+ /**
+ * Returns a positional accuracy estimation in metres for the given operation, or {@code NaN} if unknown.
+ * This method applies the following heuristics:
+ *
+ * <ul>
+ * <li>If the given operation is an instance of {@link AbstractCoordinateOperation}, then delegate to the
+ * operation {@link AbstractCoordinateOperation#getLinearAccuracy() getLinearAccuracy()} method.</li>
+ *
+ * <li>Otherwise if a {@linkplain org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult quantitative result}
+ * is found with a linear unit, then return the result value converted to metres.</li>
+ *
+ * <li>Otherwise if the operation is a {@linkplain org.apache.sis.referencing.operation.DefaultConversion
+ * conversion}, then returns 0 since a conversion is by definition accurate up to rounding errors.</li>
+ *
+ * <li>Otherwise if the operation is a {@linkplain org.apache.sis.referencing.operation.DefaultTransformation
+ * transformation}, then the returned value depends on whether the datum shift were applied with the help
+ * of Bursa-Wolf parameters of not.</li>
+ * </ul>
+ *
+ * See {@link AbstractCoordinateOperation#getLinearAccuracy()} for more details on the above heuristic rules.
+ *
+ * @param operation The coordinate operation for which to get the accuracy estimation, or {@code null}.
+ * @return The accuracy estimation (always in meters), or NaN if unknown.
+ *
+ * @see #findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
+ *
+ * @since 0.7
+ */
+ public static double getLinearAccuracy(final CoordinateOperation operation) {
+ if (operation == null) {
+ return Double.NaN;
+ } else if (operation instanceof AbstractCoordinateOperation) {
+ return ((AbstractCoordinateOperation) operation).getLinearAccuracy();
+ } else {
+ return PositionalAccuracyConstant.getLinearAccuracy(operation);
+ }
+ }
+
+ /**
+ * Returns the valid geographic area for the given coordinate operation, or {@code null} if unknown.
+ * This method explores the {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of validity}
+ * associated with the given operation. If more than one geographic bounding box is found, then they will be
+ * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) added}
+ * together.
+ *
+ * @param operation The coordinate operation for which to get the domain of validity, or {@code null}.
+ * @return The geographic area where the operation is valid, or {@code null} if unspecified.
+ *
+ * @see #findOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, GeographicBoundingBox)
+ * @see Extents#getGeographicBoundingBox(Extent)
+ *
+ * @category information
+ *
+ * @since 0.7
+ */
+ public static GeographicBoundingBox getGeographicBoundingBox(final CoordinateOperation operation) {
+ return (operation != null) ? Extents.getGeographicBoundingBox(operation.getDomainOfValidity()) : null;
+ }
+
+ /**
* Returns the valid geographic area for the given coordinate reference system, or {@code null} if unknown.
- * This method explores the {@linkplain CoordinateReferenceSystem#getDomainOfValidity() domain of validity}
- * associated with the given CRS. If more than one geographic bounding box is found, then they will be
- * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox)
- * added} together.
+ * This method explores the {@linkplain org.apache.sis.referencing.crs.AbstractCRS#getDomainOfValidity() domain of
+ * validity} associated with the given CRS. If more than one geographic bounding box is found, then they will be
+ * {@linkplain org.apache.sis.metadata.iso.extent.DefaultGeographicBoundingBox#add(GeographicBoundingBox) added}
+ * together.
*
- * @param crs The coordinate reference system, or {@code null}.
- * @return The geographic area, or {@code null} if none.
+ * @param crs The coordinate reference system for which to get the domain of validity, or {@code null}.
+ * @return The geographic area where the coordinate reference system is valid, or {@code null} if unspecified.
*
* @see #getEnvelope(CoordinateReferenceSystem)
* @see Extents#getGeographicBoundingBox(Extent)
@@ -596,43 +745,4 @@ check: while (lower != 0 || upper != di
}
return AuthorityFactories.ALL.getAuthorityFactory(CRSAuthorityFactory.class, authority, null);
}
-
- /**
- * Finds a mathematical operation that transforms or converts coordinates from the given source to the
- * given target coordinate reference system. If an estimation of the geographic area containing the points
- * to transform is known, it can be specified for helping this method to find a better suited operation.
- *
- * <p>Note that the area of interest is just one aspect that may affect the coordinate operation.
- * Other aspects are the time of interest (because some coordinate operations take in account the
- * plate tectonics movement) or the desired accuracy. For more control on the coordinate operation
- * to create, see {@link CoordinateOperationContext}.</p>
- *
- * @param sourceCRS the CRS of source coordinates.
- * @param targetCRS the CRS of target coordinates.
- * @param areaOfInterest the area of interest, or {@code null} if none.
- * @return the mathematical operation from {@code sourceCRS} to {@code targetCRS}.
- * @throws FactoryException if the operation can not be created.
- *
- * @see DefaultCoordinateOperationFactory#createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)
- *
- * @since 0.7
- */
- public static CoordinateOperation findOperation(final CoordinateReferenceSystem sourceCRS,
- final CoordinateReferenceSystem targetCRS,
- final GeographicBoundingBox areaOfInterest)
- throws FactoryException
- {
- ArgumentChecks.ensureNonNull("sourceCRS", sourceCRS);
- ArgumentChecks.ensureNonNull("targetCRS", targetCRS);
- CoordinateOperationContext context = null;
- if (areaOfInterest != null) {
- final DefaultGeographicBoundingBox bbox = DefaultGeographicBoundingBox.castOrCopy(areaOfInterest);
- if (bbox.isEmpty()) {
- throw new IllegalArgumentException(Errors.format(Errors.Keys.EmptyArgument_1, "areaOfInterest"));
- }
- context = new CoordinateOperationContext();
- context.setGeographicBoundingBox(bbox);
- }
- return CoordinateOperations.factory.createOperation(sourceCRS, targetCRS, context);
- }
}
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1737124&r1=1737123&r2=1737124&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Wed Mar 30 15:21:47 2016
@@ -1458,6 +1458,7 @@ public class GeodeticObjectFactory exten
* @throws FactoryException if the object creation failed.
*
* @see XML#unmarshal(String)
+ * @see org.apache.sis.referencing.CRS#fromXML(String)
*/
@Override
public CoordinateReferenceSystem createFromXML(final String xml) throws FactoryException {
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1737124&r1=1737123&r2=1737124&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Wed Mar 30 15:21:47 2016
@@ -558,32 +558,33 @@ check: for (int isTarget=0; ; isTar
*
* <ul>
* <li>If a {@linkplain org.apache.sis.metadata.iso.quality.DefaultQuantitativeResult quantitative result}
- * is found with a linear unit, then this accuracy estimate is converted to
- * {@linkplain javax.measure.unit.SI#METRE metres} and returned.</li>
+ * is found with a linear unit, then returns the result value converted to metres.</li>
*
- * <li>Otherwise, if the operation is a {@linkplain DefaultConversion conversion}, then returns 0 since a
- * conversion is by definition accurate up to rounding errors.</li>
+ * <li>Otherwise if the operation is a {@linkplain DefaultConversion conversion},
+ * then returns 0 since a conversion is by definition accurate up to rounding errors.</li>
*
- * <li>Otherwise, if the operation is a {@linkplain DefaultTransformation transformation}, then checks if
- * the datum shift were applied with the help of Bursa-Wolf parameters.
- * If a datum shift has been applied, returns 25 meters.
- * If a datum shift should have been applied but has been omitted, returns 3000 meters.
- *
- * <div class="note"><b>Note:</b>
- * the 3000 meters value is higher than the highest value (999 meters) found in the EPSG
- * database version 6.7. The 25 meters value is the next highest value found in the EPSG
- * database for a significant number of transformations.</div>
- *
- * <li>Otherwise, if the operation is a {@linkplain DefaultConcatenatedOperation concatenated operation},
- * returns the sum of the accuracy of all components. This is a conservative scenario where we assume that
- * errors cumulate linearly.
- *
- * <div class="note"><b>Note:</b>
- * this is not necessarily the "worst case" scenario since the accuracy could be worst if the math transforms
- * are highly non-linear.</div></li>
+ * <li>Otherwise if the operation is a {@linkplain DefaultTransformation transformation},
+ * then checks if the datum shift were applied with the help of Bursa-Wolf parameters.
+ * If a datum shift has been applied, returns 25 meters.
+ * If a datum shift should have been applied but has been omitted, returns 3000 meters.
+ *
+ * <div class="note"><b>Note:</b>
+ * the 3000 meters value is higher than the highest value (999 meters) found in the EPSG
+ * database version 6.7. The 25 meters value is the next highest value found in the EPSG
+ * database for a significant number of transformations.</div>
+ *
+ * <li>Otherwise if the operation is a {@linkplain DefaultConcatenatedOperation concatenated operation},
+ * returns the sum of the accuracy of all components.
+ * This is a conservative scenario where we assume that errors cumulate linearly.
+ *
+ * <div class="note"><b>Note:</b>
+ * this is not necessarily the "worst case" scenario since the accuracy could be worst
+ * if the math transforms are highly non-linear.</div></li>
* </ul>
*
* @return The accuracy estimation (always in meters), or NaN if unknown.
+ *
+ * @see org.apache.sis.referencing.CRS#getLinearAccuracy(CoordinateOperation)
*/
public double getLinearAccuracy() {
return PositionalAccuracyConstant.getLinearAccuracy(this);
Modified: sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java?rev=1737124&r1=1737123&r2=1737124&view=diff
==============================================================================
--- sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java [UTF-8] (original)
+++ sis/branches/JDK8/core/sis-referencing/src/main/java/org/apache/sis/referencing/package-info.java [UTF-8] Wed Mar 30 15:21:47 2016
@@ -26,19 +26,41 @@
* postal address. This package is the root for both kinds, with an emphasis on the one for coordinates.</p>
*
* <div class="section">Fetching geodetic object instances</div>
- * Geodetic objects can be instantiated either directly by specifying all information to a factory method
- * or constructor, or indirectly by specifying the identifier of an entry in a database. In particular,
- * the <a href="http://www.epsg.org">EPSG</a> database provides definitions for many geodetic objects,
+ * Geodetic objects can be instantiated either
+ * {@linkplain org.apache.sis.referencing.factory.GeodeticObjectFactory directly by specifying all information to a factory method or constructor}, or
+ * {@linkplain org.apache.sis.referencing.factory.GeodeticAuthorityFactory indirectly by specifying the identifier of an entry in a database}.
+ * In particular, the <a href="http://www.epsg.org">EPSG</a> database provides definitions for many geodetic objects,
* and Apache SIS provides convenience shortcuts for some of them in the
- * {@link org.apache.sis.referencing.CommonCRS} enumerations.
+ * {@link org.apache.sis.referencing.CommonCRS} enumerations. Other convenience methods are
+ * {@link org.apache.sis.referencing.CRS#forCode(String)},
+ * {@link org.apache.sis.referencing.CRS#fromWKT(String)} and
+ * {@link org.apache.sis.referencing.CRS#fromXML(String)}
+ *
+ * <div class="section">Usage example</div>
+ * The following example projects a (<var>latitude</var>, <var>longitude</var>) coordinate to
+ * a <cite>Universal Transverse Mercator</cite> projection in the zone of the coordinate:
+ *
+ * {@preformat java
+ * CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.geographic();
+ * CoordinateReferenceSystem sourceCRS = CommonCRS.WGS84.UTM(20, 30); // 20°N 30°E (watchout axis order!)
+ * CoordinateOperation operation = CRS.findOperation(sourceCRS, targetCRS, null);
+ * if (CRS.getLinearAccuracy(operation) < 100) {
+ * // If the accuracy is less than 100 metres (or any other threshold at application choice)
+ * // maybe the operation is not suitable. Decide here what to do (throw an exception, etc).
+ * }
+ * MathTransform mt = operation.getMathTransform();
+ * DirectPosition position = new DirectPosition2D(20, 30); // 20°N 30°E (watchout axis order!)
+ * position = operation.transform(position, position);
+ * System.out.println(position);
+ * }
*
* <div class="section">The EPSG database</div>
* The EPSG geodetic parameter dataset is a structured database required to:
*
* <ul>
- * <li>define {@linkplain org.opengis.referencing.crs.CoordinateReferenceSystem Coordinate Reference Systems}
+ * <li>define {@linkplain org.apache.sis.referencing.crs.AbstractCRS Coordinate Reference Systems}
* (CRS) such that coordinates describe positions unambiguously;</li>
- * <li>define {@linkplain org.opengis.referencing.operation.CoordinateOperation Coordinate Operations}
+ * <li>define {@linkplain org.apache.sis.referencing.operation.AbstractCoordinateOperation Coordinate Operations}
* that allow coordinates to be changed from one CRS to another CRS.</li>
* </ul>
*