Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java @ 468:7ba4c7222265
Added ij-Index determination for horizontal-cross-sections.
gnv-artifacts/trunk@531 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Tue, 12 Jan 2010 11:34:25 +0000 |
parents | c7ca2fce041f |
children | c8089cd7d777 |
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 org.apache.log4j.Logger; import de.intevation.gnv.raster.Raster.ValueToIndex; /** * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) */ public class Palette implements ValueToIndex { private static Logger log = Logger.getLogger(Palette.class); 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(Entry other) { index = other.index; from = other.from; to = other.to; description = other.description; color = other.color; } 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 double getFrom() { return from; } public double getTo() { return to; } public Color getColor() { return color; } 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; } public boolean isInfinity() { return from == -Double.MAX_VALUE || to == Double.MAX_VALUE; } } // class Entry protected Entry [] entries; protected Entry lookup; protected Color [] rgbs; 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) { 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(); } public Palette(Palette original, int N) { if (N < 2) { throw new IllegalArgumentException("N < 2"); } Entry [] origEntries = original.entries; int newSize = 0; for (int i = 0; i < origEntries.length; ++i) { // cannot split infinity intervals newSize += origEntries[i].isInfinity() ? 1 : N; } entries = new Entry[newSize]; rgbs = new Color[newSize]; for (int i = 0, j = 0; i < origEntries.length; ++i) { Entry origEntry = origEntries[i]; if (origEntry.isInfinity()) { // infinity intervals are just copied Entry nEntry = new Entry(origEntry); entries[j] = nEntry; rgbs[j] = nEntry.color; nEntry.index = j++; } else { // split interval into N parts double from = origEntry.from; double to = origEntry.to; double delta = (to - from)/N; for (int k = 0; k < N; ++k) { Entry nEntry = new Entry(origEntry); nEntry.from = from; nEntry.to = from + delta; from += delta; entries[j] = nEntry; rgbs[j] = nEntry.color; nEntry.index = j++; } } // limited interval } // for all original entries 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 Palette subdivide(int N) { return new Palette(this, N); } 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: