/* * GeoTools - The Open Source Java GIS Toolkit * http://geotools.org * * (C) 2002-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.renderer.lite.gridcoverage2d; import java.awt.Color; import org.geotools.referencing.piecewise.DefaultPiecewiseTransform1DElement; import org.geotools.renderer.i18n.ErrorKeys; import org.geotools.renderer.i18n.Errors; import org.opengis.geometry.DirectPosition; import org.opengis.geometry.MismatchedDimensionException; class ColorMapUtilities { /** * Codes ARGB par d�faut. On utilise un exemplaire unique pour toutes les * cr�ation d'objets {@link LinearColorMapElement}. */ static final int[] DEFAULT_ARGB = { 0xFF000000, 0xFFFFFFFF }; /** * Makes sure that an argument is non-null. * * @param name * Argument name. * @param object * User argument. * @throws IllegalArgumentException * if {@code object} is null. */ static void ensureNonNull(final String name, final Object object) throws IllegalArgumentException { if (object == null) { throw new IllegalArgumentException(Errors.format( ErrorKeys.NULL_ARGUMENT_$1, name)); } } /** * Compare deux valeurs de type {@code double}. Cette m�thode est similaire * � {@link Double#compare(double,double)}, except� qu'elle ordonne aussi * les diff�rentes valeurs NaN. */ static int compare(final double v1, final double v2) { if (Double.isNaN(v1) && Double.isNaN(v2)) { final long bits1 = Double.doubleToRawLongBits(v1); final long bits2 = Double.doubleToRawLongBits(v2); if (bits1 < bits2) return -1; if (bits1 > bits2) return +1; } return Double.compare(v1, v2); } // /** // * Returns a linear transform with the supplied scale and offset values. // * // * @param scale // * The scale factor. May be 0 for a constant transform. // * @param offset // * The offset value. May be NaN if this method is invoked from a // * constructor for initializing {@link #transform} for a // * qualitative category. // */ // static MathTransform1D createLinearTransform( // final double scale, final double offset) { // return LinearTransform1D.create(scale, offset); // } // // /** // * Create a linear transform mapping values from {@code sampleValueRange} to // * {@code geophysicsValueRange}. // */ // static MathTransform1D createLinearTransform( // final NumberRange sourceRange, final NumberRange destinationRange) { // final Class sType = sourceRange.getElementClass(); // final Class dType = destinationRange.getElementClass(); // /* // * First, find the direction of the adjustment to apply to the ranges if // * we wanted all values to be inclusives. Then, check if the adjustment // * is really needed: if the values of both ranges are inclusive or // * exclusive, then there is no need for an adjustment before computing // * the coefficient of a linear relation. // */ // int sMinInc = sourceRange.isMinIncluded() ? 0 : +1; // int sMaxInc = sourceRange.isMaxIncluded() ? 0 : -1; // int dMinInc = destinationRange.isMinIncluded() ? 0 : +1; // int dMaxInc = destinationRange.isMaxIncluded() ? 0 : -1; // // /* // * Now, extracts the minimal and maximal values and computes the linear // * coefficients. // */ // final double minSource = doubleValue(sType, sourceRange.getMinValue(), // sMinInc); // final double maxSource = doubleValue(sType, sourceRange.getMaxValue(), // sMaxInc); // final double minDestination = doubleValue(dType, destinationRange // .getMinValue(), dMinInc); // final double maxDestination = doubleValue(dType, destinationRange // .getMaxValue(), dMaxInc); // // // ///////////////////////////////////////////////////////////////// // // // // optimizations // // // // ///////////////////////////////////////////////////////////////// // // // // // // // If the output range is a single value let's create a constant // // transform // // // // // // if (ColorMapUtilities.compare(minDestination, maxDestination) == 0) // return LinearTransform1D.create(0, minDestination); // // // // // // // // If the input range is a single value this transform ca be created // // only if we map to another single value // // // // // // if (ColorMapUtilities.compare(minSource, maxSource) == 0) // throw new IllegalArgumentException("Impossible to map a single value to a range."); // // double scale = (maxDestination - minDestination) // / (maxSource - minSource); // // ///////////////////////////////////////////////////////////////// // // // // Take into account the fact that the maxSample and the minSample can // // be // // similar hence we have a constant transformation. // // // // ///////////////////////////////////////////////////////////////// // if (Double.isNaN(scale)) // scale = 0; // final double offset = minDestination - scale * minSource; // return createLinearTransform(scale, offset); // } // // /** // * Returns a {@code double} value for the specified number. If // * {@code direction} is non-zero, then this method will returns the closest // * representable number of type {@code type} before or after the double // * value. // * // * @param type // * The range element class. {@code number} must be an instance of // * this class (this will not be checked). // * @param number // * The number to transform to a {@code double} value. // * @param direction // * -1 to return the previous representable number, +1 to return // * the next representable number, or 0 to return the number with // * no change. // */ // static double doubleValue(final Class type, // final Comparable number, final int direction) { // assert (direction >= -1) && (direction <= +1) : direction; // return XMath.rool(type, ((Number) number).doubleValue(), direction); // } /** * Ensure the specified point is one-dimensional. */ static void checkDimension(final DirectPosition point) { final int dim = point.getDimension(); if (dim != 1) { throw new MismatchedDimensionException(Errors.format( ErrorKeys.MISMATCHED_DIMENSION_$2, Integer.valueOf(1), Integer.valueOf(dim))); } } /** * Check that all the output values for the various * {@link DefaultConstantPiecewiseTransformElement} are equal. * * @param preservingElements * array of {@link DefaultConstantPiecewiseTransformElement}s. * @return the array of {@link DefaultConstantPiecewiseTransformElement}s if the check is * successful. * @throws IllegalArgumentException * in case the check is unsuccessful. */ static DefaultPiecewiseTransform1DElement[] checkPreservingElements( LinearColorMapElement[] preservingElements) { if (preservingElements != null) { double outval = Double.NaN; Color color=null; for (int i = 0; i < preservingElements.length; i++) { //the no data element must be a linear transform mapping to a single value if(!(preservingElements[i] instanceof ConstantColorMapElement)) throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, preservingElements)); final ConstantColorMapElement nc = (ConstantColorMapElement) preservingElements[i]; if(nc.getColors().length!=1) throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); if (i == 0) { outval = nc.getOutputMaximum(); color=nc.getColors()[0]; } else { if (compare(outval, nc.getOutputMaximum()) != 0) throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); if (!color.equals(nc.getColors()[0])) throw new IllegalArgumentException(Errors.format(ErrorKeys.ILLEGAL_ARGUMENT_$1, nc.getColors())); } } } return preservingElements; } }