/******************************************************************************* * Copyright 2012 Geoscience Australia * * 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 au.gov.ga.earthsci.worldwind.common.util; import java.awt.Color; import java.util.Map.Entry; import java.util.TreeMap; /** * Color map that allows mapping from a double value to a color. Contains * interpolation functionality for interpolating between the two closest color * mappings for a certain double value. * * @author Michael de Hoog (michael.dehoog@ga.gov.au) */ public class ColorMap extends TreeMap<Double, Color> { private boolean interpolateHue = true; private boolean valuesPercentages = false; /** * @return Should the interpolation be performed in the HSB color space? If * not, the RGB color space is used. */ public boolean isInterpolateHue() { return interpolateHue; } /** * Set whether the interpolation should be performed in the HSB color space. * * @param interpolateHue */ public void setInterpolateHue(boolean interpolateHue) { this.interpolateHue = interpolateHue; } /** * @return Should the values mapped to the colors in this map be treated as * percentages? */ public boolean isValuesPercentages() { return valuesPercentages; } /** * Set whether the values mapped to the colors in the map should be treated * as percentages. * * @param valuesPercentages */ public void setValuesPercentages(boolean valuesPercentages) { this.valuesPercentages = valuesPercentages; } /** * Calculate the color for the given double value. If there is no exact * mapping for this value, the two closest color mappings either side of the * provided value are interpolated. If this contains no colors, black is * returned. * * @param value * @return Color at value */ public Color calculateColor(double value) { Entry<Double, Color> lessEntry = floorEntry(value); Entry<Double, Color> greaterEntry = ceilingEntry(value); double mixer = 0; if (lessEntry != null && greaterEntry != null) { double window = greaterEntry.getKey() - lessEntry.getKey(); if (window > 0) { mixer = (value - lessEntry.getKey()) / window; } } Color color0 = lessEntry == null ? null : lessEntry.getValue(); Color color1 = greaterEntry == null ? null : greaterEntry.getValue(); return Util.interpolateColor(color0, color1, mixer, interpolateHue); } /** * Calculate the color for the given double value as a percentage between * the given minimum and maximum. The given value is scaled between 0 and 1 * before passing to the {@link #calculateColor(double)} function. * * @param value * @param minimum * @param maximum * @return Color at value */ public Color calculateColorAsPercentage(double value, double minimum, double maximum) { return calculateColor((value - minimum) / (maximum - minimum)); } /** * Calculate the color for the given double value. If * {@link #isValuesPercentages()} is true, the given value is scaled between * 0 and 1 (using the given minimum and maximum) before being passed to the * {@link #calculateColor(double)} function. * * @param value * @param minimum * @param maximum * @return Color at value */ public Color calculateColorNotingIsValuesPercentages(double value, double minimum, double maximum) { if (isValuesPercentages()) return calculateColorAsPercentage(value, minimum, maximum); return calculateColor(value); } }