Package org.apache.sis.referencing.datum

Source Code of org.apache.sis.referencing.datum.TimeDependentBWP

/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements.  See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License.  You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.sis.referencing.datum;

import java.util.Date;
import java.util.Arrays;
import org.opengis.metadata.extent.Extent;
import org.opengis.referencing.datum.GeodeticDatum;
import org.apache.sis.internal.util.Numerics;
import org.apache.sis.internal.util.DoubleDouble;

import static org.apache.sis.util.ArgumentChecks.*;
import static org.apache.sis.internal.referencing.Formulas.JULIAN_YEAR_LENGTH;


/**
* Parameters for a time-dependent geographic transformation between two datum.
* The {@link #tX tX}, {@link #tY tY}, {@link #tZ tZ}, {@link #rX rX}, {@link #rY rY}, {@link #rZ rZ}
* and {@link #dS dS} parameters inherited from the parent class are values at a point in time given
* by {@link #getTimeReference()}. Those values vary at a rate given by the parameters listed in the
* table below (codes, names and abbreviations are from the EPSG database):
*
* <table class="sis">
*   <tr><th>Code</th> <th>Name</th>                                 <th>Abbr.</th></tr>
*   <tr><td>1040</td> <td>Rate of change of X-axis translation</td> <td>{@link #dtX}</td></tr>
*   <tr><td>1041</td> <td>Rate of change of Y-axis translation</td> <td>{@link #dtY}</td></tr>
*   <tr><td>1042</td> <td>Rate of change of Z-axis translation</td> <td>{@link #dtZ}</td></tr>
*   <tr><td>1043</td> <td>Rate of change of X-axis rotation</td>    <td>{@link #drX}</td></tr>
*   <tr><td>1044</td> <td>Rate of change of Y-axis rotation</td>    <td>{@link #drY}</td></tr>
*   <tr><td>1045</td> <td>Rate of change of Z-axis rotation</td>    <td>{@link #drZ}</td></tr>
*   <tr><td>1046</td> <td>Rate of change of scale difference</td>   <td>{@link #ddS}</td></tr>
* </table>
*
* The numerical fields in this {@code TimeDependentBWP} class uses the EPSG abbreviations
* with 4 additional constraints compared to the EPSG definitions:
*
* <ul>
*   <li>Unit of {@link #ddS} is fixed to <em>parts per million per year</em>.</li>
*   <li>Unit of {@link #dtX}, {@link #dtY} and {@link #dtZ} is fixed to <em>millimetres per year</em>.</li>
*   <li>Unit of {@link #drX}, {@link #drY} and {@link #drZ} is fixed to <em>milli arc-seconds per year</em>.</li>
*   <li>Sign of rotation terms is fixed to the <em>Position Vector</em> convention (EPSG operation method 1053).
*       This is the opposite sign than the <cite>Coordinate Frame Rotation</cite> (EPSG operation method 1056.
*       The Position Vector convention is used by IAG and recommended by ISO 19111.</li>
* </ul>
*
* @author  Martin Desruisseaux (Geomatys)
* @since   0.4
* @version 0.4
* @module
*/
public class TimeDependentBWP extends BursaWolfParameters {
    /**
     * Serial number for inter-operability with different versions.
     */
    private static final long serialVersionUID = -4628799278259080258L;

    /**
     * Rate of change of X-axis translation in millimetres per year (EPSG:1040).
     */
    public double dtX;

    /**
     * Rate of change of Y-axis translation in millimetres per year (EPSG:1041).
     */
    public double dtY;

    /**
     * Rate of change of Z-axis translation in millimetres per year (EPSG:1042).
     */
    public double dtZ;

    /**
     * Rate of change of X-axis rotation in milli arc-seconds per year (EPSG:1043),
     * sign following the <cite>Position Vector</cite> convention.
     */
    public double drX;

    /**
     * Rate of change of Y-axis rotation in milli arc-seconds per year (EPSG:1044),
     * sign following the <cite>Position Vector</cite> convention.
     */
    public double drY;

    /**
     * Rate of change of Z-axis rotation in milli arc-seconds per year (EPSG:1045),
     * sign following the <cite>Position Vector</cite> convention.
     */
    public double drZ;

    /**
     * Rate of change of the scale difference in parts per million per year (EPSG:1046).
     */
    public double ddS;

    /**
     * The reference epoch for time-dependent parameters (EPSG:1047).
     */
    private final long timeReference;

