view gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java @ 426:3a0c0ad113d9

Load palettes from configuration. gnv-artifacts/trunk@474 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Tue, 22 Dec 2009 10:34:15 +0000
parents 21fbd254db71
children 67091b17462d
line wrap: on
line source
package de.intevation.gnv.raster;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

import java.util.Arrays;

import java.awt.Color;

import de.intevation.gnv.raster.Raster.ValueToIndex;

/**
 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de)
 */
public class Palette
implements   ValueToIndex
{
    public static final class Entry 
    implements                Comparable
    {
        private Entry  left;
        private Entry  right;

        private int    index;

        private double from;
        private double to;

        private String description;

        private Color  color;

        public Entry() {
        }

        public Entry(
            int    index, 
            double from, 
            double to, 
            Color  color,
            String description
        ) {
            this.index       = index;
            this.from        = from;
            this.to          = to;
            this.color       = color;
            this.description = description;
        }

        public int compareTo(Object other) {
            Entry e = (Entry)other;
            if (from < e.from) return -1;
            if (from > e.from) return +1;
            return 0;
        }

        public Entry locateEntry(double value) {
            Entry current = this;
            while (current != null) {
                boolean b = value >= current.from;
                if (b && value <= current.to) {
                    return current;
                }
                current = b
                    ? current.right
                    : current.left;
            }
            return null;
        }

        public int locate(double value) {
            Entry entry = locateEntry(value);
            return entry != null
                ? entry.index
                : -1;
        }

        public Entry findByIndex(int index) {
            Entry current = this;
            while (current != null) {
                if (current.index == index) {
                    break;
                }
                current = index < current.index
                    ? current.left
                    : current.right;
            }
            return current;
        }

        public String getDescription() {
            return description;
        }
    } // class Entry

    protected Entry [] entries;
    protected Entry    lookup;
    protected Color [] rgbs;
    protected String   description;

    private Entry buildLookup(Entry [] entries, int lo, int hi) {
        if (lo > hi) {
            return null;
        }
        int mid = (lo + hi)/2;
        Entry entry = entries[mid];
        entry.left  = buildLookup(entries, lo, mid-1);
        entry.right = buildLookup(entries, mid+1, hi);
        return entry;
    }

    public Palette() {
    }

    public Palette(Document document) {
        this(document, null);
    }

    public Palette(Document document, String description) {

        this.description = description;

        NodeList rangeNodes = document.getElementsByTagName("range");

        entries = new Entry[rangeNodes.getLength()];
        rgbs    = new Color[entries.length];

        for (int i = 0; i < entries.length; ++i) {
            Element rangeElement = (Element)rangeNodes.item(i);
            double from  = doubleValue(rangeElement.getAttribute("from"));
            double to    = doubleValue(rangeElement.getAttribute("to"));
            Color  color = color(rangeElement.getAttribute("rgb"));
            String desc = rangeElement.getAttribute("description");
            if (from > to) { double t = from; from = to; to = t; }
            entries[i] = new Entry(i, from, to, color, desc);
            rgbs[i] = color;
        }

        buildLookup();
    }

    private static final double doubleValue(String s) {
        if (s == null || (s = s.trim()).length() == 0) {
            return 0d;
        }
        if ((s = s.toLowerCase()).startsWith("-inf")) {
            return -Double.MAX_VALUE; // XXX: Not using Double.NEGATIVE_INFINITY!
        }

        if (s.startsWith("inf")) {
            return Double.MAX_VALUE; // XXX: Not using Double.NEGATIVE_INFINITY!
        }

        return Double.parseDouble(s);
    }

    private static final Color color(String s) {
        if (s == null || (s = s.trim()).length() == 0) {
            return null;
        }
        return Color.decode(s);
    }


    protected void buildLookup() {
        Arrays.sort(entries);
        lookup = buildLookup(entries, 0, entries.length-1);
    }

    public String getDescription() {
        return description;
    }

    public int getSize() {
        return rgbs.length;
    }

    public Color getColor(int index) {
        return rgbs[index];
    }

    public int indexToRGB(int index) {
        return rgbs[index].getRGB();
    }

    public int toIndex(double value) {
        return lookup.locate(value);
    }

    public Entry getEntry(double value) {
        return lookup.locateEntry(value);
    }

    public Entry getEntryByIndex(int index) {
        return lookup.findByIndex(index);
    }
}
// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8:

http://dive4elements.wald.intevation.org