diff gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java @ 424:21fbd254db71

Added support for converting 2D rasters into polygons. gnv-artifacts/trunk@472 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author Sascha L. Teichmann <sascha.teichmann@intevation.de>
date Mon, 21 Dec 2009 18:00:54 +0000
parents
children 3a0c0ad113d9
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java	Mon Dec 21 18:00:54 2009 +0000
@@ -0,0 +1,188 @@
+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;
+
+    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 description = rangeElement.getAttribute("description");
+            if (from > to) { double t = from; from = to; to = t; }
+            entries[i] = new Entry(i, from, to, color, description);
+            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 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