    /**
     * Creates a new instance for the given target datum, domain of validity and time reference.
     * All numerical parameters are initialized to 0, which correspond to an identity transform.
     * Callers can assign numerical values to the public fields of interest after construction.
     *
     * @param targetDatum The target datum (usually WGS 84) for this set of parameters.
     * @param domainOfValidity Area or region in which a coordinate transformation based on those Bursa-Wolf parameters
     *        is valid, or {@code null} is unspecified.
     * @param timeReference The reference epoch for time-dependent parameters.
     */
    public TimeDependentBWP(final GeodeticDatum targetDatum, final Extent domainOfValidity, final Date timeReference) {
        super(targetDatum, domainOfValidity);
        ensureNonNull("timeReference", timeReference);
        this.timeReference = timeReference.getTime();
    }

    /**
     * Verifies parameters validity after initialization.
     */
    @Override
    void verify() {
        super.verify();
        ensureFinite("dtX", dtX);
        ensureFinite("dtY", dtY);
        ensureFinite("dtZ", dtZ);
        ensureFinite("drX", drX);
        ensureFinite("drY", drY);
        ensureFinite("drZ", drZ);
    }

    /**
     * Returns the reference epoch for time-dependent parameters.
     *
     * @return The reference epoch for time-dependent parameters.
     */
    public Date getTimeReference() {
        return new Date(timeReference);
    }

    /**
     * Returns the elapsed time from the {@linkplain TimeDependentBWP#getTimeReference() reference time}
     * to the given date in millennium, or {@code null} if none.
     */
    @Override
    final DoubleDouble period(final Date time) {
        if (time != null) {
            final long millis = time.getTime() - timeReference;
            if (millis != 0) { // Returns null for 0 as an optimization.
                final DoubleDouble period = new DoubleDouble(millis, 0);
                period.divide(1000 * JULIAN_YEAR_LENGTH, 0);
                return period;
            }
        }
        return null;
    }

    /**
     * Returns the parameter at the given index. If this {@code BursaWolfParameters} is time-dependent,
     * then the returned value shall be corrected for the given period.
     *
     * @param index  0 for {@code tX}, 1 for {@code tY}, <i>etc.</i> in {@code TOWGS84[…]} order.
     * @param period The value computed by {@link #period(Date)}, or {@code null}.
     */
    @Override
    final DoubleDouble param(final int index, final DoubleDouble period) {
        final DoubleDouble p = super.param(index, period);
        if (period != null) {
            final double value = period.value;
            final double error = period.error;
            final double d;
            switch (index) {
                case 0: d = dtX; break;
                case 1: d = dtY; break;
                case 2: d = dtZ; break;
                case 3: d = drX; break;
                case 4: d = drY; break;
                case 5: d = drZ; break;
                case 6: d = ddS; period.multiply(1000, 0); break;
                default: throw new AssertionError(index);
            }
            period.multiply(d);
            p.add(period);
            period.value = value;
            period.error = error;
        }
        return p;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isIdentity() {
        return super.isIdentity() && dtX == 0 && dtY == 0 && dtZ == 0;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean isTranslation() {
        return super.isTranslation() && drX == 0 && drY == 0 && drZ == 0;
    }

    /**
     * Inverts in-place the sign of rotation terms and their derivative.
     * This method can be invoked for converting a <cite>Coordinate Frame Rotation</cite> transformation
     * (EPSG operation method 9607) to a <em>Position Vector</em> transformation (EPSG operation method 9606).
     * The later convention is used by IAG and recommended by ISO 19111.
     */
    @Override
    public void reverseRotation() {
        super.reverseRotation();
        drX = -drX;
        drY = -drY;
        drZ = -drZ;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public void invert() {
        super.invert();
        dtX = -dtX;
        dtY = -dtY;
        dtZ = -dtZ;
        drX = -drX;
        drY = -drY;
        drZ = -drZ;
        ddS = -ddS;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public boolean equals(final Object object) {
        if (super.equals(object)) {
            final TimeDependentBWP that = (TimeDependentBWP) object;
            return timeReference == that.timeReference &&
                   Numerics.equals(this.dtX, that.dtX) &&
                   Numerics.equals(this.dtY, that.dtY) &&
                   Numerics.equals(this.dtZ, that.dtZ) &&
                   Numerics.equals(this.drX, that.drX) &&
                   Numerics.equals(this.drY, that.drY) &&
                   Numerics.equals(this.drZ, that.drZ) &&
                   Numerics.equals(this.ddS, that.ddS);
        }
        return false;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public int hashCode() {
        return ((int) serialVersionUID) ^ Arrays.hashCode(new double[] {
            tX, tY, tZ, rX, rY, rZ, dS, dtX, dtY, dtZ, drX, drY, drZ, ddS, timeReference
        });
    }
}
TOP

Related Classes of org.apache.sis.referencing.datum.TimeDependentBWP

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.