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 2017/03/31 18:49:18 UTC
svn commit: r1789729 [4/9] - in /sis/branches/JDK9: ./
application/sis-console/
application/sis-console/src/main/java/org/apache/sis/console/
application/sis-console/src/test/java/org/apache/sis/console/ core/
core/sis-feature/src/main/java/org/apache/...
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/EPSGFactoryFallback.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -45,6 +45,7 @@ import org.apache.sis.util.resources.Voc
import org.apache.sis.util.iso.DefaultNameSpace;
import org.apache.sis.util.CharSequences;
import org.apache.sis.util.Debug;
+import org.apache.sis.measure.Latitude;
/**
@@ -94,8 +95,8 @@ final class EPSGFactoryFallback extends
}
/**
- * Returns the EPSG authority with only a modification in the title of emphasing that this is a subset
- * of EPSG dataset.
+ * Returns the EPSG authority with only a modification in the title
+ * for emphasing that this is a subset of EPSG dataset.
*/
@Override
public synchronized Citation getAuthority() {
@@ -138,10 +139,14 @@ final class EPSGFactoryFallback extends
add(codes, crs.geographic);
add(codes, crs.geo3D);
}
- if (projected && (crs.northUTM != 0 || crs.southUTM != 0)) {
- for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) {
- if (crs.northUTM != 0) codes.add(Integer.toString(crs.northUTM + zone));
- if (crs.southUTM != 0) codes.add(Integer.toString(crs.southUTM + zone));
+ if (projected) {
+ add(codes, crs.northUPS);
+ add(codes, crs.southUPS);
+ if (crs.northUTM != 0 || crs.southUTM != 0) {
+ for (int zone = crs.firstZone; zone <= crs.lastZone; zone++) {
+ if (crs.northUTM != 0) codes.add(Integer.toString(crs.northUTM + zone));
+ if (crs.southUTM != 0) codes.add(Integer.toString(crs.southUTM + zone));
+ }
}
}
}
@@ -246,13 +251,19 @@ final class EPSGFactoryFallback extends
final double latitude;
int zone;
if (crs.northUTM != 0 && (zone = n - crs.northUTM) >= crs.firstZone && zone <= crs.lastZone) {
- latitude = +1;
+ latitude = +1; // Any north latitude below 56�N (because of Norway exception) is okay
} else if (crs.southUTM != 0 && (zone = n - crs.southUTM) >= crs.firstZone && zone <= crs.lastZone) {
- latitude = -1;
+ latitude = -1; // Any south latitude above 80�S (because of UPS south case) is okay.
+ } else if (n == crs.northUPS) {
+ latitude = Latitude.MAX_VALUE;
+ zone = 30; // Any random UTM zone is okay.
+ } else if (n == crs.southUPS) {
+ latitude = Latitude.MIN_VALUE;
+ zone = 30; // Any random UTM zone is okay.
} else {
continue;
}
- return crs.UTM(latitude, TransverseMercator.centralMeridian(zone));
+ return crs.universal(latitude, TransverseMercator.Zoner.UTM.centralMeridian(zone));
}
}
if ((kind & (DATUM | CRS)) != 0) {
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/StandardDefinitions.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -41,12 +41,14 @@ import org.opengis.util.NoSuchIdentifier
import org.apache.sis.internal.system.DefaultFactories;
import org.apache.sis.internal.metadata.AxisNames;
import org.apache.sis.internal.referencing.provider.TransverseMercator;
+import org.apache.sis.internal.referencing.provider.PolarStereographicA;
import org.apache.sis.metadata.iso.extent.Extents;
import org.apache.sis.metadata.iso.citation.Citations;
import org.apache.sis.referencing.datum.DefaultEllipsoid;
import org.apache.sis.referencing.datum.DefaultPrimeMeridian;
import org.apache.sis.referencing.datum.DefaultGeodeticDatum;
import org.apache.sis.referencing.datum.DefaultVerticalDatum;
+import org.apache.sis.referencing.cs.CoordinateSystems;
import org.apache.sis.referencing.cs.DefaultVerticalCS;
import org.apache.sis.referencing.cs.DefaultCartesianCS;
import org.apache.sis.referencing.cs.DefaultSphericalCS;
@@ -72,6 +74,7 @@ import static org.apache.sis.internal.me
/**
* Definitions of referencing objects identified by the {@link CommonCRS} enumeration values.
* This class is used only as a fallback if the objects can not be fetched from the EPSG database.
+ * This class should not be loaded when a connection to an EPSG geodetic dataset is available.
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.4
@@ -107,7 +110,7 @@ final class StandardDefinitions {
map.put(IDENTIFIERS_KEY, new NamedIdentifier(Citations.EPSG, String.valueOf(code)));
}
map.put(NAME_KEY, new NamedIdentifier(Citations.EPSG, name));
- map.put(ALIAS_KEY, alias); // May be null, which is okay.
+ map.put(ALIAS_KEY, alias); // May be null, which is okay.
if (world) {
map.put(DOMAIN_OF_VALIDITY_KEY, Extents.WORLD);
}
@@ -126,29 +129,31 @@ final class StandardDefinitions {
}
/**
- * Returns the operation method for Transverse Mercator projection using the SIS factory implementation.
- * This method restricts the factory to SIS implementation instead than arbitrary factory in order to meet
- * the contract saying that {@link CommonCRS} methods should never fail.
+ * Creates a Universal Transverse Mercator (UTM) or a Universal Polar Stereographic (UPS) projected CRS
+ * using the Apache SIS factory implementation. This method restricts the factory to SIS implementation
+ * instead than arbitrary factory in order to meet the contract saying that {@link CommonCRS} methods
+ * should never fail.
*
* @param code the EPSG code, or 0 if none.
* @param baseCRS the geographic CRS on which the projected CRS is based.
- * @param latitude a latitude in the zone of the desired projection, to be snapped to 0�.
+ * @param isUTM {@code true} for UTM or {@code false} for UPS. Note: redundant with the given latitude.
+ * @param latitude a latitude in the zone of the desired projection, to be snapped to 0�, 90�S or 90�N.
* @param longitude a longitude in the zone of the desired projection, to be snapped to UTM central meridian.
* @param derivedCS the projected coordinate system.
*/
- static ProjectedCRS createUTM(final int code, final GeographicCRS baseCRS,
+ static ProjectedCRS createUniversal(final int code, final GeographicCRS baseCRS, final boolean isUTM,
final double latitude, final double longitude, final CartesianCS derivedCS)
{
final OperationMethod method;
try {
- method = DefaultFactories.forBuildin(MathTransformFactory.class,
- DefaultMathTransformFactory.class)
- .getOperationMethod(TransverseMercator.NAME);
+ method = DefaultFactories.forBuildin(MathTransformFactory.class, DefaultMathTransformFactory.class)
+ .getOperationMethod(isUTM ? TransverseMercator.NAME : PolarStereographicA.NAME);
} catch (NoSuchIdentifierException e) {
- throw new IllegalStateException(e); // Should not happen with SIS implementation.
+ throw new IllegalStateException(e); // Should not happen with SIS implementation.
}
final ParameterValueGroup parameters = method.getParameters().createValue();
- String name = TransverseMercator.setParameters(parameters, true, latitude, longitude);
+ String name = isUTM ? TransverseMercator.Zoner.UTM.setParameters(parameters, latitude, longitude)
+ : PolarStereographicA.setParameters(parameters, latitude >= 0);
final DefaultConversion conversion = new DefaultConversion(properties(0, name, null, false), method, null, parameters);
name = baseCRS.getName().getCode() + " / " + name;
@@ -165,17 +170,17 @@ final class StandardDefinitions {
*/
static GeographicCRS createGeographicCRS(final short code, final GeodeticDatum datum, final EllipsoidalCS cs) {
final String name;
- String alias = null;
- String scope = null;
+ String alias = null;
+ String scope = null;
boolean world = false;
switch (code) {
- case 4326: name = "WGS 84"; world = true; scope = "Horizontal component of 3D system."; break;
- case 4322: name = "WGS 72"; world = true; break;
- case 4258: name = "ETRS89"; alias = "ETRS89-GRS80"; break;
- case 4269: name = "NAD83"; break;
- case 4267: name = "NAD27"; break;
- case 4230: name = "ED50"; break;
- case 4047: name = "Unspecified datum based upon the GRS 1980 Authalic Sphere"; world = true; break;
+ case 4326: name = "WGS 84"; world = true; scope = "Horizontal component of 3D system."; break;
+ case 4322: name = "WGS 72"; world = true; scope = "Horizontal component of 3D system."; break;
+ case 4258: name = "ETRS89"; alias = "ETRS89-GRS80"; scope = "Horizontal component of 3D system."; break;
+ case 4269: name = "NAD83"; scope = "Geodetic survey."; break;
+ case 4267: name = "NAD27"; scope = "Geodetic survey."; break;
+ case 4230: name = "ED50"; scope = "Geodetic survey."; break;
+ case 4047: name = "Unspecified datum based upon the GRS 1980 Authalic Sphere"; world = true; break;
default: throw new AssertionError(code);
}
final Map<String, Object> properties = properties(code, name, alias, world);
@@ -313,16 +318,17 @@ final class StandardDefinitions {
@SuppressWarnings("fallthrough")
static CoordinateSystem createCoordinateSystem(final short code) {
final String name;
- final int dim; // Number of dimension.
+ int type = 0; // 0= Cartesian (default), 1= Spherical, 2= Ellipsoidal
+ int dim = 2; // Number of dimension, default to 2.
short axisCode; // Code of first axis + dim (or code after the last axis).
- boolean isCartesian = false;
- boolean isSpherical = false;
switch (code) {
- case 6422: name = "Ellipsoidal 2D"; dim = 2; axisCode = 108; break;
- case 6423: name = "Ellipsoidal 3D"; dim = 3; axisCode = 111; break;
- case 6404: name = "Spherical"; dim = 3; axisCode = 63; isSpherical = true; break;
- case 6500: name = "Earth centred"; dim = 3; axisCode = 118; isCartesian = true; break;
- case 4400: name = "Cartesian 2D"; dim = 2; axisCode = 3; isCartesian = true; break;
+ case 6422: name = "Ellipsoidal 2D"; type = 2; axisCode = 108; break;
+ case 6423: name = "Ellipsoidal 3D"; type = 2; dim = 3; axisCode = 111; break;
+ case 6404: name = "Spherical"; type = 1; dim = 3; axisCode = 63; break;
+ case 6500: name = "Earth centred"; dim = 3; axisCode = 118; break;
+ case 4400: name = "Cartesian 2D"; axisCode = 3; break;
+ case 1026: name = "Cartesian 2D for UPS north"; axisCode = 1067; break;
+ case 1027: name = "Cartesian 2D for UPS south"; axisCode = 1059; break;
default: throw new AssertionError(code);
}
final Map<String,?> properties = properties(code, name, null, false);
@@ -334,20 +340,13 @@ final class StandardDefinitions {
case 1: xAxis = createAxis(--axisCode);
case 0: break;
}
- if (isCartesian) {
- if (zAxis != null) {
- return new DefaultCartesianCS(properties, xAxis, yAxis, zAxis);
- } else {
- return new DefaultCartesianCS(properties, xAxis, yAxis);
- }
- } else if (isSpherical) {
- return new DefaultSphericalCS(properties, xAxis, yAxis, zAxis);
- } else {
- if (zAxis != null) {
- return new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis);
- } else {
- return new DefaultEllipsoidalCS(properties, xAxis, yAxis);
- }
+ switch (type) {
+ default: throw new AssertionError(type);
+ case 0: return (zAxis != null) ? new DefaultCartesianCS (properties, xAxis, yAxis, zAxis)
+ : new DefaultCartesianCS (properties, xAxis, yAxis);
+ case 1: return new DefaultSphericalCS (properties, xAxis, yAxis, zAxis);
+ case 2: return (zAxis != null) ? new DefaultEllipsoidalCS(properties, xAxis, yAxis, zAxis)
+ : new DefaultEllipsoidalCS(properties, xAxis, yAxis);
}
}
@@ -367,12 +366,10 @@ final class StandardDefinitions {
switch (code) {
case 1: name = "Easting";
abrv = "E";
- unit = Units.METRE;
dir = AxisDirection.EAST;
break;
case 2: name = "Northing";
abrv = "N";
- unit = Units.METRE;
dir = AxisDirection.NORTH;
break;
case 60: name = "Spherical latitude";
@@ -393,7 +390,6 @@ final class StandardDefinitions {
break;
case 62: name = "Geocentric radius";
abrv = "R"; // See HardCodedAxes.GEOCENTRIC_RADIUS in tests.
- unit = Units.METRE;
dir = AxisDirection.UP;
rm = RangeMeaning.EXACT;
min = 0;
@@ -440,6 +436,23 @@ final class StandardDefinitions {
abrv = "Z";
dir = AxisDirection.GEOCENTRIC_Z;
break;
+ case 1057: // Actually no axis allocated by EPSG here, but createCoordinateSystem(1027) needs this number.
+ case 1056: name = "Easting";
+ abrv = "E";
+ dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 90);
+ break;
+ case 1058: name = "Northing";
+ abrv = "N";
+ dir = CoordinateSystems.directionAlongMeridian(AxisDirection.NORTH, 0);
+ break;
+ case 1065: name = "Easting";
+ abrv = "E";
+ dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 90);
+ break;
+ case 1066: name = "Northing";
+ abrv = "N";
+ dir = CoordinateSystems.directionAlongMeridian(AxisDirection.SOUTH, 180);
+ break;
default: throw new AssertionError(code);
}
final Map<String,Object> properties = properties(code, name, null, false);
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/crs/AbstractCRS.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -169,7 +169,7 @@ public class AbstractCRS extends Abstrac
* </tr>
* </table>
*
- * @param properties The properties to be given to the coordinate reference system.
+ * @param properties the properties to be given to the coordinate reference system.
* @param cs the coordinate system.
*/
public AbstractCRS(final Map<String,?> properties, final CoordinateSystem cs) {
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/cs/DefaultCoordinateSystemAxis.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -19,6 +19,7 @@ package org.apache.sis.referencing.cs;
import java.util.Map;
import java.util.HashMap;
import java.util.Locale;
+import java.util.Objects;
import javax.measure.Unit;
import javax.measure.quantity.Angle;
import javax.measure.UnitConverter;
@@ -45,6 +46,7 @@ import org.apache.sis.referencing.Identi
import org.apache.sis.measure.Longitude;
import org.apache.sis.measure.Latitude;
import org.apache.sis.measure.Units;
+import org.apache.sis.util.Utilities;
import org.apache.sis.util.ComparisonMode;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.internal.jaxb.Context;
@@ -69,9 +71,6 @@ import static org.apache.sis.util.collec
*/
import static org.apache.sis.internal.referencing.NilReferencingObject.UNNAMED;
-// Branch-dependent imports
-import java.util.Objects;
-
/**
* Coordinate system axis name, direction, unit and range of values.
@@ -567,12 +566,13 @@ public class DefaultCoordinateSystemAxis
* i.e. it is caller responsibility to determine if range shall be considered as metadata.
*
* @param that the axis to compare with this axis.
+ * @param mode whether the unit comparison is approximative or exact.
* @param cr {@code true} for comparing also the range minimum and maximum values.
* @return {@code true} if unit, direction and optionally range extremum are equal.
*/
- private boolean equalsIgnoreMetadata(final CoordinateSystemAxis that, final boolean cr) {
- return Objects.equals(getUnit(), that.getUnit()) &&
- Objects.equals(getDirection(), that.getDirection()) &&
+ private boolean equalsIgnoreMetadata(final CoordinateSystemAxis that, final ComparisonMode mode, final boolean cr) {
+ return Objects.equals(getDirection(), that.getDirection()) &&
+ Utilities.deepEquals(getUnit(), that.getUnit(), mode) &&
(!cr || (doubleToLongBits(getMinimumValue()) == doubleToLongBits(that.getMinimumValue()) &&
doubleToLongBits(getMaximumValue()) == doubleToLongBits(that.getMaximumValue())));
}
@@ -618,7 +618,7 @@ public class DefaultCoordinateSystemAxis
}
case BY_CONTRACT: {
final CoordinateSystemAxis that = (CoordinateSystemAxis) object;
- return equalsIgnoreMetadata(that, true) &&
+ return equalsIgnoreMetadata(that, mode, true) &&
Objects.equals(getAbbreviation(), that.getAbbreviation()) &&
Objects.equals(getRangeMeaning(), that.getRangeMeaning());
}
@@ -629,8 +629,8 @@ public class DefaultCoordinateSystemAxis
* coordinate operation may shift some ordinate values (typically �360� on longitudes).
*/
final CoordinateSystemAxis that = (CoordinateSystemAxis) object;
- if (!equalsIgnoreMetadata(that, RangeMeaning.WRAPAROUND.equals(this.getRangeMeaning()) &&
- RangeMeaning.WRAPAROUND.equals(that.getRangeMeaning())))
+ if (!equalsIgnoreMetadata(that, mode, RangeMeaning.WRAPAROUND.equals(this.getRangeMeaning()) &&
+ RangeMeaning.WRAPAROUND.equals(that.getRangeMeaning())))
{
return false;
}
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DatumShiftGrid.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -233,9 +233,9 @@ public abstract class DatumShiftGrid<C e
}
/**
- * Computes the conversion factors needed by {@link #interpolateAtNormalized(double, double, double[])}.
- * This method takes only the 2 first dimensions. If a conversion factor can not be computed, then it is
- * set to NaN.
+ * Computes the conversion factors needed by {@link #interpolateInCell(double, double, double[])}.
+ * This method takes only the 2 first dimensions. If a conversion factor can not be computed,
+ * then it is set to NaN.
*/
@SuppressWarnings("fallthrough")
private void computeConversionFactors() {
@@ -308,7 +308,7 @@ public abstract class DatumShiftGrid<C e
* validity will still be accepted, but the extrapolated results may be very wrong.
*
* <p>The unit of measurement for the coordinate values in the returned envelope is
- * given by {@link #getCoordinateUnit()}. The complete CRS is undefined.</p>
+ * given by {@link #getCoordinateUnit()}. The envelope CRS is undefined.</p>
*
* @return the domain covered by this grid.
* @throws TransformException if an error occurred while computing the envelope.
@@ -327,6 +327,7 @@ public abstract class DatumShiftGrid<C e
*
* @return the unit of measurement of input values before conversion to grid indices.
*
+ * @see #getTranslationUnit()
* @see org.apache.sis.referencing.operation.AbstractCoordinateOperation#getInterpolationCRS()
*/
public Unit<C> getCoordinateUnit() {
@@ -339,7 +340,7 @@ public abstract class DatumShiftGrid<C e
* given by {@link #getCoordinateUnit()}.
* The output points are grid indices with integer values in the center of grid cells.
*
- * <p>This transform is usually two-dimensional and linear, in which case conversions from (<var>x</var>,<var>y</var>)
+ * <p>This transform is usually two-dimensional, in which case conversions from (<var>x</var>,<var>y</var>)
* coordinates to ({@code gridX}, {@code gridY}) indices can be done with the following formulas:</p>
* <ul>
* <li><var>gridX</var> = (<var>x</var> - <var>x\u2080</var>) / <var>\u0394x</var></li>
@@ -416,6 +417,7 @@ public abstract class DatumShiftGrid<C e
*
* @return the unit of measurement of output values interpolated by {@code interpolateAt(\u2026)}.
*
+ * @see #getCoordinateUnit()
* @see #interpolateAt
*/
public Unit<T> getTranslationUnit() {
@@ -461,7 +463,7 @@ public abstract class DatumShiftGrid<C e
/**
* Interpolates the translation to apply for the given two-dimensional grid indices. The result is stored in
* the given {@code vector} array, which shall have a length of at least {@link #getTranslationDimensions()}.
- * The output unit of measurement is the same than the one documented in {@link #getCellValue}.
+ * The output unit of measurement is the same than the one documented in {@link #getCellValue(int, int, int)}.
*
* <div class="section">Default implementation</div>
* The default implementation performs the following steps for each dimension <var>dim</var>,
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/datum/DefaultEllipsoid.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -17,6 +17,7 @@
package org.apache.sis.referencing.datum;
import java.util.Map;
+import java.util.Objects;
import javax.measure.Unit;
import javax.measure.quantity.Length;
import javax.measure.UnitConverter;
@@ -42,6 +43,7 @@ import org.apache.sis.referencing.Abstra
import org.apache.sis.io.wkt.Formatter;
import org.apache.sis.io.wkt.Convention;
import org.apache.sis.util.ComparisonMode;
+import org.apache.sis.util.Utilities;
import org.apache.sis.measure.Units;
import static java.lang.Math.*;
@@ -49,9 +51,6 @@ import static java.lang.Double.*;
import static org.apache.sis.util.ArgumentChecks.ensureStrictlyPositive;
import static org.apache.sis.util.ArgumentChecks.ensureNonNull;
-// Branch-dependent imports
-import java.util.Objects;
-
/**
* Geometric figure that can be used to describe the approximate shape of the earth.
@@ -717,7 +716,7 @@ public class DefaultEllipsoid extends Ab
*/
final Ellipsoid that = (Ellipsoid) object;
final Unit<Length> unit = getAxisUnit(); // In case the user override this method.
- if (!Objects.equals(unit, that.getAxisUnit())) {
+ if (!Utilities.deepEquals(unit, that.getAxisUnit(), mode)) {
return false;
}
final UnitConverter c = mode.isApproximative() ? unit.getConverterTo(Units.METRE) : null;
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/factory/CommonAuthorityFactory.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -43,6 +43,7 @@ import org.opengis.referencing.cs.Cartes
import org.opengis.referencing.cs.AxisDirection;
import org.opengis.referencing.datum.DatumFactory;
import org.opengis.referencing.datum.EngineeringDatum;
+import org.apache.sis.internal.referencing.provider.TransverseMercator.Zoner;
import org.apache.sis.internal.referencing.GeodeticObjectBuilder;
import org.apache.sis.internal.referencing.Resources;
import org.apache.sis.metadata.iso.citation.Citations;
@@ -60,9 +61,6 @@ import org.apache.sis.util.resources.Err
import org.apache.sis.util.iso.DefaultNameSpace;
import org.apache.sis.util.iso.SimpleInternationalString;
-import static org.apache.sis.internal.referencing.provider.TransverseMercator.zone;
-import static org.apache.sis.internal.referencing.provider.TransverseMercator.centralMeridian;
-
/**
* Creates coordinate reference systems in the "{@code OGC}", "{@code CRS}" or {@code "AUTO(2)"} namespaces.
@@ -178,14 +176,18 @@ import static org.apache.sis.internal.re
*
* <div class="note"><b>Examples:</b>
* {@code "AUTO2:42001,1,-100,45"} identifies a Universal Transverse Mercator (UTM) projection
- * for a zone containing the point at (45�N, 100�W).</div>
+ * for a zone containing the point at (45�N, 100�W) with axes in metres.</div>
*
* Codes in the {@code "AUTO"} namespace are the same than codes in the {@code "AUTO2"} namespace, except that
* the {@linkplain org.apache.sis.measure.Units#valueOfEPSG(int) EPSG code} of the desired unit of measurement
* was used instead than the unit factor.
* The {@code "AUTO"} namespace was defined in the <cite>Web Map Service</cite> (WMS) 1.1.1 specification
* while the {@code "AUTO2"} namespace is defined in WMS 1.3.0.
- * In Apache SIS implementation, the unit parameter (either as factor or as EPSG code) is optional and default to metres.
+ * In Apache SIS implementation, the unit parameter (either as factor or as EPSG code) is optional and defaults to metres.
+ *
+ * <p>In the {@code AUTO(2):42001} case, the UTM zone is calculated as specified in WMS 1.3 specification,
+ * i.e. <strong>without</strong> taking in account the Norway and Svalbard special cases and without
+ * switching to polar stereographic projections for high latitudes.</p>
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.7
@@ -588,23 +590,26 @@ public class CommonAuthorityFactory exte
* 42005: WGS 84 / Auto Mollweide \u2014 defined by "Central_Meridian" only.
*/
case 42001: isUTM = true; break;
- case 42002: isUTM = (latitude == 0) && (centralMeridian(zone(longitude)) == longitude); break;
- case 42003: method = "Orthographic"; param = Constants.LATITUDE_OF_ORIGIN; break;
- case 42004: method = "Equirectangular"; param = Constants.STANDARD_PARALLEL_1; break;
- case 42005: method = "Mollweide"; break;
+ case 42002: isUTM = (latitude == 0) && (Zoner.UTM.centralMeridian(Zoner.UTM.zone(0, longitude)) == longitude); break;
+ case 42003: method = "Orthographic"; param = Constants.LATITUDE_OF_ORIGIN; break;
+ case 42004: method = "Equirectangular"; param = Constants.STANDARD_PARALLEL_1; break;
+ case 42005: method = "Mollweide"; break;
default: throw noSuchAuthorityCode(String.valueOf(projection), code, null);
}
/*
* For the (Universal) Transverse Mercator case (AUTO:42001 and 42002), we delegate to the CommonCRS
* enumeration if possible because CommonCRS will itself delegate to the EPSG factory if possible.
+ * The Math.signum(latitude) instruction is for preventing "AUTO:42001" to handle the UTM special cases
+ * (Norway and Svalbard) or to switch on the Universal Polar Stereographic projection for high latitudes,
+ * because the WMS specification does not said that we should.
*/
final CommonCRS datum = CommonCRS.WGS84;
- final GeographicCRS baseCRS;
- final ProjectedCRS crs;
- CartesianCS cs;
+ final GeographicCRS baseCRS; // To be set, directly or indirectly, to WGS84.geographic().
+ final ProjectedCRS crs; // Temporary UTM projection, for extracting other properties.
+ CartesianCS cs; // Coordinate system with (E,N) axes in metres.
try {
if (isUTM != null && isUTM) {
- crs = datum.UTM(latitude, longitude);
+ crs = datum.universal(Math.signum(latitude), longitude);
if (factor == (isLegacy ? Constants.EPSG_METRE : 1)) {
return crs;
}
@@ -613,7 +618,7 @@ public class CommonAuthorityFactory exte
} else {
cs = projectedCS;
if (cs == null) {
- crs = datum.UTM(latitude, longitude);
+ crs = datum.universal(Math.signum(latitude), longitude);
projectedCS = cs = crs.getCoordinateSystem();
baseCRS = crs.getBaseCRS();
} else {
@@ -641,10 +646,10 @@ public class CommonAuthorityFactory exte
*/
final GeodeticObjectBuilder builder = new GeodeticObjectBuilder();
if (isUTM != null) {
- if (isUTM) {
+ if (isUTM && crs != null) {
builder.addName(crs.getName());
} // else default to the conversion name, which is "Transverse Mercator".
- builder.setTransverseMercator(isUTM, latitude, longitude);
+ builder.setTransverseMercator(isUTM ? Zoner.UTM : Zoner.ANY, latitude, longitude);
} else {
builder.setConversionMethod(method)
.addName(PROJECTION_NAMES[projection - FIRST_PROJECTION_CODE])
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/LinearTransformBuilder.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -16,189 +16,720 @@
*/
package org.apache.sis.referencing.operation.builder;
+import java.util.Map;
+import java.util.Arrays;
import java.io.IOException;
+import org.opengis.util.FactoryException;
import org.opengis.geometry.DirectPosition;
import org.opengis.geometry.MismatchedDimensionException;
+import org.opengis.geometry.coordinate.Position;
+import org.opengis.referencing.operation.Matrix;
+import org.opengis.referencing.operation.MathTransformFactory;
import org.apache.sis.io.TableAppender;
import org.apache.sis.math.Line;
import org.apache.sis.math.Plane;
+import org.apache.sis.math.Vector;
import org.apache.sis.referencing.operation.matrix.Matrices;
import org.apache.sis.referencing.operation.matrix.MatrixSIS;
import org.apache.sis.referencing.operation.transform.LinearTransform;
-import org.apache.sis.referencing.operation.transform.MathTransforms;
+import org.apache.sis.internal.referencing.ExtendedPrecisionMatrix;
import org.apache.sis.util.resources.Vocabulary;
import org.apache.sis.util.resources.Errors;
import org.apache.sis.util.ArgumentChecks;
+import org.apache.sis.util.ArraysExt;
import org.apache.sis.util.Classes;
import org.apache.sis.util.Debug;
/**
- * Creates a linear (usually affine) transform which will map approximatively the given source points to
- * the given target points. The transform coefficients are determined using a <cite>least squares</cite>
- * estimation method, with the assumption that source points are precise and all uncertainty is in the
- * target points.
+ * Creates an affine transform which will map approximatively the given source positions to the given target positions.
+ * In many cases, the <em>source</em> positions are grid indices and the <em>target</em> positions are geographic or
+ * projected coordinates, but this is not mandatory. If the source positions are known to be grid indices,
+ * then a builder created by the {@link #LinearTransformBuilder(int...)} constructor will be more efficient.
+ * Otherwise a builder created by the {@link #LinearTransformBuilder()} constructor will be able to handle
+ * randomly distributed coordinates.
*
- * <div class="note"><b>Implementation note:</b>
- * The quantity that current implementation tries to minimize is not strictly the squared Euclidian distance.
- * The current implementation rather processes each target dimension independently, which may not give the same
- * result than if we tried to minimize the squared Euclidian distances by taking all dimensions in account together.
- * This algorithm may change in future SIS versions.
- * </div>
+ * <p>The transform coefficients are determined using a <cite>least squares</cite> estimation method,
+ * with the assumption that source positions are exact and all the uncertainty is in the target positions.</p>
*
* @author Martin Desruisseaux (Geomatys)
* @since 0.5
- * @version 0.5
+ * @version 0.8
* @module
*
+ * @see LocalizationGridBuilder
* @see LinearTransform
* @see Line
* @see Plane
*/
-public class LinearTransformBuilder {
+public class LinearTransformBuilder extends TransformBuilder {
/**
- * The arrays of source ordinate values, for example (x[], y[]).
- * This is {@code null} if not yet specified.
+ * Number of grid columns and rows, or {@code null} if the coordinates are not distributed on a regular grid.
+ * If the grid size is known, then the {@link #sources} coordinates do not need to be specified.
+ */
+ private final int[] gridSize;
+
+ /**
+ * The arrays of source ordinate values. Accessed with indices in that order: {@code sources[dimension][point]}.
+ * This layout allows to create only a few (typically two) large arrays instead of a multitude of small arrays.
+ * Example: {x[], y[]}.
+ *
+ * <p>In the special case where {@link #gridSize} is non-null, then this array does not need to be specified
+ * and can be {@code null}. In such case, the source coordinates are implicitly:</p>
+ *
+ * <blockquote>
+ * (0,0), (1,0), (2,0), (3,0) \u2026 ({@link #gridSize}[0]-1, 0),<br>
+ * (0,1), (1,1), (2,1), (3,1) \u2026 ({@link #gridSize}[0]-1, 1),<br>
+ * (0,2), (1,2), (2,2), (3,2) \u2026 ({@link #gridSize}[0]-1, 2),<br>
+ * (0,{@link #gridSize}[1]-1) \u2026 ({@link #gridSize}[0]-1, {@link #gridSize}[1]-1).
+ * </blockquote>
*/
private double[][] sources;
/**
- * The arrays of target ordinate values, for example (x[], y[], z[]).
+ * The arrays of target ordinate values. Accessed with indices in that order: {@code targets[dimension][point]}.
+ * This layout allows to create only a few (typically two) large arrays instead of a multitude of small arrays.
+ * Example: {x[], y[], z[]}.
* This is {@code null} if not yet specified.
*/
private double[][] targets;
/**
+ * The product of all {@link #gridSize} values, or 0 if none if {@link #gridSize} is null.
+ * If non-zero, then this is the length of {@link #targets} arrays to create.
+ */
+ final int gridLength;
+
+ /**
+ * Number of valid positions in the {@link #sources} or {@link #targets} arrays.
+ * Note that the "valid" positions may contain {@link Double#NaN}�ordinate values.
+ * This field is only indicative if this {@code LinearTransformBuilder} instance
+ * has been created by {@link #LinearTransformBuilder(int...)}.
+ */
+ private int numPoints;
+
+ /**
* The transform created by the last call to {@link #create()}.
+ * This is reset to {@code null} when coordinates are modified.
*/
- private LinearTransform transform;
+ private transient LinearTransform transform;
/**
* An estimation of the Pearson correlation coefficient for each target dimension.
- * This is {@code null} if not yet specified.
+ * This is {@code null} if not yet computed.
*/
- private double[] correlation;
+ private transient double[] correlation;
/**
- * Creates a new linear transform builder.
+ * Creates a new linear transform builder for randomly distributed positions.
+ *
+ * <div class="note"><b>Tip:</b>
+ * if the source coordinates are grid indices, then
+ * the {@link #LinearTransformBuilder(int...)} constructor will create a more efficient builder.
+ * </div>
*/
public LinearTransformBuilder() {
+ gridSize = null;
+ gridLength = 0;
+ }
+
+ /**
+ * Creates a new linear transform builder for source positions distributed on a regular grid.
+ * This constructor notifies {@code LinearTransformBuilder}�that ordinate values of all source positions will
+ * be integers in the [0 \u2026 {@code gridSize[0]}-1] range for the first dimension (typically column indices),
+ * in the [0 \u2026 {@code gridSize[1]}-1] range for the second dimension (typically row indices), <i>etc.</i>
+ * The dimension of all source positions is the length of the given {@code gridSize} array.
+ *
+ * <p>An empty array is equivalent to invoking the no-argument constructor,
+ * i.e. no restriction is put on the source coordinates.</p>
+ *
+ * @param gridSize the number of integer ordinate values in each grid dimension.
+ * @throws IllegalArgumentException if a grid size is not strictly positive, or if the product
+ * of all values (\u220f{@code gridSize}) is greater than {@link Integer#MAX_VALUE}.
+ *
+ * @since 0.8
+ */
+ public LinearTransformBuilder(int... gridSize) {
+ ArgumentChecks.ensureNonNull("gridSize", gridSize);
+ if (gridSize.length == 0) {
+ this.gridSize = null;
+ this.gridLength = 0;
+ } else {
+ gridSize = gridSize.clone();
+ long length = 1;
+ for (int s : gridSize) {
+ ArgumentChecks.ensureStrictlyPositive("gridSize", s);
+ length = Math.multiplyExact(length, s);
+ }
+ if (length > Integer.MAX_VALUE) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.ValueOutOfRange_4,
+ "\u220fgridSize", 1, Integer.MAX_VALUE, length));
+ }
+ this.gridSize = gridSize;
+ gridLength = (int) length;
+ }
+ }
+
+ /**
+ * Returns the grid size for the given dimension. It is caller's responsibility to ensure that
+ * this method is invoked only on instances created by {@link #LinearTransformBuilder(int...)}.
+ */
+ final int gridSize(final int srcDim) {
+ return gridSize[srcDim];
+ }
+
+ /**
+ * Allocates memory for a builder created for source positions distributed on a grid.
+ * All target values need to be initialized to NaN because we can not rely on {@link #numPoints}.
+ *
+ * <p>If this builder has been created for randomly distributed source points, then the allocation
+ * should rather be performed as below:</p>
+ *
+ * {@preformat java
+ * sources = new double[srcDim][capacity];
+ * targets = new double[tgtDim][capacity];
+ * }
+ */
+ private void allocate(final int tgtDim) {
+ targets = new double[tgtDim][gridLength];
+ for (final double[] r : targets) {
+ Arrays.fill(r, Double.NaN);
+ }
+ }
+
+ /**
+ * Resize all the given arrays to the given capacity. This method should be invoked only for
+ * {@code LinearTransformBuilder} instances created for randomly distributed source positions.
+ */
+ private static void resize(double[][] data, final int capacity) {
+ for (int i=0; i<data.length; i++) {
+ data[i] = ArraysExt.resize(data[i], capacity);
+ }
+ }
+
+ /**
+ * Returns the offset of the given source grid coordinate, or -1 if none. The algorithm implemented in this
+ * method is inefficient, but should rarely be used. This is only a fallback when {@link #flatIndex(int[])}
+ * can not be used.
+ */
+ private int search(final int[] source) {
+ assert gridSize == null; // This method should not be invoked for points distributed on a grid.
+search: for (int j=0; j<numPoints; j++) {
+ for (int i=0; i<source.length; i++) {
+ if (source[i] != sources[i][j]) {
+ continue search; // Search another position for the same source.
+ }
+ }
+ return j;
+ }
+ return -1;
+ }
+
+ /**
+ * Returns the offset where to store a target position for the given source position in the flattened array.
+ * This method should be invoked only when this {@code LinearTransformBuilder} has been created for a grid
+ * of known size. Caller must have verified the array length before to invoke this method.
+ *
+ * @throws IllegalArgumentException if an ordinate value is illegal.
+ */
+ private int flatIndex(final int[] source) {
+ assert sources == null; // This method should not be invoked for randomly distributed points.
+ int offset = 0;
+ for (int i = gridSize.length; i != 0;) {
+ final int size = gridSize[--i];
+ final int index = source[i];
+ if (index < 0 || index >= size) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.ValueOutOfRange_4, "source", 0, size-1, index));
+ }
+ offset = offset * size + index;
+ }
+ return offset;
}
/**
- * Extracts the ordinate values of the given points into separated arrays, one for each dimension.
+ * Returns the index where to store a target position for the given source position in the flattened array.
+ * This method should be invoked only when this {@code LinearTransformBuilder} has been created for a grid
+ * of known size. Callers must have verified the position dimension before to invoke this method.
*
- * @param points the points from which to extract the ordinate values.
- * @param dimension the expected number of dimensions.
+ * @throws IllegalArgumentException if an ordinate value is illegal.
*/
- private static double[][] toArrays(final DirectPosition[] points, final int dimension) {
- final int length = points.length;
- final double[][] ordinates = new double[dimension][length];
- for (int j=0; j<length; j++) {
- final DirectPosition p = points[j];
- final int d = p.getDimension();
- if (d != dimension) {
- throw new MismatchedDimensionException(Errors.format(
- Errors.Keys.MismatchedDimension_3, "points[" + j + ']', dimension, d));
+ private int flatIndex(final DirectPosition source) {
+ assert sources == null; // This method should not be invoked for randomly distributed points.
+ int offset = 0;
+ for (int i = gridSize.length; i != 0;) {
+ final int size = gridSize[--i];
+ final double ordinate = source.getOrdinate(i);
+ final int index = (int) ordinate;
+ if (index != ordinate) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.NotAnInteger_1, ordinate));
}
- for (int i=0; i<dimension; i++) {
- ordinates[i][j] = p.getOrdinate(i);
+ if (index < 0 || index >= size) {
+ throw new IllegalArgumentException(Errors.format(Errors.Keys.ValueOutOfRange_4, "source", 0, size-1, index));
}
+ offset = offset * size + index;
}
- return ordinates;
+ return offset;
+ }
+
+ /**
+ * Verifies that the given number of dimensions is equal to the expected value.
+ * No verification are done if the source point is the first point of randomly distributed points.
+ */
+ private void verifySourceDimension(final int actual) {
+ final int expected;
+ if (gridSize != null) {
+ expected = gridSize.length;
+ } else if (sources != null) {
+ expected = sources.length;
+ } else {
+ return;
+ }
+ if (actual != expected) {
+ throw new MismatchedDimensionException(Errors.format(Errors.Keys.MismatchedDimension_3, "source", expected, actual));
+ }
+ }
+
+ /**
+ * Builds the exception message for an unexpected position dimension. This method assumes
+ * that positions are stored in this builder as they are read from user-provided collection.
+ */
+ private String mismatchedDimension(final String name, final int expected, final int actual) {
+ return Errors.format(Errors.Keys.MismatchedDimension_3, name + '[' + numPoints + ']', expected, actual);
+ }
+
+ /**
+ * Returns the error message to be given to {@link IllegalStateException} when there is no data.
+ */
+ private static String noData() {
+ return Errors.format(Errors.Keys.MissingValueForProperty_1, "sourceToTarget");
}
/**
- * Sets the source points. The number of points shall be the same than the number of target points.
+ * Returns the number of dimensions in source positions.
+ *
+ * @return the dimension of source points.
+ * @throws IllegalStateException if the number of source dimensions is not yet known.
*
- * <p><b>Limitation:</b> in current implementation, the source points must be one or two-dimensional.
- * This restriction may be removed in a future SIS version.</p>
+ * @see LinearTransform#getSourceDimensions()
+ *
+ * @since 0.8
+ */
+ public int getSourceDimensions() {
+ if (gridSize != null) return gridSize.length;
+ if (sources != null) return sources.length;
+ throw new IllegalStateException(noData());
+ }
+
+ /**
+ * Returns the number of dimensions in target positions.
+ *
+ * @return the dimension of target points.
+ * @throws IllegalStateException if the number of target dimensions is not yet known.
+ *
+ * @see LinearTransform#getTargetDimensions()
+ *
+ * @since 0.8
+ */
+ public int getTargetDimensions() {
+ if (targets != null) return targets.length;
+ throw new IllegalStateException(noData());
+ }
+
+ /**
+ * Returns the direct position of the given position, or {@code null} if none.
+ */
+ private static DirectPosition position(final Position p) {
+ return (p != null) ? p.getDirectPosition() : null;
+ }
+
+ /**
+ * Sets all matching control point pairs, overwriting any previous setting. The source positions are the keys in
+ * the given map, and the target positions are the associated values in the map. The map should not contain two
+ * entries with the same source position. Coordinate reference systems are ignored.
+ * Null positions are silently ignored.
+ *
+ * <p>All source positions shall have the same number of dimensions (the <cite>source dimension</cite>),
+ * and all target positions shall have the same number of dimensions (the <cite>target dimension</cite>).
+ * However the source dimension does not need to be the same the target dimension.
+ * Apache SIS currently supports only one- or two-dimensional source positions,
+ * together with arbitrary target dimension.</p>
+ *
+ * <p>If this builder has been created with the {@link #LinearTransformBuilder(int...)} constructor,
+ * then the ordinate values of all source positions shall be integers in the [0 \u2026 {@code gridSize[0]}-1]
+ * range for the first dimension (typically column indices), in the [0 \u2026 {@code gridSize[1]}-1] range for
+ * the second dimension (typically row indices), <i>etc</i>. This constraint does not apply for builders
+ * created with the {@link #LinearTransformBuilder()} constructor.</p>
+ *
+ * @param sourceToTarget a map of source positions to target positions.
+ * Source positions are assumed precise and target positions are assumed uncertain.
+ * @throws IllegalArgumentException if this builder has been {@linkplain #LinearTransformBuilder(int...)
+ * created for a grid} but some source ordinates are not indices in that grid.
+ * @throws MismatchedDimensionException if some positions do not have the expected number of dimensions.
+ *
+ * @since 0.8
+ */
+ public void setControlPoints(final Map<? extends Position, ? extends Position> sourceToTarget)
+ throws MismatchedDimensionException
+ {
+ ArgumentChecks.ensureNonNull("sourceToTarget", sourceToTarget);
+ pendingSources = null;
+ pendingTargets = null;
+ transform = null;
+ correlation = null;
+ sources = null;
+ targets = null;
+ numPoints = 0;
+ int srcDim = 0;
+ int tgtDim = 0;
+ for (final Map.Entry<? extends Position, ? extends Position> entry : sourceToTarget.entrySet()) {
+ final DirectPosition src = position(entry.getKey()); if (src == null) continue;
+ final DirectPosition tgt = position(entry.getValue()); if (tgt == null) continue;
+ /*
+ * The first time that we get a non-null source and target coordinate, allocate the arrays.
+ * The sources arrays are allocated only if the source coordiantes are randomly distributed.
+ */
+ if (targets == null) {
+ tgtDim = tgt.getDimension();
+ if (tgtDim <= 0) {
+ throw new MismatchedDimensionException(mismatchedDimension("target", 2, tgtDim));
+ }
+ if (gridSize == null) {
+ srcDim = src.getDimension();
+ if (srcDim <= 0) {
+ throw new MismatchedDimensionException(mismatchedDimension("source", 2, srcDim));
+ }
+ final int capacity = sourceToTarget.size();
+ sources = new double[srcDim][capacity];
+ targets = new double[tgtDim][capacity];
+ } else {
+ srcDim = gridSize.length;
+ allocate(tgtDim);
+ }
+ }
+ /*
+ * Verify that the source and target coordinates have the expected number of dimensions before to store
+ * the coordinates. If the grid size is known, we do not need to store the source coordinates. Instead,
+ * we compute its index in the fixed-size target arrays.
+ */
+ int d;
+ if ((d = src.getDimension()) != srcDim) throw new MismatchedDimensionException(mismatchedDimension("source", srcDim, d));
+ if ((d = tgt.getDimension()) != tgtDim) throw new MismatchedDimensionException(mismatchedDimension("target", tgtDim, d));
+ int index;
+ if (gridSize != null) {
+ index = flatIndex(src);
+ } else {
+ index = numPoints;
+ for (int i=0; i<srcDim; i++) {
+ sources[i][index] = src.getOrdinate(i);
+ }
+ }
+ for (int i=0; i<tgtDim; i++) {
+ targets[i][index] = tgt.getOrdinate(i);
+ }
+ numPoints++;
+ }
+ }
+
+ /**
+ * Sets a single matching control point pair. Source position is assumed precise and target position is assumed uncertain.
+ * If the given source position was already associated with another target position, then the old target position is discarded.
+ *
+ * <div class="note"><b>Performance note:</b>
+ * current implementation is efficient for builders {@linkplain #LinearTransformBuilder(int...) created for a grid}
+ * but inefficient for builders {@linkplain #LinearTransformBuilder() created for randomly distributed points}.
+ * In the later case, the {@link #setControlPoints(Map)} method is a more efficient alternative.</div>
+ *
+ * @param source the source coordinates. If this builder has been created with the {@link #LinearTransformBuilder(int...)} constructor,
+ * then for every index <var>i</var> the {@code source[i]} value shall be in the [0 \u2026 {@code gridSize[i]}-1] range inclusive.
+ * If this builder has been created with the {@link #LinearTransformBuilder()} constructor, then no constraint apply.
+ * @param target the target coordinates, assumed uncertain.
+ * @throws IllegalArgumentException if this builder has been {@linkplain #LinearTransformBuilder(int...) created for a grid}
+ * but some source ordinates are out of index range.
+ * @throws MismatchedDimensionException if the source or target position does not have the expected number of dimensions.
+ *
+ * @since 0.8
+ */
+ public void setControlPoint(final int[] source, final double[] target) {
+ ArgumentChecks.ensureNonNull("source", source);
+ ArgumentChecks.ensureNonNull("target", target);
+ verifySourceDimension(source.length);
+ final int tgtDim = target.length;
+ if (targets != null && tgtDim != targets.length) {
+ throw new MismatchedDimensionException(Errors.format(
+ Errors.Keys.MismatchedDimension_3, "target", targets.length, tgtDim));
+ }
+ int index;
+ if (gridSize != null) {
+ index = flatIndex(source); // Invoked first for validating argument before to allocate arrays.
+ if (targets == null) {
+ allocate(tgtDim);
+ }
+ } else {
+ /*
+ * Case of randomly distributed points. Algorithm used below is inefficient, but Javadoc
+ * warns the user that (s)he should use setControlPoints(Map) instead in such case.
+ */
+ final int srcDim = source.length;
+ if (targets == null) {
+ targets = new double[tgtDim][20]; // Arbitrary initial capacity of 20 points.
+ sources = new double[srcDim][20];
+ }
+ index = search(source);
+ if (index < 0) {
+ index = numPoints++;
+ if (numPoints >= targets[0].length) {
+ final int n = Math.multiplyExact(numPoints, 2);
+ resize(sources, n);
+ resize(targets, n);
+ }
+ }
+ for (int i=0; i<srcDim; i++) {
+ sources[i][index] = source[i];
+ }
+ }
+ for (int i=0; i<tgtDim; i++) {
+ targets[i][index] = target[i];
+ }
+ }
+
+ /**
+ * Returns a single target coordinate for the given source coordinate, or {@code null} if none.
+ * This method can be used for retrieving points set by previous calls to
+ * {@link #setControlPoint(int[], double[])} or {@link #setControlPoints(Map)}.
+ *
+ * <div class="note"><b>Performance note:</b>
+ * current implementation is efficient for builders {@linkplain #LinearTransformBuilder(int...) created for a grid}
+ * but inefficient for builders {@linkplain #LinearTransformBuilder() created for randomly distributed points}.</div>
+ *
+ * @param source the source coordinates. If this builder has been created with the {@link #LinearTransformBuilder(int...)} constructor,
+ * then for every index <var>i</var> the {@code source[i]} value shall be in the [0 \u2026 {@code gridSize[i]}-1] range inclusive.
+ * If this builder has been created with the {@link #LinearTransformBuilder()} constructor, then no constraint apply.
+ * @return the target coordinates associated to the given source, or {@code null} if none.
+ * @throws IllegalArgumentException if this builder has been {@linkplain #LinearTransformBuilder(int...) created for a grid}
+ * but some source ordinates are out of index range.
+ * @throws MismatchedDimensionException if the source position does not have the expected number of dimensions.
+ *
+ * @since 0.8
+ */
+ public double[] getControlPoint(final int[] source) {
+ processPendings();
+ ArgumentChecks.ensureNonNull("source", source);
+ verifySourceDimension(source.length);
+ if (targets == null) {
+ return null;
+ }
+ final int index;
+ if (gridSize != null) {
+ index = flatIndex(source);
+ } else {
+ index = search(source);
+ if (index < 0) {
+ return null;
+ }
+ }
+ boolean isNaN = true;
+ final double[] target = new double[targets.length];
+ for (int i=0; i<target.length; i++) {
+ isNaN &= Double.isNaN(target[i] = targets[i][index]);
+ }
+ return isNaN ? null : target;
+ }
+
+ /**
+ * More straightforward version of {@link #getControlPoint(int[])} for the case where this
+ * {@code LinearTransformBuilder} is known to have been built for grid source coordinates.
+ * This method is for {@link LocalizationGridBuilder#create()} internal usage.
+ */
+ final void getControlPoint2D(final int[] source, final double[] target) {
+ assert gridSize != null;
+ final int index = flatIndex(source);
+ final int tgtDim = targets.length;
+ for (int i=0; i<tgtDim; i++) {
+ target[i] = targets[i][index];
+ }
+ }
+
+ /**
+ * Sets the source points, overwriting any previous setting. The number of source points will need to be the same
+ * than the number of {@linkplain #setTargetPoints target points} when the {@link #create()} method will be invoked.
+ * In current Apache SIS implementation, the source points must be one or two-dimensional.
+ *
+ * <p>If this builder has been created with the {@link #LinearTransformBuilder(int, int)} constructor,
+ * then all given points must be two-dimensional and all ordinate values must be integers in the
+ * [0 \u2026 <var>width</var>-1] or [0 \u2026 <var>height</var>-1] range for the first and second dimension
+ * respectively. This constraint does not apply if this builder has been created with the
+ * {@link #LinearTransformBuilder()} constructor.</p>
+ *
+ * <p>It is caller's responsibility to ensure that no source point is duplicated.
+ * If the same source point is repeated twice, then {@code LinearTransformBuilder} behavior is undefined.</p>
*
* @param points the source points, assumed precise.
* @throws MismatchedDimensionException if at least one point does not have the expected number of dimensions.
+ *
+ * @deprecated Replaced by {@link #setControlPoints(Map)}.
*/
+ @Deprecated
public void setSourcePoints(final DirectPosition... points) throws MismatchedDimensionException {
ArgumentChecks.ensureNonNull("points", points);
- if (points.length != 0) {
- sources = toArrays(points, points[0].getDimension() == 1 ? 1 : 2);
- } else {
- sources = null;
- }
transform = null;
correlation = null;
+ sources = null;
+ targets = null;
+ numPoints = 0;
+ pendingSources = points.clone();
}
/**
- * Sets the target points. The number of points shall be the same than the number of source points.
+ * Sets the target points, overwriting any previous setting. The number of target points will need to be the same
+ * than the number of {@linkplain #setSourcePoints source points} when the {@link #create()} method will be invoked.
* Target points can have any number of dimensions (not necessarily 2), but all points shall have
* the same number of dimensions.
*
* @param points the target points, assumed uncertain.
* @throws MismatchedDimensionException if not all points have the same number of dimensions.
+ *
+ * @deprecated Replaced by {@link #setControlPoints(Map)}.
*/
+ @Deprecated
public void setTargetPoints(final DirectPosition... points) throws MismatchedDimensionException {
ArgumentChecks.ensureNonNull("points", points);
- if (points.length != 0) {
- targets = toArrays(points, points[0].getDimension());
- } else {
- targets = null;
- }
transform = null;
correlation = null;
+ sources = null;
+ targets = null;
+ numPoints = 0;
+ pendingTargets = points.clone();
}
- /*
- * No getters yet because we did not determined what they should return.
- * Array? Collection? Map<source,target>?
- */
+ @Deprecated
+ private transient DirectPosition[] pendingSources, pendingTargets;
+
+ @Deprecated
+ private void processPendings() {
+ if (pendingSources != null || pendingTargets != null) {
+ if (pendingSources == null || pendingTargets == null) {
+ throw new IllegalStateException(Errors.format(
+ Errors.Keys.MissingValueForProperty_1, (pendingSources == null) ? "sources" : "targets"));
+ }
+ final int length = pendingSources.length;
+ if (pendingTargets.length != length) {
+ throw new IllegalStateException(Errors.format(Errors.Keys.MismatchedArrayLengths));
+ }
+ final Map<DirectPosition,DirectPosition> sourceToTarget = new java.util.HashMap<>(length);
+ for (int i=0; i<length; i++) {
+ sourceToTarget.put(pendingSources[i], pendingTargets[i]);
+ }
+ setControlPoints(sourceToTarget);
+ }
+ }
/**
- * Creates a linear transform approximation from the source points to the target points.
- * This method assumes that source points are precise and all uncertainty is in the target points.
+ * Creates a linear transform approximation from the source positions to the target positions.
+ * This method assumes that source positions are precise and that all uncertainty is in the target positions.
*
* @return the fitted linear transform.
+ *
+ * @deprecated Replaced by {@link #create(MathTransformFactory)}.
*/
+ @Deprecated
public LinearTransform create() {
+ try {
+ return create(null);
+ } catch (FactoryException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ /**
+ * Creates a linear transform approximation from the source positions to the target positions.
+ * This method assumes that source positions are precise and that all uncertainty is in the target positions.
+ *
+ * @param factory the factory to use for creating the transform, or {@code null} for the default factory.
+ * The {@link MathTransformFactory#createAffineTransform(Matrix)} method of that factory
+ * shall return {@link LinearTransform} instances.
+ * @return the fitted linear transform.
+ * @throws FactoryException if the transform can not be created,
+ * for example because the source or target points have not be specified.
+ *
+ * @since 0.8
+ */
+ @Override
+ @SuppressWarnings("serial")
+ public LinearTransform create(final MathTransformFactory factory) throws FactoryException {
if (transform == null) {
+ processPendings();
final double[][] sources = this.sources; // Protect from changes.
final double[][] targets = this.targets;
- if (sources == null || targets == null) {
- throw new IllegalStateException(Errors.format(
- Errors.Keys.MissingValueForProperty_1, (sources == null) ? "sources" : "targets"));
+ if (targets == null) {
+ throw new FactoryException(noData());
}
- final int sourceDim = sources.length;
+ final int sourceDim = (sources != null) ? sources.length : gridSize.length;
final int targetDim = targets.length;
correlation = new double[targetDim];
- final MatrixSIS matrix = Matrices.createZero(targetDim + 1, sourceDim + 1);
+ final MatrixSIS matrix = Matrices.create(targetDim + 1, sourceDim + 1, ExtendedPrecisionMatrix.ZERO);
matrix.setElement(targetDim, sourceDim, 1);
- switch (sourceDim) {
- case 1: {
- final Line line = new Line();
- for (int j=0; j < targets.length; j++) {
- correlation[j] = line.fit(sources[0], targets[j]);
- matrix.setElement(j, 0, line.slope());
- matrix.setElement(j, 1, line.y0());
+ for (int j=0; j < targetDim; j++) {
+ final double c;
+ switch (sourceDim) {
+ case 1: {
+ final int row = j;
+ final Line line = new Line() {
+ @Override public void setEquation(final Number slope, final Number y0) {
+ super.setEquation(slope, y0);
+ matrix.setNumber(row, 0, slope); // Preserve the extended precision (double-double).
+ matrix.setNumber(row, 1, y0);
+ }
+ };
+ if (sources != null) {
+ c = line.fit(vector(sources[0]), vector(targets[j]));
+ } else {
+ c = line.fit(Vector.createSequence(0, 1, gridSize[0]),
+ Vector.create(targets[j], false));
+ }
+ break;
}
- break;
- }
- case 2: {
- final Plane plan = new Plane();
- for (int j=0; j < targets.length; j++) {
- correlation[j] = plan.fit(sources[0], sources[1], targets[j]);
- matrix.setElement(j, 0, plan.slopeX());
- matrix.setElement(j, 1, plan.slopeY());
- matrix.setElement(j, 2, plan.z0());
+ case 2: {
+ final int row = j;
+ final Plane plan = new Plane() {
+ @Override public void setEquation(final Number sx, final Number sy, final Number z0) {
+ super.setEquation(sx, sy, z0);
+ matrix.setNumber(row, 0, sx); // Preserve the extended precision (double-double).
+ matrix.setNumber(row, 1, sy);
+ matrix.setNumber(row, 2, z0);
+ }
+ };
+ if (sources != null) {
+ c = plan.fit(vector(sources[0]), vector(sources[1]), vector(targets[j]));
+ } else try {
+ c = plan.fit(gridSize[0], gridSize[1], Vector.create(targets[j], false));
+ } catch (IllegalArgumentException e) {
+ // This may happen if the z vector still contain some "NaN" values.
+ throw new FactoryException(noData(), e);
+ }
+ break;
+ }
+ default: {
+ throw new FactoryException(Errors.format(Errors.Keys.ExcessiveNumberOfDimensions_1, sourceDim));
}
- break;
}
- default: throw new AssertionError(sourceDim); // Should have been verified by setSourcePoints(\u2026) method.
+ correlation[j] = c;
}
- transform = MathTransforms.linear(matrix);
+ transform = (LinearTransform) nonNull(factory).createAffineTransform(matrix);
}
return transform;
}
/**
+ * Wraps the given array in a vector of length {@link #numPoints}. This method should be
+ * invoked only when this builder has been created by {@link #LinearTransformBuilder()}.
+ * This can be identified by {@code sources != null} or {@code gridSize == null}.
+ */
+ private Vector vector(final double[] data) {
+ assert gridSize == null;
+ return Vector.create(data, false).subList(0, numPoints);
+ }
+
+ /**
* Returns the correlation coefficients of the last transform created by {@link #create()},
* or {@code null} if none. If non-null, the array length is equals to the number of target
* dimensions.
@@ -227,13 +758,9 @@ public class LinearTransformBuilder {
buffer.append(':').append(lineSeparator);
final TableAppender table = new TableAppender(buffer, " ");
table.setMultiLinesCells(true);
- table.append(Matrices.toString(transform.getMatrix()));
- table.nextColumn();
- table.append(lineSeparator);
- table.append(" ");
- table.append(Vocabulary.format(Vocabulary.Keys.Correlation));
- table.append(" =");
- table.nextColumn();
+ table.append(Matrices.toString(transform.getMatrix())).nextColumn();
+ table.append(lineSeparator).append(" ")
+ .append(Vocabulary.format(Vocabulary.Keys.Correlation)).append(" =").nextColumn();
table.append(Matrices.create(correlation.length, 1, correlation).toString());
try {
table.flush();
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/builder/package-info.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -31,7 +31,7 @@
*
* @author Martin Desruisseaux (Geomatys)
* @version 0.5
- * @since 0.5
+ * @since 0.8
* @module
*/
package org.apache.sis.referencing.operation.builder;
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/Matrices.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -68,7 +68,7 @@ import org.apache.sis.internal.referenci
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.4
- * @version 0.7
+ * @version 0.8
* @module
*
* @see org.apache.sis.parameter.TensorParameters
@@ -203,8 +203,12 @@ public final class Matrices extends Stat
*/
public static MatrixSIS create(final int numRow, final int numCol, final Number[] elements) {
ArgumentChecks.ensureNonNull("elements", elements);
- if (elements == ExtendedPrecisionMatrix.IDENTITY) { // Intentionally undocumented features.
- return GeneralMatrix.createExtendedPrecision(numRow, numCol, true);
+ /*
+ * Below is an intantionally undocumented feature. We use those sentinel values as a way to create
+ * matrices with extended precision without exposing our double-double arithmetic in public API.
+ */
+ if (elements == ExtendedPrecisionMatrix.IDENTITY || elements == ExtendedPrecisionMatrix.ZERO) {
+ return GeneralMatrix.createExtendedPrecision(numRow, numCol, elements == ExtendedPrecisionMatrix.IDENTITY);
}
final GeneralMatrix matrix = GeneralMatrix.createExtendedPrecision(numRow, numCol, false);
if (matrix.setElements(elements)) {
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/MatrixSIS.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -56,7 +56,7 @@ import org.apache.sis.util.resources.Err
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.4
- * @version 0.7
+ * @version 0.8
* @module
*
* @see Matrices
@@ -556,6 +556,46 @@ public abstract class MatrixSIS implemen
}
/**
+ * Returns a new vector which is the result of multiplying this matrix with the specified vector.
+ * In other words, returns {@code this} � {@code vector}. The length of the given vector must be
+ * equal to the number of columns in this matrix, and the length of the returned vector will be
+ * equal to the number of rows in this matrix.
+ *
+ * <div class="section">Relationship with coordinate operations</div>
+ * In the context of coordinate operations, {@code Matrix.multiply(vector)} is related to
+ * <code>{@linkplain AffineTransform#transform(double[], int, double[], int, int) AffineTransform.transform}(\u2026)</code>
+ * except that the last {@code vector} number is implicitly 1 in {@code AffineTransform} operations.
+ * While this {@code multiply(double[])} method could be used for coordinate transformation, it is not its purpose.
+ * This method is designed for occasional uses when accuracy is more important than performance.
+ *
+ * @param vector the vector to multiply to this matrix.
+ * @return the result of {@code this} � {@code vector}.
+ * @throws MismatchedMatrixSizeException if the length of the given vector is not equals to the
+ * number of columns in this matrix.
+ *
+ * @since 0.8
+ */
+ public double[] multiply(final double[] vector) {
+ final int numCol = getNumCol();
+ if (vector.length != numCol) {
+ throw new MismatchedMatrixSizeException(Errors.format(Errors.Keys.UnexpectedArrayLength_2, numCol, vector.length));
+ }
+ final double[] target = new double[getNumRow()];
+ final DoubleDouble ele = new DoubleDouble();
+ final DoubleDouble sum = new DoubleDouble();
+ for (int j=0; j<target.length; j++) {
+ for (int i=0; i<numCol; i++) {
+ get(j, i, ele);
+ ele.multiply(vector[i]);
+ sum.add(ele);
+ }
+ target[j] = sum.value;
+ sum.clear();
+ }
+ return target;
+ }
+
+ /**
* Returns the value of <var>U</var> which solves {@code this} � <var>U</var> = {@code matrix}.
* This is equivalent to first computing the inverse of {@code this}, then multiplying the result
* by the given matrix.
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/package-info.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/package-info.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/package-info.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/matrix/package-info.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -70,7 +70,7 @@
*
* @author Martin Desruisseaux (IRD, Geomatys)
* @since 0.4
- * @version 0.6
+ * @version 0.8
* @module
*/
package org.apache.sis.referencing.operation.matrix;
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/NormalizedProjection.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -720,8 +720,7 @@ public abstract class NormalizedProjecti
/**
* Default constructor.
*/
- public Inverse() {
- NormalizedProjection.this.super();
+ Inverse() {
}
/**
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/projection/TransverseMercator.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -107,7 +107,6 @@ public class TransverseMercator extends
* Work around for RFE #4093999 in Sun's bug database
* ("Relax constraint on placement of this()/super() call in constructors").
*/
- @SuppressWarnings("fallthrough")
@Workaround(library="JDK", version="1.7")
private static Initializer initializer(final OperationMethod method, final Parameters parameters) {
final boolean isSouth = identMatch(method, "(?i).*\\bSouth\\b.*", TransverseMercatorSouth.IDENTIFIER);
@@ -126,11 +125,10 @@ public class TransverseMercator extends
}
/**
- * Work around for RFE #4093999 in Sun's bug database
- * ("Relax constraint on placement of this()/super() call in constructors").
+ * Creates a new Transverse Mercator projection from the given initializer.
+ * This constructor is used also by {@link ZonedGridSystem}.
*/
- @Workaround(library="JDK", version="1.7")
- private TransverseMercator(final Initializer initializer) {
+ TransverseMercator(final Initializer initializer) {
super(initializer);
final double \u03c60 = toRadians(initializer.getAndStore(LATITUDE_OF_ORIGIN));
/*
@@ -185,7 +183,7 @@ public class TransverseMercator extends
*
* Denormalization
* - Scale x and y by B.
- * - Subtract M0 to the northing.
+ * - Subtract M\u2080 to the northing.
* - Multiply by the scale factor (done by the super-class constructor).
* - Add false easting and false northing (done by the super-class constructor).
*/
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform1D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -176,7 +176,6 @@ public abstract class AbstractMathTransf
* Constructs an inverse math transform.
*/
protected Inverse() {
- AbstractMathTransform1D.this.super();
}
/**
Modified: sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java
URL: http://svn.apache.org/viewvc/sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java?rev=1789729&r1=1789728&r2=1789729&view=diff
==============================================================================
--- sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] (original)
+++ sis/branches/JDK9/core/sis-referencing/src/main/java/org/apache/sis/referencing/operation/transform/AbstractMathTransform2D.java [UTF-8] Fri Mar 31 18:49:16 2017
@@ -339,7 +339,6 @@ public abstract class AbstractMathTransf
* Constructs an inverse math transform.
*/
protected Inverse() {
- AbstractMathTransform2D.this.super();
}
/**