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 13:25:07 UTC
svn commit: r1737101 [3/7] - in /sis/branches/JDK6: ./
application/sis-console/src/main/artifact/conf/
core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/
core/sis-metadata/src/main/java/org/apache/sis/internal/metadata/sql/
core/sis-meta...
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultGeodeticDatum.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -243,6 +243,13 @@ public class DefaultGeodeticDatum extend
* </tr>
* </table>
*
+ * If Bursa-Wolf parameters are specified, then the prime meridian of their
+ * {@linkplain BursaWolfParameters#getTargetDatum() target datum} shall be either the same than the
+ * {@code primeMeridian} given to this constructor, or Greenwich. This restriction is for avoiding
+ * ambiguity about whether the longitude rotation shall be applied before or after the datum shift.
+ * If the target prime meridian is Greenwich, then the datum shift will be applied in a coordinate
+ * system having Greenwich as the prime meridian.
+ *
* @param properties The properties to be given to the identified object.
* @param ellipsoid The ellipsoid.
* @param primeMeridian The prime meridian.
@@ -265,7 +272,7 @@ public class DefaultGeodeticDatum extend
BursaWolfParameters param = bursaWolf[i];
ensureNonNullElement("bursaWolf", i, param);
param = param.clone();
- param.verify();
+ param.verify(primeMeridian);
bursaWolf[i] = param;
}
}
@@ -368,12 +375,21 @@ public class DefaultGeodeticDatum extend
* 1033 – <cite>Position Vector transformation (geocentric domain)</cite>, or
* 1053 – <cite>Time-dependent Position Vector transformation</cite>.
*
- * <p>If this datum and the given {@code targetDatum} do not use the same
- * {@linkplain #getPrimeMeridian() prime meridian}, then it is caller's responsibility
- * to apply longitude rotation before to use the matrix returned by this method.</p>
- *
- * <div class="section">Search order</div>
- * This method performs the search in the following order:
+ * <p>If this datum and the given {@code targetDatum} do not use the same {@linkplain #getPrimeMeridian() prime meridian},
+ * then it is caller's responsibility to to apply longitude rotation before to use the matrix returned by this method.
+ * The target prime meridian should be Greenwich (see {@linkplain #DefaultGeodeticDatum(Map, Ellipsoid, PrimeMeridian)
+ * constructor javadoc}), in which case the datum shift should be applied in a geocentric coordinate system having
+ * Greenwich as the prime meridian.</p>
+ *
+ * <div class="note"><b>Note:</b>
+ * in EPSG dataset version 8.9, all datum shifts that can be represented by this method use Greenwich as the
+ * prime meridian, both in source and target datum.</div>
+ *
+ * <div class="section">Search criterion</div>
+ * If the given {@code areaOfInterest} is non-null and contains at least one geographic bounding box, then this
+ * method ignores any Bursa-Wolf parameters having a {@linkplain BursaWolfParameters#getDomainOfValidity() domain
+ * of validity} that does not intersect the given geographic extent.
+ * This method performs the search among the remaining parameters in the following order:
* <ol>
* <li>If this {@code GeodeticDatum} contains {@code BursaWolfParameters} having the given
* {@linkplain BursaWolfParameters#getTargetDatum() target datum} (ignoring metadata),
@@ -449,7 +465,7 @@ public class DefaultGeodeticDatum extend
* not a subclass of BursaWolfParameters. This optimisation covers the vast majority of cases.
*/
return bursaWolf.getPositionVectorTransformation(bursaWolf.getClass() != BursaWolfParameters.class ?
- Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway instant.
+ Extents.getDate(areaOfInterest, 0.5) : null); // 0.5 is for choosing midway instant.
}
/**
@@ -530,7 +546,7 @@ public class DefaultGeodeticDatum extend
@Override
public boolean equals(final Object object, final ComparisonMode mode) {
if (object == this) {
- return true; // Slight optimization.
+ return true; // Slight optimization.
}
if (!super.equals(object, mode)) {
return false;
@@ -547,14 +563,10 @@ public class DefaultGeodeticDatum extend
return deepEquals(getEllipsoid(), that.getEllipsoid(), mode) &&
deepEquals(getPrimeMeridian(), that.getPrimeMeridian(), mode);
/*
- * HACK: We do not consider Bursa-Wolf parameters as a non-metadata field.
- * This is needed in order to get equalsIgnoreMetadata(...) to returns
- * 'true' when comparing the WGS84 constant in this class with a WKT
- * DATUM element with a TOWGS84[0,0,0,0,0,0,0] element. Furthermore,
- * the Bursa-Wolf parameters are not part of ISO 19111 specification.
- * We don't want two CRS to be considered as different because one has
- * more of those transformation informations (which is nice, but doesn't
- * change the CRS itself).
+ * Bursa-Wolf parameters are considered ignorable metadata. This is needed in order to get
+ * equalsIgnoreMetadata(…) to return true when comparing WGS84 datums with and without the
+ * WKT 1 "TOWGS84[0,0,0,0,0,0,0]" element. Furthermore those Bursa-Wolf parameters are not
+ * part of ISO 19111 specification.
*/
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/TimeDependentBWP.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.datum
import java.util.Date;
import org.opengis.metadata.extent.Extent;
import org.opengis.referencing.datum.GeodeticDatum;
+import org.opengis.referencing.datum.PrimeMeridian;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.internal.util.DoubleDouble;
@@ -132,8 +133,8 @@ public class TimeDependentBWP extends Bu
* Verifies parameters validity after initialization.
*/
@Override
- void verify() {
- super.verify();
+ void verify(final PrimeMeridian pm) throws IllegalArgumentException {
+ super.verify(pm);
ensureFinite("dtX", dtX);
ensureFinite("dtY", dtY);
ensureFinite("dtZ", dtZ);
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/package-info.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -40,6 +40,18 @@
* DefaultGeodeticDatum.getPositionVectorTransformation(GeodeticDatum, Extent)}</li>
* </ul>
*
+ * <div class="section">Datum shifts</div>
+ * Three classes are provided in support of coordinate transformations between different datums:
+ * <ul>
+ * <li>{@link org.apache.sis.referencing.datum.BursaWolfParameters} performs an approximation
+ * based on a translation, rotation and scale of geocentric coordinates.</li>
+ * <li>{@link org.apache.sis.referencing.datum.TimeDependentBWP} is like {@code BursaWolfParameters},
+ * but varies with time for taking in account the motion of plate tectonic.</li>
+ * <li>{@link org.apache.sis.referencing.datum.DatumShiftGrid} is used for more accurate transformations
+ * than what {@code BursaWolfParameters} allows, by interpolating the geographic or geocentric translations
+ * in a grid (e.g. NADCON or NTv2) instead than apply the same transformation for every points.</li>
+ * </ul>
+ *
* @author Martin Desruisseaux (IRD, Geomatys)
* @author Cédric Briançon (Geomatys)
* @since 0.4
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -640,6 +640,11 @@ public class CommonAuthorityFactory exte
return unit;
}
+ @Override public Unit<?> getUnitReplacement(CoordinateSystemAxis axis, Unit<?> ignored) {
+ assert SI.METRE.equals(ignored) : ignored;
+ return unit;
+ }
+
@Override public boolean accept(CoordinateSystemAxis axis) {
return true;
}
@@ -647,6 +652,10 @@ public class CommonAuthorityFactory exte
@Override public AxisDirection getDirectionReplacement(AxisDirection direction) {
return direction;
}
+
+ @Override public AxisDirection getDirectionReplacement(CoordinateSystemAxis axis, AxisDirection direction) {
+ return direction;
+ }
});
}
/*
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/GeodeticObjectFactory.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -26,6 +26,8 @@ import java.util.logging.Logger;
import java.util.logging.LogRecord;
import java.util.concurrent.atomic.AtomicReference;
import java.lang.reflect.Constructor;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
import javax.measure.unit.Unit;
import javax.measure.quantity.Angle;
import javax.measure.quantity.Length;
@@ -186,8 +188,9 @@ import org.apache.sis.xml.XML;
* since localizations are applied by the {@link InternationalString#toString(Locale)} method.</p>
*
* @author Martin Desruisseaux (IRD, Geomatys)
+ * @author Guilhem Legal (Geomatys)
* @since 0.6
- * @version 0.6
+ * @version 0.7
* @module
*/
public class GeodeticObjectFactory extends AbstractFactory implements CRSFactory, CSFactory, DatumFactory, Parser {
@@ -1524,7 +1527,13 @@ public class GeodeticObjectFactory exten
if (c == null) {
c = Class.forName("org.apache.sis.io.wkt.GeodeticObjectParser").asSubclass(Parser.class)
.getConstructor(Map.class, ObjectFactory.class, MathTransformFactory.class);
- c.setAccessible(true);
+ final Constructor<?> cp = c; // For allowing use in inner class or lambda expression.
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override public Void run() {
+ cp.setAccessible(true);
+ return null;
+ }
+ });
parserConstructor = c;
}
p = c.newInstance(defaultProperties, this, getMathTransformFactory());
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/MultiAuthoritiesFactory.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -751,7 +751,7 @@ public class MultiAuthoritiesFactory ext
if (code == null) {
message = Errors.format(Errors.Keys.MissingComponentInElement_2, s, "code");
} else {
- message = Errors.format(Errors.Keys.CanNotCreateObjectOfType_2, type, uri.type);
+ message = Errors.format(Errors.Keys.CanNotCreateObjectAsInstanceOf_2, type, uri.type);
}
throw new NoSuchAuthorityCodeException(message, authority, code, s);
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/BursaWolfInfo.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/BursaWolfInfo.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/BursaWolfInfo.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/BursaWolfInfo.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -17,14 +17,21 @@
package org.apache.sis.referencing.factory.sql;
import java.util.Locale;
+import java.util.List;
+import java.util.Map;
+import java.util.LinkedHashMap;
import java.sql.ResultSet;
import javax.measure.unit.Unit;
import javax.measure.unit.NonSI;
import javax.measure.unit.SI;
import javax.measure.converter.ConversionException;
+import org.opengis.util.FactoryException;
+import org.opengis.metadata.extent.Extent;
+import org.apache.sis.internal.referencing.ExtentSelector;
import org.apache.sis.referencing.datum.BursaWolfParameters;
import org.apache.sis.referencing.datum.TimeDependentBWP;
import org.apache.sis.referencing.factory.FactoryDataException;
+import org.apache.sis.referencing.factory.GeodeticAuthorityFactory;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.measure.Units;
@@ -123,11 +130,22 @@ final class BursaWolfInfo {
final int target;
/**
+ * The value of {@code AREA_OF_USE_CODE}.
+ */
+ private final int domainOfValidity;
+
+ /**
+ * The domain of validity as an {@code Extent} object.
+ */
+ private Extent extent;
+
+ /**
* Fills a structure with the specified values.
*/
- BursaWolfInfo(final int operation, final int method, final int targetCRS) {
- this.operation = operation;
- this.method = method;
+ BursaWolfInfo(final int operation, final int method, final int targetCRS, final int domainOfValidity) {
+ this.operation = operation;
+ this.method = method;
+ this.domainOfValidity = domainOfValidity;
switch (targetCRS) {
case TARGET_CRS: target = TARGET_DATUM; break;
// More codes may be added in future SIS version.
@@ -155,4 +173,44 @@ final class BursaWolfInfo {
public String toString() {
return String.valueOf(operation);
}
+
+ /**
+ * Gets the domain of validity. The result is cached.
+ *
+ * @param factory The factory to use for creating {@code Extent} instances.
+ */
+ Extent getDomainOfValidity(final GeodeticAuthorityFactory factory) throws FactoryException {
+ if (extent == null && domainOfValidity != 0) {
+ extent = factory.createExtent(String.valueOf(domainOfValidity));
+ }
+ return extent;
+ }
+
+ /**
+ * Given an array of {@code BursaWolfInfo} instances, retains only the instances having the largest
+ * domain of validity for each target datum. If two instances have the same domain of validity, the
+ * first one is retained. This presume that the instances have already been sorted for preference order
+ * before to invoke this method.
+ *
+ * @param factory The factory to use for creating {@code Extent} instances.
+ * @param candidates The Bursa-Wolf parameters candidates.
+ * @param addTo Where to add the instances retained by this method.
+ */
+ static void filter(final GeodeticAuthorityFactory factory, final BursaWolfInfo[] candidates,
+ final List<BursaWolfInfo> addTo) throws FactoryException
+ {
+ final Map<Integer,ExtentSelector<BursaWolfInfo>> added = new LinkedHashMap<Integer,ExtentSelector<BursaWolfInfo>>();
+ for (BursaWolfInfo candidate : candidates) {
+ final Integer target = candidate.target;
+ ExtentSelector<BursaWolfInfo> selector = added.get(target);
+ if (selector == null) {
+ selector = new ExtentSelector<BursaWolfInfo>(null);
+ added.put(target, selector);
+ }
+ selector.evaluate(candidate.getDomainOfValidity(factory), candidate);
+ }
+ for (final ExtentSelector<BursaWolfInfo> select : added.values()) {
+ addTo.add(select.best());
+ }
+ }
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGDataAccess.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -19,7 +19,6 @@ package org.apache.sis.referencing.facto
import java.util.Set;
import java.util.Map;
import java.util.List;
-import java.util.HashSet;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.LinkedHashMap;
@@ -40,7 +39,6 @@ import java.sql.ResultSetMetaData;
import java.sql.Statement;
import java.sql.SQLException;
import java.text.DateFormat;
-import java.text.SimpleDateFormat;
import java.text.ParseException;
import java.net.URI;
import java.net.URISyntaxException;
@@ -72,6 +70,7 @@ import org.apache.sis.internal.metadata.
import org.apache.sis.internal.metadata.sql.SQLUtilities;
import org.apache.sis.internal.referencing.DeprecatedCode;
import org.apache.sis.internal.referencing.EPSGParameterDomain;
+import org.apache.sis.internal.referencing.ReferencingUtilities;
import org.apache.sis.internal.referencing.Formulas;
import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.system.Semaphores;
@@ -107,17 +106,21 @@ import org.apache.sis.util.ArgumentCheck
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Localized;
import org.apache.sis.util.Version;
+import org.apache.sis.util.Workaround;
+import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.collection.Containers;
import org.apache.sis.measure.MeasurementRange;
import org.apache.sis.measure.NumberRange;
import org.apache.sis.measure.Units;
+import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
import static org.apache.sis.internal.referencing.ServicesForMetadata.CONNECTION;
// Branch-dependent imports
import org.apache.sis.internal.jdk7.JDK7;
import org.apache.sis.internal.jdk8.JDK8;
import org.apache.sis.internal.jdk7.AutoCloseable;
+import org.apache.sis.internal.util.StandardDateFormat;
/**
@@ -176,6 +179,7 @@ public class EPSGDataAccess extends Geod
*
* @see #replaceDeprecatedCS
*/
+ @Workaround(library = "EPSG:6401-6420", version = "8.9") // Deprecated in 2002 but still present in 2016.
private static final Map<Integer,Integer> DEPRECATED_CS = deprecatedCS();
static Map<Integer,Integer> deprecatedCS() {
final Map<Integer,Integer> m = new HashMap<Integer,Integer>(24);
@@ -1640,7 +1644,7 @@ addURIs: for (int i=0; ; i++) {
properties = new HashMap<String,Object>(properties); // Protect from changes
final Ellipsoid ellipsoid = owner.createEllipsoid (getString(code, result, 10));
final PrimeMeridian meridian = owner.createPrimeMeridian(getString(code, result, 11));
- final BursaWolfParameters[] param = createBursaWolfParameters(epsg);
+ final BursaWolfParameters[] param = createBursaWolfParameters(meridian, epsg);
if (param != null) {
properties.put(DefaultGeodeticDatum.BURSA_WOLF_KEY, param);
}
@@ -1665,7 +1669,7 @@ addURIs: for (int i=0; ; i++) {
throw new FactoryDataException(error().getString(Errors.Keys.DatumOriginShallBeDate));
}
if (dateFormat == null) {
- dateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.CANADA);
+ dateFormat = new StandardDateFormat();
dateFormat.setCalendar(getCalendar()); // Use UTC timezone.
}
try {
@@ -1713,10 +1717,13 @@ addURIs: for (int i=0; ; i++) {
* That legacy format had a {@code TOWGS84} element which needs the information provided by this method.
* Note that {@code TOWGS84} is a deprecated element as of WKT 2 (ISO 19162).</p>
*
- * @param code The EPSG code of the {@link GeodeticDatum}.
+ * @param meridian The source datum prime meridian, used for discarding any target datum using a different meridian.
+ * @param code The EPSG code of the source {@link GeodeticDatum}.
* @return an array of Bursa-Wolf parameters, or {@code null}.
*/
- private BursaWolfParameters[] createBursaWolfParameters(final Integer code) throws SQLException, FactoryException {
+ private BursaWolfParameters[] createBursaWolfParameters(final PrimeMeridian meridian, final Integer code)
+ throws SQLException, FactoryException
+ {
/*
* We do not provide TOWGS84 information for WGS84 itself or for any other datum on our list of target datum,
* in order to avoid infinite recursivity. The 'ensureNonRecursive' call is an extra safety check which should
@@ -1729,7 +1736,8 @@ addURIs: for (int i=0; ; i++) {
ResultSet result = executeQuery("BursaWolfParametersSet",
"SELECT COORD_OP_CODE," +
" COORD_OP_METHOD_CODE," +
- " TARGET_CRS_CODE" +
+ " TARGET_CRS_CODE," +
+ " AREA_OF_USE_CODE"+
" FROM [Coordinate_Operation]" +
" WHERE DEPRECATED=0" + // Do not put spaces around "=" - SQLTranslator searches for this exact match.
" AND TARGET_CRS_CODE = " + BursaWolfInfo.TARGET_CRS +
@@ -1743,7 +1751,8 @@ addURIs: for (int i=0; ; i++) {
final BursaWolfInfo info = new BursaWolfInfo(
getInteger(code, result, 1), // Operation
getInteger(code, result, 2), // Method
- getInteger(code, result, 3)); // Target datum
+ getInteger(code, result, 3), // Target datum
+ getInteger(code, result, 4)); // Domain of validity
if (info.target != code) { // Paranoiac check.
bwInfos.add(info);
}
@@ -1764,12 +1773,7 @@ addURIs: for (int i=0; ; i++) {
final BursaWolfInfo[] codes = bwInfos.toArray(new BursaWolfInfo[size]);
sort("Coordinate_Operation", codes);
bwInfos.clear();
- final Set<Integer> added = new HashSet<Integer>();
- for (BursaWolfInfo candidate : codes) {
- if (added.add(candidate.target)) {
- bwInfos.add(candidate);
- }
- }
+ BursaWolfInfo.filter(owner, codes, bwInfos);
size = bwInfos.size();
}
/*
@@ -1777,6 +1781,7 @@ addURIs: for (int i=0; ; i++) {
*/
final BursaWolfParameters[] parameters = new BursaWolfParameters[size];
final Locale locale = getLocale();
+ int count = 0;
for (int i=0; i<size; i++) {
final BursaWolfInfo info = bwInfos.get(i);
final GeodeticDatum datum;
@@ -1786,7 +1791,17 @@ addURIs: for (int i=0; ; i++) {
} finally {
endOfRecursivity(BursaWolfParameters.class, code);
}
- final BursaWolfParameters bwp = new BursaWolfParameters(datum, null);
+ /*
+ * Accept only Bursa-Wolf parameters between datum that use the same prime meridian.
+ * This is for avoiding ambiguity about whether longitude rotation should be applied
+ * before or after the datum change. This check is useless for EPSG dataset 8.9 since
+ * all datum seen by this method use Greenwich. But we nevertheless perform this check
+ * as a safety for future evolution or customized EPSG dataset.
+ */
+ if (!equalsIgnoreMetadata(meridian, datum.getPrimeMeridian())) {
+ continue;
+ }
+ final BursaWolfParameters bwp = new BursaWolfParameters(datum, info.getDomainOfValidity(owner));
result = executeQuery("BursaWolfParameters",
"SELECT PARAMETER_CODE," +
" PARAMETER_VALUE," +
@@ -1809,9 +1824,9 @@ addURIs: for (int i=0; ; i++) {
// except for the sign of rotation parameters.
bwp.reverseRotation();
}
- parameters[i] = bwp;
+ parameters[count++] = bwp;
}
- return parameters;
+ return ArraysExt.resize(parameters, count);
}
/**
@@ -2313,7 +2328,8 @@ addURIs: for (int i=0; ; i++) {
throw new FactoryDataException(exception.getLocalizedMessage(), exception);
}
final AxisName an = getAxisName(nameCode);
- final CoordinateSystemAxis axis = owner.csFactory.createCoordinateSystemAxis(createProperties("Coordinate Axis", an.name, epsg, an.description, false),
+ final CoordinateSystemAxis axis = owner.csFactory.createCoordinateSystemAxis(
+ createProperties("Coordinate Axis", an.name, epsg, an.description, false),
abbreviation, direction, owner.createUnit(unit));
returnValue = ensureSingleton(axis, returnValue, code);
}
@@ -2832,7 +2848,7 @@ next: while (r.next()) {
sourceDimensions = sourceCRS.getCoordinateSystem().getDimension();
} else {
sourceCRS = null;
- sourceDimensions = 2; // Acceptable default for projections only.
+ sourceDimensions = 2; // Acceptable default for projections only.
isDimensionKnown = false;
}
if (targetCode != null) {
@@ -2840,7 +2856,7 @@ next: while (r.next()) {
targetDimensions = targetCRS.getCoordinateSystem().getDimension();
} else {
targetCRS = null;
- targetDimensions = 2; // Acceptable default for projections only.
+ targetDimensions = 2; // Acceptable default for projections only.
isDimensionKnown = false;
}
/*
@@ -2930,10 +2946,8 @@ next: while (r.next()) {
final MathTransform mt;
final MathTransformFactory mtFactory = owner.mtFactory;
if (mtFactory instanceof DefaultMathTransformFactory) {
- DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
- context.setSource(sourceCRS);
- context.setTarget(targetCRS);
- mt = ((DefaultMathTransformFactory) mtFactory).createParameterizedTransform(parameters, context);
+ mt = ((DefaultMathTransformFactory) mtFactory).createParameterizedTransform(parameters,
+ ReferencingUtilities.createTransformContext(sourceCRS, targetCRS, null));
} else {
// Fallback for non-SIS implementations. Work for map projections but not for Molodensky.
mt = mtFactory.createBaseToDerived(sourceCRS, parameters, targetCRS.getCoordinateSystem());
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGFactory.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -350,8 +350,9 @@ public class EPSGFactory extends Concurr
* If no provider is specified, then this method will search on the classpath (with {@link java.util.ServiceLoader})
* for user-provided implementations of {@code InstallationScriptProvider}.
* If no user-specified provider is found, then this method will search for
- * {@code "EPSG_Tables.sql"}, {@code "EPSG_Data.sql"} and {@code "EPSG_FKeys.sql"} files in the
- * {@code $SIS_DATA/Databases/ExternalSources} directory.</li>
+ * {@code "EPSG_*Tables.sql"}, {@code "EPSG_*Data.sql"} and {@code "EPSG_*FKeys.sql"} files in the
+ * {@code $SIS_DATA/Databases/ExternalSources} directory where {@code *} stands for any characters
+ * provided that there is no ambiguity.</li>
* </ul>
*
* <p><b>Legal constraint:</b>
@@ -374,28 +375,33 @@ public class EPSGFactory extends Concurr
if (ac) {
connection.setAutoCommit(false);
}
- boolean success = false;
try {
- if (!"".equals(schema)) { // Schema may be null.
- installer.setSchema(schema != null ? schema : Constants.EPSG);
- if (catalog != null && !catalog.isEmpty()) {
- installer.prependNamespace(catalog);
+ boolean success = false;
+ try {
+ if (!"".equals(schema)) { // Schema may be null.
+ installer.setSchema(schema != null ? schema : Constants.EPSG);
+ if (catalog != null && !catalog.isEmpty()) {
+ installer.prependNamespace(catalog);
+ }
}
- }
- installer.run(scriptProvider);
- success = true;
- } finally {
- if (ac) {
- if (success) {
- connection.commit();
- } else {
- connection.rollback();
+ installer.run(scriptProvider, locale);
+ success = true;
+ } finally {
+ if (ac) {
+ if (success) {
+ connection.commit();
+ } else {
+ connection.rollback();
+ }
+ connection.setAutoCommit(true);
}
- connection.setAutoCommit(true);
- }
- if (!success) {
- installer.logFailure(locale);
}
+ } catch (IOException e) {
+ installer.logFailure(locale, e);
+ throw e;
+ } catch (SQLException e) {
+ installer.logFailure(locale, e);
+ throw e;
}
} finally {
installer.close();
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/EPSGInstaller.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -32,11 +32,10 @@ import java.io.BufferedReader;
import org.apache.sis.util.StringBuilders;
import org.apache.sis.internal.metadata.sql.ScriptRunner;
import org.apache.sis.internal.metadata.sql.SQLUtilities;
-import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.util.Fallback;
import org.apache.sis.util.CharSequences;
+import org.apache.sis.util.Exceptions;
import org.apache.sis.util.resources.Messages;
-import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.logging.PerformanceLevel;
import org.apache.sis.setup.InstallationResources;
@@ -251,12 +250,12 @@ final class EPSGInstaller extends Script
* @throws IOException if an error occurred while reading an input.
* @throws SQLException if an error occurred while executing a SQL statement.
*/
- public void run(InstallationResources scriptProvider) throws SQLException, IOException {
+ public void run(InstallationResources scriptProvider, final Locale locale) throws SQLException, IOException {
long time = System.nanoTime();
- log(Messages.getResources(null).getLogRecord(Level.INFO, Messages.Keys.CreatingSchema_2, EPSG,
- SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
+ InstallationScriptProvider.log(Messages.getResources(locale).getLogRecord(Level.INFO,
+ Messages.Keys.CreatingSchema_2, EPSG, SQLUtilities.getSimplifiedURL(getConnection().getMetaData())));
if (scriptProvider == null) {
- scriptProvider = lookupProvider();
+ scriptProvider = lookupProvider(locale);
}
final String[] scripts = scriptProvider.getResourceNames(EPSG);
int numRows = 0;
@@ -269,7 +268,7 @@ final class EPSGInstaller extends Script
}
}
time = System.nanoTime() - time;
- log(Messages.getResources(null).getLogRecord(
+ InstallationScriptProvider.log(Messages.getResources(locale).getLogRecord(
PerformanceLevel.forDuration(time, TimeUnit.NANOSECONDS),
Messages.Keys.InsertDuration_2, numRows, time / 1E9f));
}
@@ -277,7 +276,7 @@ final class EPSGInstaller extends Script
/**
* Searches for a SQL script provider on the classpath before to fallback on the default provider.
*/
- private static InstallationResources lookupProvider() {
+ private static InstallationResources lookupProvider(final Locale locale) throws IOException {
InstallationResources fallback = null;
for (final InstallationResources provider : ServiceLoader.load(InstallationResources.class)) {
if (provider.getAuthorities().contains(EPSG)) {
@@ -287,7 +286,7 @@ final class EPSGInstaller extends Script
fallback = provider;
}
}
- return (fallback != null) ? fallback : new InstallationScriptProvider.Default();
+ return (fallback != null) ? fallback : new InstallationScriptProvider.Default(locale);
}
/**
@@ -296,21 +295,13 @@ final class EPSGInstaller extends Script
* lets the exception propagate. Another code (for example {@link org.apache.sis.referencing.CRS#forCode(String)})
* may catch that exception and log another record with the exception message.
*/
- final void logFailure(final Locale locale) {
+ final void logFailure(final Locale locale, final Exception cause) {
String message = Messages.getResources(locale).getString(Messages.Keys.CanNotCreateSchema_1, EPSG);
String status = status(locale);
if (status != null) {
message = message + ' ' + status;
}
- log(new LogRecord(Level.WARNING, message));
- }
-
- /**
- * Logs the given record. This method pretend that the record has been logged by
- * {@code EPSGFactory.install(…)} because it is the public API using this class.
- */
- private static void log(final LogRecord record) {
- record.setLoggerName(Loggers.CRS_FACTORY);
- Logging.log(EPSGFactory.class, "install", record);
+ message = Exceptions.formatChainedMessages(locale, message, cause);
+ InstallationScriptProvider.log(new LogRecord(Level.WARNING, message));
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/sql/InstallationScriptProvider.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -19,6 +19,8 @@ package org.apache.sis.referencing.facto
import java.util.Set;
import java.util.Locale;
import java.util.Collections;
+import java.util.logging.Level;
+import java.util.logging.LogRecord;
import java.sql.Connection;
import java.io.BufferedReader;
import java.io.LineNumberReader;
@@ -28,14 +30,17 @@ import java.io.IOException;
import java.io.FileNotFoundException;
import java.nio.charset.Charset;
import org.apache.sis.util.resources.Errors;
+import org.apache.sis.util.logging.Logging;
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.setup.InstallationResources;
import org.apache.sis.internal.system.DataDirectory;
+import org.apache.sis.internal.system.Loggers;
import org.apache.sis.internal.util.CollectionsExt;
import org.apache.sis.internal.util.Constants;
// Branch-dependent imports
import org.apache.sis.internal.jdk7.StandardCharsets;
+import org.apache.sis.internal.jdk7.DirectoryStream;
import org.apache.sis.internal.jdk7.Files;
import org.apache.sis.internal.jdk7.Path;
@@ -261,17 +266,27 @@ public abstract class InstallationScript
*/
protected abstract InputStream openStream(final String name) throws IOException;
+ /**
+ * Logs the given record. This method pretend that the record has been logged by
+ * {@code EPSGFactory.install(…)} because it is the public API using this class.
+ */
+ static void log(final LogRecord record) {
+ record.setLoggerName(Loggers.CRS_FACTORY);
+ Logging.log(EPSGFactory.class, "install", record);
+ }
+
/**
* The default implementation which use the scripts in the {@code $SIS_DATA/Databases/ExternalSources}
- * directory, if present. This class expects the files to have those exact names:
+ * directory, if present. This class expects the files to have those exact names where {@code *} stands
+ * for any characters provided that there is no ambiguity:
*
* <ul>
- * <li>{@code EPSG_Tables.sql}</li>
- * <li>{@code EPSG_Data.sql}</li>
- * <li>{@code EPSG_FKeys.sql}</li>
+ * <li>{@code EPSG_*Tables.sql}</li>
+ * <li>{@code EPSG_*Data.sql}</li>
+ * <li>{@code EPSG_*FKeys.sql}</li>
* </ul>
*
* @author Martin Desruisseaux (Geomatys)
@@ -283,27 +298,61 @@ public abstract class InstallationScript
/**
* The directory containing the scripts, or {@code null} if it does not exist.
*/
- private final Path directory;
+ private Path directory;
+
+ /**
+ * Index of the first real file in the array given to the constructor.
+ * We set the value to 1 for skipping the {@code PREPARE} pseudo-file.
+ */
+ private static final int FIRST_FILE = 1;
/**
* Creates a default provider.
*/
- Default() {
+ Default(final Locale locale) throws IOException {
super(Constants.EPSG,
PREPARE,
- "EPSG_Tables.sql",
- "EPSG_Data.sql",
- "EPSG_FKeys.sql",
+ "Tables",
+ "Data",
+ "FKeys",
FINISH);
Path dir = DataDirectory.DATABASES.getDirectory();
if (dir != null) {
dir = dir.resolve("ExternalSources");
- if (!Files.isRegularFile(dir.resolve("EPSG_Tables.sql"))) {
- dir = null;
+ if (Files.isDirectory(dir)) {
+ final String[] resources = super.resources;
+ final String[] found = new String[resources.length - FIRST_FILE - 1];
+ DirectoryStream stream = Files.newDirectoryStream(dir, "EPSG_*.sql");
+ try {
+ for (final Path path : stream) {
+ final String name = path.getFileName().toString();
+ for (int i=0; i<found.length; i++) {
+ final String part = resources[FIRST_FILE + i];
+ if (name.contains(part)) {
+ if (found[i] != null) {
+ log(Errors.getResources(locale)
+ .getLogRecord(Level.WARNING, Errors.Keys.DuplicatedElement_1, part));
+ return; // Stop the search because of duplicated file.
+ }
+ found[i] = name;
+ }
+ }
+ }
+ } finally {
+ stream.close();
+ }
+ for (int i=0; i<found.length; i++) {
+ final String file = found[i];
+ if (file != null) {
+ resources[FIRST_FILE + i] = file;
+ } else {
+ dir = null;
+ }
+ }
+ directory = dir;
}
}
- directory = dir;
}
/**
@@ -337,7 +386,7 @@ public abstract class InstallationScript
*/
@Override
protected InputStream openStream(final String name) throws IOException {
- return Files.newInputStream(directory.resolve(name));
+ return (directory != null) ? Files.newInputStream(directory.resolve(name)) : null;
}
}
}
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractCoordinateOperation.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -31,6 +31,7 @@ import org.opengis.metadata.quality.Posi
import org.opengis.referencing.IdentifiedObject;
import org.opengis.referencing.crs.GeneralDerivedCRS;
import org.opengis.referencing.crs.CoordinateReferenceSystem;
+import org.opengis.referencing.operation.ConcatenatedOperation;
import org.opengis.referencing.operation.CoordinateOperation;
import org.opengis.referencing.operation.OperationMethod;
import org.opengis.referencing.operation.MathTransform;
@@ -650,16 +651,29 @@ check: for (int isTarget=0; ; isTar
* {@linkplain #transform}, if possible. If no descriptor can be inferred from the math transform,
* then this method fallback on the {@link OperationMethod} parameters.
*/
- ParameterDescriptorGroup getParameterDescriptors() throws UnsupportedOperationException {
- MathTransform mt = transform;
- while (mt != null) {
- if (mt instanceof Parameterized) {
+ ParameterDescriptorGroup getParameterDescriptors() {
+ ParameterDescriptorGroup descriptor = getParameterDescriptors(transform);
+ if (descriptor == null) {
+ final OperationMethod method = getMethod();
+ if (method != null) {
+ descriptor = method.getParameters();
+ }
+ }
+ return descriptor;
+ }
+
+ /**
+ * Returns the parameter descriptors for the given transform, or {@code null} if unknown.
+ */
+ static ParameterDescriptorGroup getParameterDescriptors(MathTransform transform) {
+ while (transform != null) {
+ if (transform instanceof Parameterized) {
final ParameterDescriptorGroup param;
if (Semaphores.queryAndSet(Semaphores.ENCLOSED_IN_OPERATION)) {
- throw new AssertionError(); // Should never happen.
+ throw new AssertionError(); // Should never happen.
}
try {
- param = ((Parameterized) mt).getParameterDescriptors();
+ param = ((Parameterized) transform).getParameterDescriptors();
} finally {
Semaphores.clear(Semaphores.ENCLOSED_IN_OPERATION);
}
@@ -667,14 +681,13 @@ check: for (int isTarget=0; ; isTar
return param;
}
}
- if (mt instanceof PassThroughTransform) {
- mt = ((PassThroughTransform) mt).getSubTransform();
+ if (transform instanceof PassThroughTransform) {
+ transform = ((PassThroughTransform) transform).getSubTransform();
} else {
break;
}
}
- final OperationMethod method = getMethod();
- return (method != null) ? method.getParameters() : null;
+ return null;
}
/**
@@ -685,13 +698,13 @@ check: for (int isTarget=0; ; isTar
* @throws UnsupportedOperationException if the parameter values can not
* be determined for the current math transform implementation.
*/
- ParameterValueGroup getParameterValues() {
+ ParameterValueGroup getParameterValues() throws UnsupportedOperationException {
MathTransform mt = transform;
while (mt != null) {
if (mt instanceof Parameterized) {
final ParameterValueGroup param;
if (Semaphores.queryAndSet(Semaphores.ENCLOSED_IN_OPERATION)) {
- throw new AssertionError(); // Should never happen.
+ throw new AssertionError(); // Should never happen.
}
try {
param = ((Parameterized) mt).getParameterValues();
@@ -844,32 +857,45 @@ check: for (int isTarget=0; ; isTar
protected String formatTo(final Formatter formatter) {
super.formatTo(formatter);
formatter.newLine();
- append(formatter, getSourceCRS(), WKTKeywords.SourceCRS);
- append(formatter, getTargetCRS(), WKTKeywords.TargetCRS);
- formatter.append(DefaultOperationMethod.castOrCopy(getMethod()));
- ParameterValueGroup parameters;
- try {
- parameters = getParameterValues();
- } catch (UnsupportedOperationException e) {
- final IdentifiedObject c = getParameterDescriptors();
- formatter.setInvalidWKT(c != null ? c : this, e);
- parameters = null;
+ /*
+ * If the WKT is a component of a ConcatenatedOperation, do not format the source and target CRS.
+ * This decision SIS-specific since the WKT 2 specification does not define concatenated operations.
+ * The choice of content to omit may change in any future version.
+ */
+ final boolean isComponent = (formatter.getEnclosingElement(1) instanceof ConcatenatedOperation);
+ if (!isComponent) {
+ append(formatter, getSourceCRS(), WKTKeywords.SourceCRS);
+ append(formatter, getTargetCRS(), WKTKeywords.TargetCRS);
}
- if (parameters != null) {
- formatter.newLine();
- for (final GeneralParameterValue param : parameters.values()) {
- WKTUtilities.append(param, formatter);
+ final OperationMethod method = getMethod();
+ if (method != null) {
+ formatter.append(DefaultOperationMethod.castOrCopy(method));
+ ParameterValueGroup parameters;
+ try {
+ parameters = getParameterValues();
+ } catch (UnsupportedOperationException e) {
+ final IdentifiedObject c = getParameterDescriptors();
+ formatter.setInvalidWKT(c != null ? c : this, e);
+ parameters = null;
}
- }
- append(formatter, getInterpolationCRS(), WKTKeywords.InterpolationCRS);
- final double accuracy = getLinearAccuracy();
- if (accuracy > 0) {
- formatter.append(new FormattableObject() {
- @Override protected String formatTo(final Formatter formatter) {
- formatter.append(accuracy);
- return WKTKeywords.OperationAccuracy;
+ if (parameters != null) {
+ formatter.newLine();
+ for (final GeneralParameterValue param : parameters.values()) {
+ WKTUtilities.append(param, formatter);
}
- });
+ }
+ }
+ if (!isComponent) {
+ append(formatter, getInterpolationCRS(), WKTKeywords.InterpolationCRS);
+ final double accuracy = getLinearAccuracy();
+ if (accuracy > 0) {
+ formatter.append(new FormattableObject() {
+ @Override protected String formatTo(final Formatter formatter) {
+ formatter.append(accuracy);
+ return WKTKeywords.OperationAccuracy;
+ }
+ });
+ }
}
if (formatter.getConvention().majorVersion() == 1) {
formatter.setInvalidWKT(this, null);
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/AbstractSingleOperation.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -225,14 +225,14 @@ class AbstractSingleOperation extends Ab
* ignoring null java.lang.Integer instances. We do not specify whether the method
* dimensions should include the interpolation dimensions or not, so we accept both.
*/
- int isTarget = 0; // 0 == false: the wrong dimension is the source one.
+ int isTarget = 0; // 0 == false: the wrong dimension is the source one.
if (expected == null || (actual == expected) || (actual == expected + interpDim)) {
actual = transform.getTargetDimensions();
expected = method.getTargetDimensions();
if (expected == null || (actual == expected) || (actual == expected + interpDim)) {
return;
}
- isTarget = 1; // 1 == true: the wrong dimension is the target one.
+ isTarget = 1; // 1 == true: the wrong dimension is the target one.
}
/*
* At least one dimension does not match. In principle this is an error, but we make an exception for the
Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java (from r1737089, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java&r1=1737089&r2=1737101&rev=1737101&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CRSPair.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -23,7 +23,7 @@ import org.apache.sis.util.CharSequences
import org.apache.sis.util.Classes;
// Branch-dependent imports
-import java.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
/**
Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java (from r1737089, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java&r1=1737089&r2=1737101&rev=1737101&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/CoordinateOperationInference.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -64,7 +64,7 @@ import org.apache.sis.util.resources.Voc
import static org.apache.sis.util.Utilities.equalsIgnoreMetadata;
// Branch-dependent imports
-import java.util.Objects;
+import org.apache.sis.internal.jdk7.Objects;
import org.apache.sis.internal.jdk8.JDK8;
@@ -194,7 +194,7 @@ public class CoordinateOperationInferenc
desiredAccuracy = context.getDesiredAccuracy();
bbox = context.getGeographicBoundingBox();
}
- previousSearches = new HashMap<>(4);
+ previousSearches = new HashMap<CRSPair,Boolean>(4);
}
/**
@@ -558,7 +558,9 @@ public class CoordinateOperationInferenc
final Matrix matrix;
try {
matrix = CoordinateSystems.swapAndScaleAxes(sourceCS, targetCS);
- } catch (IllegalArgumentException | ConversionException exception) {
+ } catch (IllegalArgumentException exception) {
+ throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS), exception);
+ } catch (ConversionException exception) {
throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS), exception);
}
return createFromAffineTransform(AXIS_CHANGES, sourceCRS, targetCRS, matrix);
@@ -604,7 +606,9 @@ public class CoordinateOperationInferenc
final Matrix matrix;
try {
matrix = CoordinateSystems.swapAndScaleAxes(sourceCS, targetCS);
- } catch (IllegalArgumentException | ConversionException exception) {
+ } catch (IllegalArgumentException exception) {
+ throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS), exception);
+ } catch (ConversionException exception) {
throw new OperationNotFoundException(notFoundMessage(sourceCRS, targetCRS), exception);
}
final int translationColumn = matrix.getNumCol() - 1; // Paranoiac check: should always be 1.
@@ -784,7 +788,7 @@ public class CoordinateOperationInferenc
if (step2.getName() == AXIS_CHANGES && mt2.getSourceDimensions() == mt2.getTargetDimensions()) main = step1;
if (main instanceof SingleOperation) {
final MathTransform mt = factorySIS.getMathTransformFactory().createConcatenatedTransform(mt1, mt2);
- main = createFromMathTransform(new HashMap<>(IdentifiedObjects.getProperties(main)),
+ main = createFromMathTransform(new HashMap<String,Object>(IdentifiedObjects.getProperties(main)),
sourceCRS, targetCRS, mt, ((SingleOperation) main).getMethod(),
(main instanceof Transformation) ? Transformation.class : SingleOperation.class);
} else {
@@ -803,7 +807,7 @@ public class CoordinateOperationInferenc
break;
}
}
- main = createFromMathTransform(new HashMap<>(IdentifiedObjects.getProperties(main)),
+ main = createFromMathTransform(new HashMap<String,Object>(IdentifiedObjects.getProperties(main)),
main.getSourceCRS(), main.getTargetCRS(), main.getMathTransform(), null, type);
}
return main;
@@ -859,7 +863,7 @@ public class CoordinateOperationInferenc
* @return a modifiable map containing the given name. Callers can put other entries in this map.
*/
private static Map<String,Object> properties(final Identifier name) {
- final Map<String,Object> properties = new HashMap<>(4);
+ final Map<String,Object> properties = new HashMap<String,Object>(4);
properties.put(CoordinateOperation.NAME_KEY, name);
if ((name == DATUM_SHIFT) || (name == ELLIPSOID_CHANGE)) {
properties.put(CoordinateOperation.COORDINATE_OPERATION_ACCURACY_KEY, new PositionalAccuracy[] {
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConcatenatedOperation.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -46,6 +46,7 @@ import static org.apache.sis.util.Utilit
// Branch-dependent imports
import org.apache.sis.internal.jdk7.Objects;
+import org.apache.sis.io.wkt.Formatter;
/**
@@ -325,6 +326,23 @@ final class DefaultConcatenatedOperation
return super.computeHashCode() + 37 * Objects.hashCode(operations);
}
+ /**
+ * Formats this coordinate operation in pseudo-WKT. This is specific to Apache SIS since
+ * there is no concatenated operation in the Well Known Text (WKT) version 2 format.
+ *
+ * @param formatter The formatter to use.
+ * @return {@code "ConcatenatedOperation"}.
+ */
+ @Override
+ protected String formatTo(final Formatter formatter) {
+ super.formatTo(formatter);
+ for (final CoordinateOperation component : operations) {
+ formatter.append(castOrCopy(component));
+ }
+ formatter.setInvalidWKT(this, null);
+ return "ConcatenatedOperation";
+ }
+
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultConversion.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -254,12 +254,12 @@ public class DefaultConversion extends A
* CoordinateReferenceSystem because the targetCRS is typically under construction when this
* method in invoked, and attempts to use it can cause NullPointerException.
*/
- final DefaultMathTransformFactory.Context context = new DefaultMathTransformFactory.Context();
- context.setSource(source);
+ final DefaultMathTransformFactory.Context context;
if (target instanceof GeneralDerivedCRS) {
+ context = ReferencingUtilities.createTransformContext(source, null, null);
context.setTarget(target.getCoordinateSystem()); // Using 'target' would be unsafe here.
} else {
- context.setTarget(target);
+ context = ReferencingUtilities.createTransformContext(source, target, null);
}
transform = ((DefaultMathTransformFactory) factory).createParameterizedTransform(parameters, context);
parameters = Parameters.unmodifiable(context.getCompletedParameters());
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/DefaultCoordinateOperationFactory.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.opera
import java.util.Map;
import java.util.HashMap;
import java.util.Collections;
+import java.util.List;
import org.opengis.util.FactoryException;
import org.opengis.util.NoSuchIdentifierException;
import org.opengis.parameter.ParameterValueGroup;
@@ -28,11 +29,13 @@ import org.opengis.referencing.Identifie
import org.opengis.referencing.crs.CoordinateReferenceSystem;
import org.opengis.referencing.crs.GeographicCRS;
import org.opengis.referencing.crs.ProjectedCRS;
+import org.opengis.referencing.crs.SingleCRS;
+import org.opengis.referencing.datum.Datum;
import org.apache.sis.internal.referencing.MergedProperties;
import org.apache.sis.internal.metadata.ReferencingServices;
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.util.CollectionsExt;
-import org.apache.sis.internal.util.Utilities;
+import org.apache.sis.referencing.CRS;
import org.apache.sis.referencing.factory.InvalidGeodeticParameterException;
import org.apache.sis.referencing.operation.transform.DefaultMathTransformFactory;
import org.apache.sis.util.collection.WeakHashSet;
@@ -42,6 +45,7 @@ import org.apache.sis.util.resources.Err
import org.apache.sis.util.ArgumentChecks;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.NullArgumentException;
+import org.apache.sis.util.Utilities;
/**
@@ -68,7 +72,7 @@ import org.apache.sis.util.NullArgumentE
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.6
- * @version 0.6
+ * @version 0.7
* @module
*/
public class DefaultCoordinateOperationFactory extends AbstractFactory implements CoordinateOperationFactory {
@@ -149,7 +153,7 @@ public class DefaultCoordinateOperationF
*
* @return The underlying math transform factory.
*/
- private MathTransformFactory getMathTransformFactory() {
+ final MathTransformFactory getMathTransformFactory() {
MathTransformFactory factory = mtFactory;
if (factory == null) {
mtFactory = factory = DefaultFactories.forBuildin(MathTransformFactory.class);
@@ -158,6 +162,18 @@ public class DefaultCoordinateOperationF
}
/**
+ * Returns the Apache SIS implementation of math transform factory.
+ * This method is used only when we need SIS-specific methods.
+ */
+ final DefaultMathTransformFactory getDefaultMathTransformFactory() {
+ MathTransformFactory factory = getMathTransformFactory();
+ if (factory instanceof DefaultMathTransformFactory) {
+ return (DefaultMathTransformFactory) factory;
+ }
+ return DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class);
+ }
+
+ /**
* Returns the operation method of the given name. The given argument shall be either a method
* {@linkplain DefaultOperationMethod#getName() name} (e.g. <cite>"Transverse Mercator"</cite>)
* or one of its {@linkplain DefaultOperationMethod#getIdentifiers() identifiers} (e.g. {@code "EPSG:9807"}).
@@ -314,6 +330,39 @@ public class DefaultCoordinateOperationF
}
/**
+ * Returns {@code true} if the given CRS are using equivalent (ignoring metadata) datum.
+ * If the CRS are {@link CompoundCRS}, then this method verifies that all datum in the
+ * target CRS exists in the source CRS, but not necessarily in the same order.
+ * The target CRS may have less datum than the source CRS.
+ *
+ * @param sourceCRS The target CRS.
+ * @param targetCRS The source CRS.
+ * @return {@code true} if all datum in the {@code targetCRS} exists in the {@code sourceCRS}.
+ */
+ private static boolean isConversion(final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS)
+ {
+ List<SingleCRS> components = CRS.getSingleComponents(sourceCRS);
+ int n = components.size(); // Number of remaining datum from sourceCRS to verify.
+ final Datum[] datum = new Datum[n];
+ for (int i=0; i<n; i++) {
+ datum[i] = components.get(i).getDatum();
+ }
+ components = CRS.getSingleComponents(targetCRS);
+next: for (int i=components.size(); --i >= 0;) {
+ final Datum d = components.get(i).getDatum();
+ for (int j=n; --j >= 0;) {
+ if (Utilities.equalsIgnoreMetadata(d, datum[j])) {
+ System.arraycopy(datum, j+1, datum, j, --n - j); // Remove the datum from the list.
+ continue next;
+ }
+ }
+ return false; // Datum from 'targetCRS' not found in 'sourceCRS'.
+ }
+ return true;
+ }
+
+ /**
* Creates a transformation or conversion from the given properties.
* This method infers by itself if the operation to create is a
* {@link Transformation}, a {@link Conversion} or a {@link Projection} sub-type
@@ -401,7 +450,7 @@ public class DefaultCoordinateOperationF
}
if (method instanceof DefaultOperationMethod) {
final Class<? extends SingleOperation> c = ((DefaultOperationMethod) method).getOperationType();
- if (c != null) { // Paranoiac check (above method should not return null).
+ if (c != null) { // Paranoiac check (above method should not return null).
if (baseType.isAssignableFrom(c)) {
baseType = c;
} else if (!c.isAssignableFrom(baseType)) {
@@ -424,7 +473,7 @@ public class DefaultCoordinateOperationF
* could be different, which we want to allow.
*/
if (baseType == SingleOperation.class) {
- if (OperationPathFinder.isConversion(sourceCRS, targetCRS)) {
+ if (isConversion(sourceCRS, targetCRS)) {
if (interpolationCRS == null && sourceCRS instanceof GeographicCRS
&& targetCRS instanceof ProjectedCRS)
{
@@ -473,7 +522,7 @@ public class DefaultCoordinateOperationF
op = new AbstractSingleOperation(properties, sourceCRS, targetCRS, interpolationCRS, method, transform);
}
if (!baseType.isInstance(op)) {
- throw new FactoryException(Errors.format(Errors.Keys.CanNotInstantiate_1, baseType));
+ throw new FactoryException(Errors.format(Errors.Keys.CanNotCreateObjectAsInstanceOf_2, baseType, op.getName()));
}
return pool.unique(op);
}
@@ -528,57 +577,87 @@ public class DefaultCoordinateOperationF
}
/**
- * Not yet implemented.
- *
- * @param sourceCRS Input coordinate reference system.
- * @param targetCRS Output coordinate reference system.
- * @param method the algorithmic method for conversion or transformation.
- * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
- * @throws FactoryException if the operation creation failed.
+ * Finds or creates an operation for conversion or transformation between two coordinate reference systems.
+ * If an operation exists, it is returned. If more than one operation exists, the operation having the widest
+ * domain of validity is returned. If no operation exists, then an exception is thrown.
+ *
+ * <p>The default implementation delegates to <code>{@linkplain #createOperation(CoordinateReferenceSystem,
+ * CoordinateReferenceSystem, CoordinateOperationContext) createOperation}(sourceCRS, targetCRS, null)}</code>.</p>
+ *
+ * @param sourceCRS input coordinate reference system.
+ * @param targetCRS output coordinate reference system.
+ * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+ * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
+ * @throws FactoryException if the operation creation failed for some other reason.
*/
@Override
public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
- final CoordinateReferenceSystem targetCRS,
- final OperationMethod method)
- throws FactoryException
+ final CoordinateReferenceSystem targetCRS)
+ throws OperationNotFoundException, FactoryException
{
- return delegate().createOperation(sourceCRS, targetCRS, method);
+ return createOperation(sourceCRS, targetCRS, (CoordinateOperationContext) null);
}
/**
- * Not yet implemented.
+ * Finds or creates an operation for conversion or transformation between two coordinate reference systems.
+ * If an operation exists, it is returned. If more than one operation exists, then the operation having the
+ * widest intersection between its {@linkplain AbstractCoordinateOperation#getDomainOfValidity() domain of
+ * validity} and the {@linkplain CoordinateOperationContext#getAreaOfInterest() area of interest} is returned.
+ *
+ * <p>The default implementation is as below:</p>
*
- * @param sourceCRS Input coordinate reference system.
- * @param targetCRS Output coordinate reference system.
- * @return A coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+ * {@preformat java
+ * return new CoordinateOperationInference(this, context).createOperation(sourceCRS, targetCRS);
+ * }
+ *
+ * Subclasses can override this method if they need, for example, to use a custom
+ * {@link CoordinateOperationInference} implementation.
+ *
+ * @param sourceCRS input coordinate reference system.
+ * @param targetCRS output coordinate reference system.
+ * @param context area of interest and desired accuracy, or {@code null}.
+ * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}.
* @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
* @throws FactoryException if the operation creation failed for some other reason.
+ *
+ * @see CoordinateOperationInference
+ *
+ * @since 0.7
*/
- @Override
public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
- final CoordinateReferenceSystem targetCRS)
+ final CoordinateReferenceSystem targetCRS,
+ final CoordinateOperationContext context)
throws OperationNotFoundException, FactoryException
{
- return delegate().createOperation(sourceCRS, targetCRS);
+ return new CoordinateOperationInference(this, context).createOperation(sourceCRS, targetCRS);
}
/**
- * Temporarily returns a third-party factory for operation not yet implemented by this class.
- * This method will be removed when the missing implementation will have been ported to SIS.
+ * Returns an operation using a particular method for conversion or transformation between
+ * two coordinate reference systems. If an operation exists using the given method, then it
+ * is returned. If no operation using the given method is found, then the implementation has
+ * the option of inferring the operation from the argument objects.
+ *
+ * <p>Current implementation ignores the {@code method} argument.
+ * This behavior may change in a future Apache SIS version.</p>
+ *
+ * @param sourceCRS input coordinate reference system.
+ * @param targetCRS output coordinate reference system.
+ * @param method the algorithmic method for conversion or transformation.
+ * @return a coordinate operation from {@code sourceCRS} to {@code targetCRS}.
+ * @throws OperationNotFoundException if no operation path was found from {@code sourceCRS} to {@code targetCRS}.
+ * @throws FactoryException if the operation creation failed for some other reason.
+ *
+ * @deprecated Replaced by {@link #createOperation(CoordinateReferenceSystem, CoordinateReferenceSystem, CoordinateOperationContext)}.
*/
- private synchronized CoordinateOperationFactory delegate() throws FactoryException {
- if (delegate != null) {
- return delegate;
- }
- for (final CoordinateOperationFactory factory : java.util.ServiceLoader.load(CoordinateOperationFactory.class)) {
- if (!Utilities.isSIS(factory.getClass())) {
- delegate = factory;
- return factory;
- }
- }
- throw new FactoryException(Errors.format(Errors.Keys.MissingRequiredModule_1, "geotk-referencing")); // This is temporary.
+ @Override
+ @Deprecated
+ public CoordinateOperation createOperation(final CoordinateReferenceSystem sourceCRS,
+ final CoordinateReferenceSystem targetCRS,
+ final OperationMethod method)
+ throws FactoryException
+ {
+ ArgumentChecks.ensureNonNull("method", method); // As a matter of principle.
+ return createOperation(sourceCRS, targetCRS, (CoordinateOperationContext) null);
}
-
- /** Temporary, to be deleted in a future SIS version. */
- private transient CoordinateOperationFactory delegate;
}
Copied: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java (from r1737089, sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java)
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java?p2=sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java&p1=sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java&r1=1737089&r2=1737101&rev=1737101&view=diff
==============================================================================
--- sis/branches/JDK7/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/InverseOperationMethod.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -67,7 +67,7 @@ final class InverseOperationMethod exten
}
Identifier name = method.getName();
name = new ImmutableIdentifier(null, name.getCodeSpace(), "Inverse " + name.getCode());
- final Map<String,Object> properties = new HashMap<>(6);
+ final Map<String,Object> properties = new HashMap<String,Object>(6);
properties.put(NAME_KEY, name);
properties.put(FORMULA_KEY, method.getFormula());
properties.put(REMARKS_KEY, method.getRemarks());
Modified: sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java?rev=1737101&r1=1737100&r2=1737101&view=diff
==============================================================================
--- sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] (original)
+++ sis/branches/JDK6/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/GeneralMatrix.java [UTF-8] Wed Mar 30 11:25:06 2016
@@ -191,7 +191,7 @@ class GeneralMatrix extends MatrixSIS im
*/
static int indexOfErrors(final int numRow, final int numCol, final double[] elements) {
assert elements.length % (numRow * numCol) == 0;
- return (numRow * numCol) % elements.length; // A % B is for getting 0 without branching if A == B.
+ return (numRow * numCol) % elements.length; // A % B is for getting 0 without branching if A == B.
}
/**
@@ -337,7 +337,7 @@ class GeneralMatrix extends MatrixSIS im
if (copy) {
elements = elements.clone();
}
- return elements; // Internal array already uses extended precision.
+ return elements; // Internal array already uses extended precision.
} else {
elements = Arrays.copyOf(elements, length);
}
@@ -415,7 +415,7 @@ class GeneralMatrix extends MatrixSIS im
* @see Matrices#create(int, int, Number[])
*/
final boolean setElements(final Number[] newValues) {
- final int numRow = this.numRow; // Protection against accidental changes.
+ final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
final int length = numRow * numCol;
if (newValues.length != length) {
@@ -494,9 +494,18 @@ class GeneralMatrix extends MatrixSIS im
*/
@Override
public final boolean isAffine() {
- final int numRow = this.numRow; // Protection against accidental changes.
+ return isAffine(true);
+ }
+
+ /**
+ * Implementation of {@link #isAffine()} with control on whether we require the matrix to be square.
+ *
+ * @param square {@code true} if the matrix must be square, or {@code false} for allowing non-square matrices.
+ */
+ final boolean isAffine(final boolean square) {
+ final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
- if (numRow == numCol) {
+ if (numRow == numCol || !square) {
int i = numRow * numCol;
if (elements[--i] == 1) {
final int base = (numRow - 1) * numCol;
@@ -526,7 +535,7 @@ class GeneralMatrix extends MatrixSIS im
*/
@Override
public final boolean isIdentity() {
- final int numRow = this.numRow; // Protection against accidental changes.
+ final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
if (numRow != numCol) {
return false;
@@ -553,9 +562,9 @@ class GeneralMatrix extends MatrixSIS im
*/
@Override
public void transpose() {
- final int numRow = this.numRow; // Protection against accidental changes.
+ final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
- final int errors = indexOfErrors(numRow, numCol, elements); // Where error values start, or 0 if none.
+ final int errors = indexOfErrors(numRow, numCol, elements); // Where error values start, or 0 if none.
for (int j=0; j<numRow; j++) {
for (int i=0; i<j; i++) {
final int lo = j*numCol + i;
@@ -574,7 +583,7 @@ class GeneralMatrix extends MatrixSIS im
* The matrix sizes much match - this is not verified unless assertions are enabled.
*/
final void setToProduct(final Matrix A, final Matrix B) {
- final int numRow = this.numRow; // Protection against accidental changes.
+ final int numRow = this.numRow; // Protection against accidental changes.
final int numCol = this.numCol;
final int nc = A.getNumCol();
assert B.getNumRow() == nc;
@@ -585,7 +594,7 @@ class GeneralMatrix extends MatrixSIS im
*/
final double[] eltA = getExtendedElements(A, numRow, nc, false);
final double[] eltB = getExtendedElements(B, nc, numCol, false);
- final int errorOffset = numRow * numCol; // Where error terms start.
+ final int errorOffset = numRow * numCol; // Where error terms start.
final int errA = numRow * nc;
final int errB = nc * numCol;
/*
@@ -597,20 +606,20 @@ class GeneralMatrix extends MatrixSIS im
for (int i=0; i<numCol; i++) {
sum.clear();
double max = 0;
- int iB = i; // Index of values in a single column of B.
- int iA = j * nc; // Index of values in a single row of A.
+ int iB = i; // Index of values in a single column of B.
+ int iA = j * nc; // Index of values in a single row of A.
final int nextRow = iA + nc;
while (iA < nextRow) {
dot.setFrom (eltA, iA, errA);
dot.multiply(eltB, iB, errB);
sum.add(dot);
- iB += numCol; // Move to next row of B.
- iA++; // Move to next column of A.
+ iB += numCol; // Move to next row of B.
+ iA++; // Move to next column of A.
final double value = Math.abs(dot.value);
if (value > max) max = value;
}
if (Math.abs(sum.value) < Math.ulp(max) * ZERO_THRESHOLD) {
- sum.clear(); // Sum is not significant according double arithmetic.
+ sum.clear(); // Sum is not significant according double arithmetic.
}
sum.storeTo(elements, k++, errorOffset);
}