# HG changeset patch # User Sascha L. Teichmann # Date 1270572823 0 # Node ID d766fe2d917a733d0368360dbc41a596c69f962c # Parent db5b04ecb4267ea719628129fec3c08433d1d4f9 More javadoc. gnv-artifacts/trunk@883 c6561f87-3c4e-4783-a992-168aeb5c3f6f diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/ChangeLog --- a/gnv-artifacts/ChangeLog Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/ChangeLog Tue Apr 06 16:53:43 2010 +0000 @@ -1,3 +1,7 @@ +2010-04-06 Sascha L. Teichmann + + * src/main/java/de/intevation/gnv/**/*.java: More javadoc. + 2010-04-06 Tim Englich ISSUE215: Rows will not be merged to one Single Row if their values are identical. diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java Tue Apr 06 16:53:43 2010 +0000 @@ -149,7 +149,8 @@ long stopTime = System.currentTimeMillis(); if (debug) { - log.debug("interpolation took: " + (stopTime - startTime)/1000f + " secs"); + log.debug("interpolation took: " + + (stopTime - startTime)/1000f + " secs"); } this.raster = raster; diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/AttributedXYColumns.java Tue Apr 06 16:53:43 2010 +0000 @@ -27,7 +27,10 @@ this(columns, null); } - public AttributedXYColumns(List columns, Map attributes) { + public AttributedXYColumns( + List columns, + Map attributes + ) { this.columns = columns; this.attributes = attributes; } diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java Tue Apr 06 16:53:43 2010 +0000 @@ -191,7 +191,8 @@ Point2d avg = Point2d.average(positions); if (avg != null && avg.near(positions) - && (relevantArea == null || relevantArea.contains(avg.x, avg.y))) { + && (relevantArea == null + || relevantArea.contains(avg.x, avg.y))) { avg.i = i; avg.j = j; avg.inverseDistanceWeighting(neighbors); diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/math/IJKey.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/IJKey.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/IJKey.java Tue Apr 06 16:53:43 2010 +0000 @@ -48,7 +48,7 @@ /** * Hashes i and j into a common value. - * @return + * @return the hash code. */ @Override public int hashCode() { diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/math/QueriedXYDepth.java Tue Apr 06 16:53:43 2010 +0000 @@ -61,11 +61,14 @@ if (ro == null) { try { - String[] filterValues = new String[] { WKTUtils.toWKT(coordinate) }; - Collection result = queryExecutor.executeQuery(this.queryID,filterValues); + String[] filterValues = + new String[] { WKTUtils.toWKT(coordinate) }; + Collection result = queryExecutor.executeQuery( + queryID, filterValues); for (Result row: result) { if ((ro = (RasterObject)row.getObject(0)) != null) { - rasterData.add(new SoftReference(last = ro)); + rasterData.add( + new SoftReference(last = ro)); } break; } @@ -91,4 +94,4 @@ } return null; } -} +} \ No newline at end of file diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/AbstractProducer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/AbstractProducer.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/AbstractProducer.java Tue Apr 06 16:53:43 2010 +0000 @@ -2,17 +2,51 @@ import de.intevation.gnv.raster.Vectorizer.RingsHandler; +/** + * Abstract base class for producing multi polygons and + * multi line strings. This base class stores a bounding box + * of world coordinates which helps to transform the index + * spaced egde data into real world coordinates. + * + * @author Sascha L. Teichmann + */ public abstract class AbstractProducer implements RingsHandler { + /** + * min x coord of the world. + */ protected double minX; + + /** + * min y coord of the world. + */ protected double minY; + + /** + * max x coord of the world. + */ protected double maxX; + + /** + * max y coord of the world. + */ protected double maxY; + /** + * Default constructor. + */ public AbstractProducer() { } + /** + * Constructor to create an Abstract producer with a + * given world bounding box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ public AbstractProducer( double minX, double minY, double maxX, double maxY diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/Filter.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Filter.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Filter.java Tue Apr 06 16:53:43 2010 +0000 @@ -3,18 +3,36 @@ import org.w3c.dom.Element; /** + * Interface to model transformations of rasters. * @author Sascha L. Teichmann */ public interface Filter { + /** + * Allows the creation of filters parameterized from XML elements. + */ public interface Factory { + /** + * Setup the factory with a given XML element. + * @param element + */ void init(Element element); + /** + * Created a new Filter with this factory. + * @return The new created Filter. + */ Filter create(); } // interface Factory + /** + * Apply this filter to a given raster. The original raster is + * unmodified and a new raster is created. + * @param raster The original raster. + * @return The new raster. + */ Raster filter(Raster raster); } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoPolygonSeriesProducer.java Tue Apr 06 16:53:43 2010 +0000 @@ -97,18 +97,18 @@ } // for all in common open } // if map defined for key - if (ps.getItemCount() > 0) { - series.add(ps); - if (attributeGenerator != null) { + if (ps.getItemCount() > 0) { + series.add(ps); + if (attributeGenerator != null) { Object attribute = attributeGenerator .generateAttribute(key.i, key.j); if (attribute != null) { ps.setAttribute("label", attribute); - } - } - ps.setAttribute("line.width", LINE_WIDTH); - } + } + } + ps.setAttribute("line.width", LINE_WIDTH); + } } // for all pairs return series; diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java Tue Apr 06 16:53:43 2010 +0000 @@ -14,24 +14,60 @@ import java.util.List; /** + * Vectorizer backend to generate iso lines which are able to be visualized + * via {@link de.intevation.gnv.jfreechart.PolygonPlot} as line strings + * and custom labels on the chart. + * * @author Sascha L. Teichmann */ public class IsoProducer extends AbstractProducer { + /** + * Iso lines separate two neighbors. This interface decouples + * the generation of a suitable label for these to neighbors. + */ public interface AttributeGenerator { + /** + * Generate attribute show as label for two given neighbors. + * @param neighbor1 The first neighbor. + * @param neighbor2 The second neighbor. + * @return The label attribute. + */ Object generateAttribute(int neighbor1, int neighbor2); } // interface AttributeGenerator + /** + * Internal map of open edge to neighbor attributes. + */ protected HashMap open; + /** + * Internal map to associate neighbors with open edges. + */ protected HashMap commonOpen; + /** + * Internal map to associate neighbors with complete rings. + */ protected HashMap> complete; + /** + * Width of the index space. + */ protected int width; + /** + * Height of the index space. + */ protected int height; + /** + * Constructor with a given world bounding box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ public IsoProducer( double minX, double minY, double maxX, double maxY @@ -112,6 +148,10 @@ } // handleRings + /** + * Join the pairs of neighbors i,j to have a distinct set. + * @return The distinct pairs of neighbors. + */ protected HashSet joinPairs() { HashSet pairs = new HashSet(); pairs.addAll(complete .keySet()); @@ -119,6 +159,11 @@ return pairs; } + /** + * Filter out the head list from the open edge lists. + * @param map Map of end and head lists. + * @return list of only head lists. + */ protected static ArrayList headList(TIntObjectHashMap map) { final ArrayList headList = new ArrayList(); map.forEachValue(new TObjectProcedure() { @@ -134,6 +179,9 @@ return headList; } + /** + * Reset internal data structures to save some memory. + */ public void clear() { open.clear(); complete.clear(); diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/KernelFilter.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/KernelFilter.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/KernelFilter.java Tue Apr 06 16:53:43 2010 +0000 @@ -5,6 +5,7 @@ import org.w3c.dom.Element; /** + * An implemenation of raster filters based on given kernels. * @author Sascha L. Teichmann */ public class KernelFilter @@ -12,15 +13,33 @@ { private static Logger log = Logger.getLogger(KernelFilter.class); + /** + * Implemens a factory which produces KernelFilters with Gauss kernels. + */ public static class GaussFactory implements Filter.Factory { + /** + * Default sigma of Gauss kernel: {@value} + */ public static final double DEFAULT_SIGMA = 1.0d; + /** + * Default radius of Gauss kernel: {@value} + */ public static final int DEFAULT_RADIUS = 5; + /** + * Configured sigma. + */ protected double sigma; + /** + * Configured radius. + */ protected int radius; + /** + * Default constructor. + */ public GaussFactory() { sigma = DEFAULT_SIGMA; radius = DEFAULT_RADIUS; @@ -54,11 +73,21 @@ } } // class GaussFactory + /** + * The kernel used by this filter. + */ protected Raster.Kernel kernel; + /** + * Default constructor. + */ public KernelFilter() { } + /** + * Constructor to create a filter with a given kernel. + * @param kernel The kernel to be used. + */ public KernelFilter(Raster.Kernel kernel) { this.kernel = kernel; } diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Palette.java Tue Apr 06 16:53:43 2010 +0000 @@ -13,13 +13,18 @@ import org.w3c.dom.NodeList; /** + * Lookup mechanism to map double values from a list of + * ranges onto a set of colors and vice versa. * @author Sascha L. Teichmann */ public class Palette implements ValueToIndex { - private static Logger log = Logger.getLogger(Palette.class); + private static Logger log = Logger.getLogger(Palette.class); + /** + * An entry in the lookup table. + */ public static final class Entry implements Comparable { @@ -37,9 +42,16 @@ private Color color; + /** + * Default constructor + */ public Entry() { } + /** + * Copy constructor + * @param other The entry to copy. + */ public Entry(Entry other) { index = other.index; externalIndex = other.externalIndex; @@ -49,6 +61,16 @@ color = other.color; } + /** + * Constructor to set the palette index, the exteral index, + * the value range, the color and the description. + * @param index The pallette index + * @param externalIndex The external index + * @param from Start of the interval + * @param to End of the interval + * @param color The color belonging to this interval. + * @param description The description of this range. + */ public Entry( int index, int externalIndex, @@ -65,6 +87,12 @@ this.description = description; } + /** + * Compares two entries by the start point of the interval. + * @param other + * @return -1 if this start point is before other. +1 if this + * start point is after, else 0. + */ public int compareTo(Object other) { Entry e = (Entry)other; if (from < e.from) return -1; @@ -72,22 +100,46 @@ return 0; } + /** + * The starting point of the interval. + * @return The starting point. + */ public double getFrom() { return from; } + /** + * The end point of the interval. + * @return The end point. + */ public double getTo() { return to; } + /** + * The color of the entry. + * @return The color. + */ public Color getColor() { return color; } + /** + * The external index of this entry. Useful to model + * external joins. + * @return The external index. + */ public int getExternalIndex() { return externalIndex; } + /** + * Searches for an entry which has a range that contains + * the given value. + * @param value The value to be searched. + * @return The entry containing the value or null if no such + * entry exists. + */ public Entry locateEntry(double value) { Entry current = this; while (current != null) { @@ -102,6 +154,12 @@ return null; } + /** + * Returns the palette index for a given value. + * @param value The value to search. + * @return The index of the palette entry or -1 if + * no such entry exists. + */ public int locate(double value) { Entry entry = locateEntry(value); return entry != null @@ -109,6 +167,12 @@ : -1; } + /** + * Searches for an interval with a given index. + * @param index The index to be searched. + * @return The entry with the given index or null if no + * such entry exists. + */ public Entry findByIndex(int index) { Entry current = this; while (current != null) { @@ -122,18 +186,39 @@ return current; } + /** + * The description of this entry. + * @return The description. + */ public String getDescription() { return description; } + /** + * Determines if the range of this entry has + * infinitive length. + * @return true if the range of this entry has infinitive + * length else false. + */ public boolean isInfinity() { return from == -Double.MAX_VALUE || to == Double.MAX_VALUE; } } // class Entry + /** + * Internal table of the entrys. + */ protected Entry [] entries; + + /** + * Root of the entry tree used to map values to entries. + */ protected Entry lookup; + + /** + * The list of colors used by this palette. + */ protected Color [] rgbs; private Entry buildLookup(Entry [] entries, int lo, int hi) { @@ -147,9 +232,16 @@ return entry; } + /** + * Default constructor. + */ public Palette() { } + /** + * Constructor to create the palette from an XML document. + * @param document The document with palette information. + */ public Palette(Document document) { NodeList rangeNodes = document.getElementsByTagName("range"); @@ -172,6 +264,13 @@ buildLookup(); } + /** + * Constructor to split a given palette into a given number of + * equal sized sub entries. Ranges of infinitive length are not + * splitted. + * @param original The source palette. + * @param N The number of chunks to split single ranges into. + */ public Palette(Palette original, int N) { if (N < 2) { throw new IllegalArgumentException("N < 2"); @@ -253,35 +352,75 @@ } + /** + * Internal method to build the lookup tree. + */ protected void buildLookup() { Arrays.sort(entries); lookup = buildLookup(entries, 0, entries.length-1); } + /** + * Creates a new palette which has ranges that are subdivided + * into a given number of sub ranges each. + * @param N The number od sub divisions of each range. + * @return The new created palette. + */ public Palette subdivide(int N) { return new Palette(this, N); } + /** + * Return the number of entries in this palette. + * @return The number of entries. + */ public int getSize() { return rgbs.length; } + /** + * Return the color of an entry for a given index. + * @param index The index. + * @return The color. + */ public Color getColor(int index) { return rgbs[index]; } + /** + * Return the RGB value + * @param index of an entry for a given index. + * @return rgb value + */ public int indexToRGB(int index) { return rgbs[index].getRGB(); } + /** + * Searches for the index of an entry which contains the + * given value. + * @param value The value to be searched. + * @return The index of the entry or -1 if no entry is found. + */ public int toIndex(double value) { return lookup.locate(value); } + /** + * Searches for the an entry which contains the given value. + * @param value The value to be searched. + * @return The entry which contains the value or null if + * no such entry is found. + */ public Entry getEntry(double value) { return lookup.locateEntry(value); } + /** + * Searches the entry for a given index. + * @param index The index of the entry. + * @return The entry or null if no such entry is found. + */ public Entry getEntryByIndex(int index) { return lookup.findByIndex(index); } diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/PaletteManager.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PaletteManager.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PaletteManager.java Tue Apr 06 16:53:43 2010 +0000 @@ -5,20 +5,45 @@ import java.util.HashMap; /** + * Manages palettes by their name. Provides different levels of + * subdivisions. * @author Sascha L. Teichmann */ public class PaletteManager { + /** + * The base palette. + */ protected Palette base; + /** + * The description of the palette. + */ protected String description; + + /** + * The name of the palette. + */ protected String name; + /** + * Already created subdivisions of the palette. + */ protected HashMap> levels; + /** + * Default constructor. + */ public PaletteManager() { } + /** + * Constructor to create a palette manager with a given name, + * description and base palette. + * @param name The name. + * @param description The description. + * @param base The base palette. + */ public PaletteManager( String name, String description, @@ -30,18 +55,35 @@ levels = new HashMap>(); } + /** + * Returns the description of the palette. + * @return The description. + */ public String getDescription() { return description; } + /** + * The name of the palette. + * @return The name. + */ public String getName() { return name; } + /** + * Returns the base palette. + * @return The base palette. + */ public Palette getBase() { return base; } + /** + * Returns the subdivided palette of a given level. + * @param n The level of subdivision. + * @return The subdivided palette. + */ public Palette getLevel(int n) { if (n < 2) { return base; diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/PolygonDatasetProducer.java Tue Apr 06 16:53:43 2010 +0000 @@ -12,16 +12,34 @@ import java.util.List; /** + * Vectorizer backend to produce polygon datasets suitable to being + * displayed with {@link de.intevation.gnv.jfreechart.PolygonPlot}. + * * @author Sascha L. Teichmann */ public class PolygonDatasetProducer extends AbstractProducer { + /** + * Maps value integers to series of polygons to group + * them by value. + */ protected HashMap polygonSeries; + /** + * Default constructor. + */ protected PolygonDatasetProducer() { } + /** + * Constructor to create a PolygonDatasetProducer with + * a given world bound box. + * @param minX Min x coord of the world. + * @param minY Min y coord of the world. + * @param maxX Max x coord of the world. + * @param maxY Max y coord of the world. + */ public PolygonDatasetProducer( double minX, double minY, double maxX, double maxY @@ -79,6 +97,11 @@ } } + /** + * Creates a new PolygonDataset from the polygons build by this + * backend. + * @return the new PolygonDataset + */ public PolygonDataset getPolygonDataset() { return new PolygonDataset(polygonSeries.values()); } diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/Raster.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Raster.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Raster.java Tue Apr 06 16:53:43 2010 +0000 @@ -1,52 +1,116 @@ package de.intevation.gnv.raster; /** + * A 2D double valued representation of a raster array. * @author Sascha L. Teichmann */ public class Raster { + /** + * A kernel can be applied to a raster to fold its values. + */ public static class Kernel { + /** + * The coefficients of the folding matrix. + */ public static final class Coeff { + /** + * i delta index of this coefficient. + */ public int di; + /** + * i delta index of this coefficient. + */ public int dj; + /** + * The weight of this coefficient. + */ public double c; + /** + * Default constructor + */ public Coeff() { } + /** + * Constructor to set the delta position and the weight of + * the coefficient. + * @param di The i delta index. + * @param dj The j delta index. + * @param c The weight of the index. + */ public Coeff(int di, int dj, double c) { this.di = di; this.dj = dj; this.c = c; } + /** + * Returns a string representation of this coefficient. + * @return The string representation. + */ + @Override public String toString() { return String.valueOf(c); } } // class Coeff + /** + * The coefficients of the folding matrix. + */ protected Coeff [] coeffs; + /** + * The width of the kernel. + */ protected int width; + /** + * Default constrcutor. + */ public Kernel() { } + /** + * Constructor for a kernel with a given coefficient matrix + * with a given width. + * @param coeffs The coefficients. + * @param width The width of the kernel. + */ public Kernel(Coeff [] coeffs, int width) { this.coeffs = coeffs; this.width = width; } + /** + * Evaluates the 2D Gauss normal distribution a given x, y + * and a given sigma. + * @param x The x location. + * @param y The y location. + * @param sigma The sigma of the distribution. + * @return The value at point x, y. + */ public static double gauss(double x, double y, double sigma) { double s2 = sigma*sigma; return 1.0d/(2.0d*Math.PI*s2)*Math.exp(-(x*x + y*y)/(2.0d*s2)); } + /** + * Creates a Gauss kernel with sigma = 1 and width 5. + * @return The new kernel. + */ public static Kernel createGauss() { return createGauss(1.0d, 5); } + /** + * Creates a Gauss kernel with a given sigma and width. + * @param sigma The sigma value + * @param width The width of the kernel. + * @return The new kernel. + */ public static Kernel createGauss(double sigma, int width) { Coeff [] coeffs = new Coeff[width*width]; double sum = 0d; @@ -66,6 +130,13 @@ return new Kernel(coeffs, width); } + /** + * Evaluates this Kernel at the raster at raster index i, j. + * @param access The accessor to the raster. + * @param i The i raster index. + * @param j The j raster index. + * @return The folded value at index i, j. + */ public double fold(Access access, int i, int j) { double s = 0.0d; @@ -86,6 +157,11 @@ return s*(1.0d - unused); } + /** + * Returns a string representation of this kernel. + * @return The string representation. + */ + @Override public String toString() { StringBuilder sb = new StringBuilder(); @@ -107,25 +183,63 @@ } } // class Kernel + /** + * Interface of allow special access patterns to the raster, + * especially at the border. + */ public interface Access { + /** + * Returns the raster value at a given index point. + * @param i The i index + * @param j The j index + * @return The value of the raster. + */ double get(int i, int j); } // interface Access + /** + * Interface to decouple the lookup which is needed + * to map double values to integers. + */ public interface ValueToIndex { + /** + * Returns the corresponding integer to a given value. + * @param value The value to be queried. + * @return The integer value or -1 if no such value was found. + */ int toIndex(double value); } // interface ValueToIndex; + /** + * Brings raster to an integer representation with equal sized bins + * of integer vaules. + */ public static class IsoClasses implements ValueToIndex { + /** + * Linear scaling factor. + */ protected double m; + /** + * Linear offset. + */ protected double b; + /** + * Number of classes. + */ protected int numClasses; + /** + * Constructor to build a lookup to transform + * an raster into an equals sized bin integer array. + * @param raster The original raster + * @param numClasses The number of classes. + */ public IsoClasses(Raster raster, int numClasses) { this.numClasses = numClasses; @@ -165,6 +279,11 @@ } } + /** + * Implements the double to integer lookup. + * @param value The value to map. + * @return The mapped value. + */ public int toIndex(double value) { return Double.isNaN(value) ? -1 @@ -172,30 +291,62 @@ } } // class IsoClasses + /** + * Internal representation of the raster. + */ protected double [] raster; + /** + * The width of the raster. + */ protected int width; + /** + * Default constructor. Creates an 0x0 raster. + */ public Raster() { this(new double[0], 0); } + /** + * Creates a raster with given values and width. + * @param raster + * @param width + */ public Raster(double [] raster, int width) { this.raster = raster; this.width = width; } + /** + * The width of the raster. + * @return The width. + */ public int getWidth() { return width; } + /** + * The height of the raster. + * @return The height. + */ public int getHeight() { return raster.length / width; } + /** + * The values of the raster. + * @return The values. + */ public double [] getValues() { return raster; } + /** + * Creates an integer representation of this raster using a + * given value to index transformer. + * @param valueToIndex The transformer to map double to integer values. + * @return The new created integer representation. + */ public int [] toIndexed(ValueToIndex valueToIndex) { int [] dst = new int[raster.length]; for (int i = 0; i < raster.length; ++i) { @@ -204,6 +355,13 @@ return dst; } + /** + * Creates a new raster by applying a kernel to this raster. + * Access to the raster is continuous at the border. + * The original raster is not modified. + * @param kernel The kernel to be applied. + * @return The new raster. + */ public Raster create(Kernel kernel) { double [] dst = new double[raster.length]; Raster r = new Raster(dst, width); @@ -211,6 +369,12 @@ return r; } + /** + * Creates a new raster by applying a kernel to this raster. + * Access to the raster is given. + * @param kernel The kernel to be applied. + * @param access The access method to the raster. + */ public void apply(Kernel kernel, Access access) { int height = getHeight(); for (int j = 0; j < height; ++j) { @@ -221,6 +385,12 @@ } } + /** + * Returns a continuous access to the raster. Values + * at the border are repeated til infinity if indices + * are accessed outside the defined area. + * @return The accessor. + */ public Access continueBorder() { return new Access() { int height = getHeight()-1; @@ -234,4 +404,4 @@ }; } } -// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : +// vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : \ No newline at end of file diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/RasterToPPM.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/RasterToPPM.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/RasterToPPM.java Tue Apr 06 16:53:43 2010 +0000 @@ -6,6 +6,8 @@ import java.io.OutputStream; /** + * Little helper class to write a Raster into an output stream + * as a Netpbm PPM file. * @author Sascha L. Teichmann */ public class RasterToPPM @@ -13,7 +15,19 @@ private RasterToPPM() { } - public static void writeToPPM(Raster raster, Palette palette, OutputStream out) + /** + * Writes a Raster to a given stream as PPM. + * @param raster The raster to be written. + * @param palette The palette used to figure out the rgb values. + * @param out The stream to write into. + * @throws IOException Thrown if some error occurred during writing + * data to the output stream. + */ + public static void writeToPPM( + Raster raster, + Palette palette, + OutputStream out + ) throws IOException { int W = raster.getWidth(); diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/Vectorizer.java Tue Apr 06 16:53:43 2010 +0000 @@ -10,14 +10,30 @@ import org.apache.log4j.Logger; /** + * Instances of this class are able to vectorize 2D integer arrays + * with a kind of flood filling regions detection mechanism to + * a set of line strings and polygons. + * * @author Sascha L. Teichmann */ public class Vectorizer { private static Logger log = Logger.getLogger(Vectorizer.class); + /** + * Callback to process the found line strings and polygons. + */ public interface RingsHandler { + /** + * Called from {@link #process(de.intevation.gnv.raster.Vectorizer.RingsHandler) } + * to give the found features to the postprocessing backend. + * @param rings The found line strings and polygons. + * @param value The integer value of the raster surrounded by + * the features. + * @param width The width of the index space of the vectorized data. + * @param height The height of the index space of the vectorized data. + */ void handleRings( List rings, int value, @@ -26,27 +42,65 @@ } // interface RingsHandler + /** + * Doubly link list representing a line string or a polygon. + */ public static final class Edge { + /** + * The predecessor. + */ public Edge prev; + /** + * The successor. + */ public Edge next; + /** + * Index of first vertex. To separate x and y values + * you have to divide the value by the width of the + * index space. + */ public int a; + /** + * Index of second vertex. To separate x and y values + * you have to divide the value by the width of the + * index space. + */ public int b; + /** + * Default constructor. + */ public Edge() { } + /** + * Constructor to create Edge with two vertices. + * @param a The first vertex. + * @param b The second vertex. + */ public Edge(int a, int b) { this.a = a; this.b = b; } + /** + * Copy constructor + * @param other The edge to clone. + */ public Edge(Edge other) { a = other.a; b = other.b; } + /** + * Chain a given edge segment to this segment. The + * side of the chaining is determined by a given + * parameter. + * @param other The segment to chain. + * @param found The side to chain. + */ public void chain(Edge other, int found) { if (found == a) { @@ -64,6 +118,11 @@ throw new IllegalStateException("cannot chain"); } + /** + * Tells if the list is complete which means that this + * edge list is a closed polygon. + * @return true if edge list is closed else false. + */ public boolean isComplete() { Edge current = this; do { @@ -76,6 +135,11 @@ return true; } + /** + * Returns the length of this edge list in next direction. + * Segments in prev direction are ignored. + * @return The length of this edge list. + */ public int length() { int length = 0; Edge current = this; @@ -84,24 +148,47 @@ return length; } - public Edge head() { - Edge current = this; - while (current.prev != null) { - current = current.prev; - } - return current; - } + /** + * Returns the head node of this edge list. + * @return The head node. + */ + public Edge head() { + Edge current = this; + while (current.prev != null) { + current = current.prev; + } + return current; + } + /** + * Hashes the two vertex indices to a common value. + * @return The hash value. + */ + @Override public int hashCode() { return (a << 16) | b; } + /** + * Two edges are considered equal if they have the same + * a and b vertices. + * @param other The other edge. + * @return true if the edges are equal else false. + */ + @Override public boolean equals(Object other) { Edge e = (Edge)other; return a == e.a && b == e.b; } } // class Edge + /** + * Simplifies a given edge list by removing collinear vertices. + * Attention: The original list is modified. + * @param edge The edge list to simplify. + * @param width The width of the vertex index space. + * @return The simplified list. + */ protected static Edge simplify(Edge edge, int width) { Edge e1 = edge, start = edge; @@ -150,55 +237,127 @@ return start; } + /** + * The raster to be traced. + */ protected int [] raster; + /** + * The width of the raster. + */ protected int width; + /** + * Map of the currently open edges. + */ protected TIntObjectHashMap openEdges; + /** + * List of rings already found. + */ protected List rings; + /** + * Flag to signal if a simplification should be performed + * after a ring is completed. + */ protected boolean simplify; + /** + * Default constructor. Simplification is turned on. + */ public Vectorizer() { this(true); } + /** + * Constructor to create a vectorized with an explicit + * simplification policy. + * @param simplify Indicates if simplification should be + * used on ring completion. + */ public Vectorizer(boolean simplify) { openEdges = new TIntObjectHashMap(); rings = new ArrayList(); this.simplify = simplify; } + /** + * Constructor to create a vectorizer with a given raster and width. + * Simplification is turn on. + * @param raster The raster to be vectorized. + * @param width The width of the raster. + */ public Vectorizer(int [] raster, int width) { this(true, raster, width); } + /** + * Constructor to create a vectorizer with a given raster, width + * and an explicit simplification policy. + * @param simplify Indicates if simplification should be + * used on ring completion. + * @param raster The raster to be vectorized. + * @param width The width of the raster. + */ public Vectorizer(boolean simplify, int [] raster, int width) { this(simplify); this.raster = raster; this.width = width; } + /** + * Returns (x, y+1) for given vertex in index space. + * @param i vertex in index space. + * @param w width of raster. + * @return (x, y+1) in index space. + */ public static final int tl(int i, int w) { int x = i % w; int y = i / w; return x + (w + 1)*y; } + /** + * Returns tl(i, w) + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return tl(i, w) + 1. + */ public static final int tr(int i, int w) { return tl(i, w) + 1; } + /** + * Returns tl(i, w) + w + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return tl(i, w) + w + 1. + */ public static final int bl(int i, int w) { return tl(i, w) + w + 1; } + /** + * Returns bl(i, w) + 1. + * @param i vertex in index space. + * @param w width of raster. + * @return bl(i, w) + 1. + */ public static final int br(int i, int w) { return bl(i, w) + 1; } + /** + * Resets open resources after a set of features were found. + */ protected void resetRegion() { openEdges.clear(); rings.clear(); } + /** + * Adds an edge to the map of open edges, joins it + * with its direct neighbors of if complete add the + * list to the complete features. + * @param edge + */ protected void emit(Edge edge) { Edge otherA = (Edge)openEdges.remove(edge.a); @@ -224,6 +383,12 @@ } } + /** + * Vectorize the raster. The found features are fed into + * the given ring handler. + * @param handler The RingHandler to postprocess the found features. + * @return The number of regions found. + */ public int process(RingsHandler handler) { BitSet visited = new BitSet(raster.length); diff -r db5b04ecb426 -r d766fe2d917a gnv-artifacts/src/main/java/de/intevation/gnv/raster/package.html --- a/gnv-artifacts/src/main/java/de/intevation/gnv/raster/package.html Tue Apr 06 13:07:11 2010 +0000 +++ b/gnv-artifacts/src/main/java/de/intevation/gnv/raster/package.html Tue Apr 06 16:53:43 2010 +0000 @@ -3,6 +3,8 @@ -DOCUMENT ME! +Classes and interfaces to handle 2D double valued +raster arrays. Additional palette support and vectorization these rasters into +simple feature vector representations are supplied.