/* JAI-Ext - OpenSource Java Advanced Image Extensions Library * http://www.geo-solutions.it/ * Copyright 2014 GeoSolutions * Licensed 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 it.geosolutions.jaiext.piecewise; import it.geosolutions.jaiext.range.Range; import it.geosolutions.jaiext.range.RangeFactory; /** * Convenience implementation of the {@link DefaultPiecewiseTransform1DElement} . * * @author Simone Giannecchini, GeoSolutions * * @source $URL$ */ public class DefaultPiecewiseTransform1DElement extends DefaultDomainElement1D implements PiecewiseTransform1DElement { /** * UID */ private static final long serialVersionUID = 7422178060824402864L; /** * The math transform * * @uml.property name="transform" */ private MathTransformation transform; /** * Inverse {@link MathTransformation} */ private MathTransformation inverse; private int hashCode = -1; /** * Builds up a {@link DefaultPiecewiseTransform1DElement} which maps a range to a constant value. * * @param name for this {@link DomainElement1D} * @param inRange for this {@link DomainElement1D} * @param outVal for this {@link DefaultLinearPiecewiseTransform1DElement} * @throws IllegalArgumentException in case the input values are illegal. */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name, final Range inRange, final double value) { return new DefaultConstantPiecewiseTransformElement(name, inRange, value); } /** * Builds up a DefaultPiecewiseTransform1DElement which maps a range to a constant value. * * @param name for this {@link DomainElement1D} * @param inRange for this {@link DomainElement1D} * @param outVal for this {@link DefaultLinearPiecewiseTransform1DElement} * @throws IllegalArgumentException in case the input values are illegal. */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name, final Range inRange, final byte value) { return new DefaultConstantPiecewiseTransformElement(name, inRange, value); } /** * Builds up a DefaultPiecewiseTransform1DElement which maps a range to a constant value. * * @param name for this {@link DomainElement1D} * @param inRange for this {@link DomainElement1D} * @param outVal for this {@link DefaultLinearPiecewiseTransform1DElement} * @throws IllegalArgumentException in case the input values are illegal. */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name, final Range inRange, final int value) { return new DefaultConstantPiecewiseTransformElement(name, inRange, value); } /** * Constructor. * * @param name for this {@link DefaultLinearPiecewiseTransform1DElement}. * @param inRange for this {@link DefaultLinearPiecewiseTransform1DElement}. * @param outRange for this {@link DefaultLinearPiecewiseTransform1DElement}. */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name, final Range inRange, final Range outRange) { return new DefaultLinearPiecewiseTransform1DElement(name, inRange, outRange); } /** * Creates a pass-through DefaultPiecewiseTransform1DElement. * * @param name for this {@link DomainElement1D}. * @throws IllegalArgumentException */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name) throws IllegalArgumentException { return new DefaultPassthroughPiecewiseTransform1DElement(name, RangeFactory.create( Double.NEGATIVE_INFINITY, true, Double.POSITIVE_INFINITY, true, true)); } /** * Creates a pass-through DefaultPiecewiseTransform1DElement. * * @param name for this {@link DomainElement1D}. * @param valueRange for this {@link DomainElement1D}. * @throws IllegalArgumentException */ public static DefaultPiecewiseTransform1DElement create(final CharSequence name, final Range valueRange) throws IllegalArgumentException { return new DefaultPassthroughPiecewiseTransform1DElement(name, valueRange); } /** * Protected constructor for {@link DomainElement1D}s that want to build their transform later on. * * @param name for this {@link DomainElement1D}. * @param valueRange for this {@link DomainElement1D}. * @throws IllegalArgumentException */ public DefaultPiecewiseTransform1DElement(CharSequence name, Range valueRange) throws IllegalArgumentException { super(name, valueRange); } /** * Public constructor for building a {@link DomainElement1D} which applies the specified transformation on the values that fall into its * definition range. * * @param name for this {@link DomainElement1D}. * @param valueRange for this {@link DomainElement1D}. * @param transform for this {@link DomainElement1D}. * @throws IllegalArgumentException */ public DefaultPiecewiseTransform1DElement(CharSequence name, Range valueRange, final MathTransformation transform) throws IllegalArgumentException { super(name, valueRange); // ///////////////////////////////////////////////////////////////////// // // Initial checks // // ///////////////////////////////////////////////////////////////////// PiecewiseUtilities.ensureNonNull("transform", transform); this.transform = transform; } /** * Getter for the underlying {@link MathTransformation} . * * @return the underlying {@link MathTransformation} . * @uml.property name="transform" */ protected synchronized MathTransformation getTransform() { return transform; } /** * Transforms the specified value. * * @param value The value to transform. * @return the transformed value. * @throws TransformationException if the value can't be transformed. */ public synchronized double transform(double value) throws TransformationException { if (transform == null) throw new IllegalStateException(); if (contains(value)) return transform.transform(value); throw new IllegalArgumentException("Provided value is not contained in this domain"); } /** * Transforms the specified {@code ptSrc} and stores the result in {@code ptDst}. */ public Position transform(final Position ptSrc, Position ptDst) throws TransformationException { if (ptDst == null) { ptDst = new Position(); } ptDst.setOrdinatePosition(transform(ptSrc.getOrdinatePosition())); return ptDst; } /** * Returns the input transformation dimensions */ public int getSourceDimensions() { return transform.getSourceDimensions(); } /** * Returns the output transformation dimensions */ public int getTargetDimensions() { return transform.getTargetDimensions(); } /** * Returns the inverse of this {@link MathTransformation} instance */ public synchronized MathTransformation inverse() throws NoninvertibleTransformException { if (inverse != null) return inverse; if (transform == null) throw new IllegalStateException(); inverse = (MathTransformation) transform.inverseTransform(); return inverse; } /** * Defines if the transformation is an identity */ public boolean isIdentity() { return transform.isIdentity(); } /** * @param mathTransform * @uml.property name="inverse" */ protected synchronized void setInverse(MathTransformation mathTransform) { if (this.inverse == null) this.inverse = mathTransform; else throw new IllegalStateException(); } /** * @param transform * @uml.property name="transform" */ protected synchronized void setTransform(MathTransformation transform) { PiecewiseUtilities.ensureNonNull("transform", transform); if (this.transform == null) this.transform = transform; else throw new IllegalStateException(); } public boolean equals(Object obj) { if (obj == this) return true; if (!(obj instanceof DefaultPiecewiseTransform1DElement)) return false; final DefaultPiecewiseTransform1DElement that = (DefaultPiecewiseTransform1DElement) obj; if (getEquivalenceClass() != (that.getEquivalenceClass())) return false; if (!PiecewiseUtilities.equals(transform, that.transform)) return false; if (!PiecewiseUtilities.equals(inverse, that.inverse)) return false; return super.equals(obj); } protected Class<?> getEquivalenceClass() { return DefaultPiecewiseTransform1DElement.class; } @Override public int hashCode() { if (hashCode >= 0) return hashCode; hashCode = 37; hashCode = PiecewiseUtilities.hash(transform, hashCode); hashCode = PiecewiseUtilities.hash(inverse, hashCode); hashCode = PiecewiseUtilities.hash(super.hashCode(), hashCode); return hashCode; } public static DefaultPiecewiseTransform1DElement create(String string, Range range, MathTransformation mathTransform1D) { return new DefaultPiecewiseTransform1DElement(string, range, mathTransform1D); } }