Package org.geotools.referencing.piecewise

Source Code of org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement

/*
*    GeoTools - The Open Source Java GIS Toolkit
*    http://geotools.org
*
*    (C) 2005-2008, Open Source Geospatial Foundation (OSGeo)
*
*    This library is free software; you can redistribute it and/or
*    modify it under the terms of the GNU Lesser General Public
*    License as published by the Free Software Foundation;
*    version 2.1 of the License.
*
*    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
*    Lesser General Public License for more details.
*/
package org.geotools.referencing.piecewise;

import java.util.logging.Level;
import java.util.logging.Logger;

import org.geotools.referencing.operation.transform.LinearTransform1D;
import org.geotools.renderer.i18n.ErrorKeys;
import org.geotools.renderer.i18n.Errors;
import org.geotools.util.NumberRange;
import org.geotools.util.Utilities;
import org.geotools.util.logging.Logging;
import org.opengis.referencing.operation.MathTransform1D;
import org.opengis.referencing.operation.NoninvertibleTransformException;

/**
* Convenience class for linear transformations that maps an interval to another interval.
* @author  Simone Giannecchini, GeoSolutions
*
*
*
* @source $URL$
*/
public class DefaultLinearPiecewiseTransform1DElement extends DefaultPiecewiseTransform1DElement implements
    PiecewiseTransform1DElement {

  /**
   *
   */
  private static final long serialVersionUID = 4026834241134908025L;

  private final static Logger LOGGER = Logging
      .getLogger("org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement");

  /**
     * @uml.property  name="outputMaximum"
     */
  private double outputMaximum;
  /**
     * @uml.property  name="outputMinimum"
     */
  private double outputMinimum;
  /**
     * @uml.property  name="outputRange"
     */
  private NumberRange<? extends Number> outputRange;
  /**
     * @uml.property  name="outputMinimumNaN"
     */
  private boolean outputMinimumNaN;
  /**
     * @uml.property  name="outputMaximumNaN"
     */
  private boolean outputMaximumNaN;
  /**
     * @uml.property  name="outputMinimumInfinite"
     */
  private boolean outputMinimumInfinite;
  /**
     * @uml.property  name="outputMaximumInfinite"
     */
  private boolean outputMaximumInfinite;



  /**
   * Constructor.
   *
   * @param name
   *            for this {@link DefaultLinearPiecewiseTransform1DElement}.
   * @param inRange
   *            for this {@link DefaultLinearPiecewiseTransform1DElement}.
   * @param outRange
   *            for this {@link DefaultLinearPiecewiseTransform1DElement}.
   */
  public DefaultLinearPiecewiseTransform1DElement(CharSequence name, NumberRange<? extends Number> inRange,
      NumberRange<? extends Number> outRange) {
    super(name, inRange);
    this.outputRange = outRange;
    // /////////////////////////////////////////////////////////////////////
    //
    // Checks
    //
    // /////////////////////////////////////////////////////////////////////
    // //
    //
    // the output class can only be integer
    //
    // //
    final Class<? extends Number> type = outRange.getElementClass();
    boolean minInc = outRange.isMinIncluded();
    boolean maxInc = outRange.isMaxIncluded();
    outputMinimum = PiecewiseUtilities.doubleValue(type, outRange
        .getMinValue(), minInc ? 0 : +1);
    outputMaximum = PiecewiseUtilities.doubleValue(type, outRange
        .getMaxValue(), maxInc ? 0 : -1);
    outputMinimumNaN = Double.isNaN(outputMinimum);
    outputMaximumNaN = Double.isNaN(outputMaximum);
    outputMinimumInfinite = Double.isInfinite(outputMinimum);
    outputMaximumInfinite = Double.isInfinite(outputMaximum);

    // //
    //
    // No open intervals for the output range
    //
    // //
    if (outputMinimumInfinite || outputMinimumInfinite) {
      throw new IllegalArgumentException(Errors.format(
          ErrorKeys.BAD_RANGE_$2, outputRange.getMinValue(),
          outputRange.getMaxValue()));
    }

    final int compareOutBounds = PiecewiseUtilities.compare(outputMinimum,
        outputMaximum);
    // //
    //
    // the output values are correctly ordered
    //
    // //
    if (compareOutBounds > 0) {
      throw new IllegalArgumentException(Errors.format(
          ErrorKeys.BAD_RANGE_$2, outputRange.getMinValue(),
          outputRange.getMaxValue()));
    }

    // //
    //
    // mapping NaN to a single value
    //
    // //
    if (isInputMaximumNaN() && isInputMinimumNaN())
      if (compareOutBounds == 0) {
        setTransform(LinearTransform1D.create(0, outputMinimum));
        setInverse(LinearTransform1D.create(outputMinimum, 0));
        return;
      } else
        throw new IllegalArgumentException(Errors.format(
            ErrorKeys.BAD_RANGE_$2, outputRange.getMinValue(),
            outputRange.getMaxValue()));

    // //
    //
    // Mapping an open interval to a single value, there is no way to map an
    // open interval to another interval!
    //
    // //
    if (isInputMaximumInfinite() || isInputMinimumInfinite())
      if (compareOutBounds == 0) {
        setTransform(PiecewiseUtilities.createLinearTransform1D(0,
            outputMinimum));
        setInverse(null);
        return;
      } else
        throw new IllegalArgumentException(Errors.format(
            ErrorKeys.BAD_RANGE_$2, outputRange.getMinValue(),
            outputRange.getMaxValue()));

    final MathTransform1D transform = PiecewiseUtilities.createLinearTransform1D(inRange,
        NumberRange.create(outputMinimum, outputMaximum));
    setTransform(transform);

    // //
    //
    // Checking the created transformation
    //
    // //
    assert transform instanceof LinearTransform1D;
    assert !Double.isNaN(((LinearTransform1D) transform).scale)
        && !Double
            .isInfinite(((LinearTransform1D) transform).scale);

    // //
    //
    // Inverse
    //
    // //
    LinearTransform1D tempTransform = (LinearTransform1D) transform;
    final double scale = tempTransform.scale;
    if (Math.abs(scale) < 1E-6)
      if (PiecewiseUtilities.compare(getInputMaximum(), getInputMinimum()) == 0)
        setInverse(LinearTransform1D.create(0, getInputMinimum()));
      else
        setInverse(null);
    else
      try {
        setInverse((MathTransform1D) transform.inverse());
      } catch (NoninvertibleTransformException e) {
        if (LOGGER.isLoggable(Level.WARNING))
          LOGGER.log(Level.WARNING, e.getLocalizedMessage(), e);
      }
  }

  /**
     * Returns the maximum output values for this  {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @return  the maximum output values for this  {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @uml.property  name="outputMaximum"
     */
  public double getOutputMaximum() {
    return outputMaximum;
  }

  /**
     * Returns the minimum output values for this  {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @return  the minimum output values for this  {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @uml.property  name="outputMinimum"
     */
  public double getOutputMinimum() {
    return outputMinimum;
  }

  /**
     * Returns the range for the output values for this {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @return  the range for the output values for this {@link DefaultLinearPiecewiseTransform1DElement}  ;
     * @uml.property  name="outputRange"
     */
  public NumberRange<? extends Number> getOutputRange() {
    return outputRange;
  }

  /**
     * Tells me if the lower boundary of the output range is NaN
     * @return  <code>true</code> if the lower boundary of the output range is  NaN, <code>false</code> otherwise.
     * @uml.property  name="outputMinimumNaN"
     */
  public boolean isOutputMinimumNaN() {
    return outputMinimumNaN;
  }

  /**
     * Tells me if the upper boundary of the output range is NaN
     * @return  <code>true</code> if the upper boundary of the output range is  NaN, <code>false</code> otherwise.
     * @uml.property  name="outputMaximumNaN"
     */
  public boolean isOutputMaximumNaN() {
    return outputMaximumNaN;
  }

  /**
     * Tells me if the lower boundary of the output range is infinite
     * @return  <code>true</code> if the lower boundary of the output range is  infinite, <code>false</code> otherwise.
     * @uml.property  name="outputMinimumInfinite"
     */
  public boolean isOutputMinimumInfinite() {
    return outputMinimumInfinite;
  }

  /**
     * Tells me if the upper boundary of the output range is infinite
     * @return  <code>true</code> if the upper boundary of the output range is  infinite, <code>false</code> otherwise.
     * @uml.property  name="outputMaximumInfinite"
     */
  public boolean isOutputMaximumInfinite() {
    return outputMaximumInfinite;
  }
 
  /**
   * Retrieves the scale factor for this linear {@link PiecewiseTransform1DElement}.
   *
   * @return the scale factor for this linear {@link PiecewiseTransform1DElement}.
   */
  public double getScale(){
    //get the transform at this point it is linear for sure
    final LinearTransform1D transform= (LinearTransform1D) getTransform();
    return transform.scale;
   
  }
 
  /**
   * Retrieves the offset factor for this linear {@link PiecewiseTransform1DElement}.
   *
   * @return the offset factor for this linear {@link PiecewiseTransform1DElement}.
   */
  public double getOffset(){
    //get the transform at this point it is linear for sure
    final LinearTransform1D transform= (LinearTransform1D) getTransform();
    return transform.offset;
   
  }
 
  /*
   * (non-Javadoc)
   * @see org.geotools.referencing.piecewise.DefaultPiecewiseTransform1DElement#toString()
   */
  public String toString() {
    final StringBuilder buffer= new StringBuilder(super.toString());
    buffer.append("\n").append("output range=").append(this.outputRange);
    return buffer.toString();
  }

    protected Class<?> getEquivalenceClass(){
        return DefaultLinearPiecewiseTransform1DElement.class;
    }

    @Override
    public boolean equals(Object obj) {
        if(this==obj)
            return true;
        if(!(obj instanceof DefaultLinearPiecewiseTransform1DElement))
            return false;
        final DefaultLinearPiecewiseTransform1DElement that= (DefaultLinearPiecewiseTransform1DElement) obj;
        if(that.getEquivalenceClass()!=this.getEquivalenceClass())
            return false;
        if(!Utilities.equals(outputRange, that.outputRange))
            return false;
        if(!Utilities.equals(outputMaximum, that.outputMaximum))
            return false;
        if(!Utilities.equals(outputMinimum, that.outputMinimum))
            return false;
        return super.equals(obj);
    }

    @Override
    public int hashCode() {
        int hashCode=37;
        hashCode=Utilities.hash(outputRange,hashCode);
        hashCode=Utilities.hash( outputMaximum,hashCode);
        hashCode=Utilities.hash( outputMinimum,hashCode);
        hashCode=Utilities.hash( super.hashCode(),hashCode);
        return hashCode;
    }
}
TOP

Related Classes of org.geotools.referencing.piecewise.DefaultLinearPiecewiseTransform1DElement

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.