//
// CoordinateSystem.java
//

/*
VisAD system for interactive analysis and visualization of numerical
data.  Copyright (C) 1996 - 2017 Bill Hibbard, Curtis Rueden, Tom
Rink, Dave Glowacki, Steve Emmerson, Tom Whittaker, Don Murray, and
Tommy Jasmin.

This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Library General Public License for more details.

You should have received a copy of the GNU Library General Public
License along with this library; if not, write to the Free
Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
MA 02111-1307, USA
*/

package visad;

/**
   CoordinateSystem is the VisAD abstract superclass for coordinate systems for
   vectors in R^n for n>0.  Specific coordinate systems are defined by
   extending this class and providing coordinate transformation logic in
   the toReference and fromReference methods.

CoordinateSystem objects should be immutable.

*/ public abstract class CoordinateSystem extends Object implements java.io.Serializable { /** reference coordinate system (e.g., (Latitude, Longitude, Radius) ) */ private final RealTupleType Reference; private final int DomainDimension; /** not required to be convertable with Reference.DefaultUnits */ private final Unit[] CoordinateSystemUnits; /** * Constructs from the type of the reference coordinate system and units for * values in this coordinate system. Subclasses must supply reference type * and units. * @param reference The type of the reference coordinate * system. Numeric values in the reference * coordinate system shall be in units of * reference.getDefaultUnits() * unless specified otherwise. * @param units The default units for this coordinate system. * Numeric values in this coordinate system shall * be in units of units unless * specified otherwise. May be null * or an array of nulls. * @throws VisADException Couldn't create necessary VisAD object. */ public CoordinateSystem(RealTupleType reference, Unit[] units) throws VisADException { if (reference == null) { throw new CoordinateSystemException( "CoordinateSystem: Reference may not be null"); } if (reference.getCoordinateSystem() != null) { throw new CoordinateSystemException( "CoordinateSystem: Reference may not have a DefaultCoordinateSystem"); } Reference = reference; DomainDimension = Reference.getDimension(); if (units != null && DomainDimension != units.length) { throw new UnitException("CoordinateSystem: units dimension does not match"); } CoordinateSystemUnits = new Unit[DomainDimension]; if (units != null) { for (int i=0; ireference.getDefaultUnits() * unless specified otherwise. * @param units The default units for this coordinate system. * Numeric values in this coordinate system shall * be in units of units unless * specified otherwise. May be null * or an array of nulls. * @param b dummy argument for trusted constructor signature */ CoordinateSystem(RealTupleType reference, Unit[] units, boolean b) { Reference = reference; DomainDimension = Reference.getDimension(); CoordinateSystemUnits = new Unit[DomainDimension]; if (units != null) { for (int i=0; i * null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * * @return true if conversion is possible. */ public static boolean canConvert(RealTupleType out, CoordinateSystem coord_out, RealTupleType in, CoordinateSystem coord_in) { if (out == null) return (in == null); if (out.equals(in)) return true; RealTupleType ref_out = out; if (coord_out != null) ref_out = coord_out.getReference(); RealTupleType ref_in = in; if (coord_in != null) ref_in = coord_in.getReference(); return ref_out.equals(ref_in); } /** *

Transforms double-valued coordinates between two {@link RealTupleType}s. * Unit conversion is always performed even if no coordinate transformation * is done.

* *

This implementation uses {@link #transformCoordinatesFreeUnits} to do * most of the transformation.

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. The values might * be modified upon return from this method. * @return The transformed coordinate values not in the input * array. * @throws VisADException if a VisAD failure occurs. * @throws NullPointerException if units_out is * null. */ public static double[][] transformCoordinates( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, double[][] value) throws VisADException { return transformCoordinates(out, coord_out, units_out, errors_out, in, coord_in, units_in, errors_in, value, true); } /** *

Transforms double-valued coordinates between two {@link RealTupleType}s. * Unit conversion is always performed even if no coordinate transformation * is done.

* *

This implementation uses {@link #transformCoordinatesFreeUnits} to do * most of the transformation.

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. The values might * be modified upon return from this method. * @param copy if false, the underlying value array * transformations may be done in place. * @return The transformed coordinate values not in the input * array, if copy is true. * @throws VisADException if a VisAD failure occurs. * @throws NullPointerException if units_out is * null. */ public static double[][] transformCoordinates( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, double[][] value, boolean copy) throws VisADException { int n = out.getDimension(); Unit[] units_free = new Unit[n]; double[][] old_value = value; value = transformCoordinatesFreeUnits(out, coord_out, units_free, errors_out, in, coord_in, units_in, errors_in, value); // WLH 21 Nov 2001 if (value == old_value) { value = new double[n][]; for (int i=0; iTransforms double-valued coordinates between two {@link RealTupleType}s. * This is just like {@link #transformCoordinates}, except that final Unit * conversion to units_out is not done; rather, * units_out[i] is set to the final {@link Unit} of * value[i].

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units or null. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. * @return The transformed coordinate values. Possibly * in the input array. * @throws VisADException if a VisAD failure occurs. */ public static double[][] transformCoordinatesFreeUnits( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, double[][] value) throws VisADException { int n = in.getDimension(); // prepare for error calculations, if any double[][] error_values = new double[1][1]; boolean any_transform = false; boolean any_errors = false; if (errors_in != null && errors_out != null) { any_errors = true; for (int i=0; iTransforms float-valued coordinates between two {@link RealTupleType}s. * Unit conversion is always performed even if no coordinate transformation * is done.

* *

This implementation uses {@link #transformCoordinatesFreeUnits} to do * most of the transformation.

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. The values might * be modified upon return from this method. * @return The transformed coordinate values not in the input * array. * @throws VisADException if a VisAD failure occurs. * @throws NullPointerException if units_out is * null. */ public static float[][] transformCoordinates( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, float[][] value) throws VisADException { return transformCoordinates(out, coord_out, units_out, errors_out, in, coord_in, units_in, errors_in, value, true); } /** *

Transforms float-valued coordinates between two {@link RealTupleType}s. * Unit conversion is always performed even if no coordinate transformation * is done.

* *

This implementation uses {@link #transformCoordinatesFreeUnits} to do * most of the transformation.

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. The values might * be modified upon return from this method. * @param copy if false, the underlying value array * transformations may be done in place. * @return The transformed coordinate values not in the input * array, if copy is true. * @throws VisADException if a VisAD failure occurs. * @throws NullPointerException if units_out is * null. */ public static float[][] transformCoordinates( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, float[][] value, boolean copy) throws VisADException { int n = out.getDimension(); Unit[] units_free = new Unit[n]; float[][] old_value = value; value = transformCoordinatesFreeUnits(out, coord_out, units_free, errors_out, in, coord_in, units_in, errors_in, value); // WLH 21 Nov 2001 if (value == old_value) { value = new float[n][]; for (int i=0; iTransforms float-valued coordinates between two {@link RealTupleType}s. * This is just like {@link #transformCoordinates}, except that final Unit * conversion to units_out is not done; rather, * units_out[i] is set to the final {@link Unit} of * value[i].

* *

If both {@link RealTupleType}s have a reference coordinate system, then * this implementation always transforms the input domain values by * first transforming them according to the input reference coordinate system * and then inverse transforming them according to the output reference * coordinate system -- even if the input and output {@link RealTupleType}s * are equal.

* * @param out The output {@link RealTupleType}. * @param coord_out The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_out The output units or null. * @param errors_out The output error estimates or null. * @param in The input {@link RealTupleType}. * @param coord_in The coordinate system transformation associated * with the output {@link RealTupleType} or * null. * @param units_in The input units or null. * @param errors_in The input error estimates or null. * @param value The input coordinate values. value[i][j] * is the j-th sample of the * i-th component. * @return The transformed coordinate values. Possibly * in the input array. * @throws VisADException if a VisAD failure occurs. */ public static float[][] transformCoordinatesFreeUnits( RealTupleType out, CoordinateSystem coord_out, Unit[] units_out, ErrorEstimate[] errors_out, RealTupleType in, CoordinateSystem coord_in, Unit[] units_in, ErrorEstimate[] errors_in, float[][] value) throws VisADException { int n = in.getDimension(); // prepare for error calculations, if any double[][] error_values = new double[1][1]; boolean any_transform = false; boolean any_errors = false; if (errors_in != null && errors_out != null) { any_errors = true; for (int i=0; itrue if and only if this instance equals cs. */ public abstract boolean equals(Object cs); }

Ads help maintain this website.