Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/raster/IsoProducer.java @ 1030:c07d9f9a738c
Removed bugs that existed in the caching mechanism (issue264, issue268).
gnv-artifacts/trunk@1067 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Ingo Weinzierl <ingo.weinzierl@intevation.de> |
---|---|
date | Thu, 06 May 2010 08:32:56 +0000 |
parents | 4abe172be970 |
children | f953c9a559d8 |
line wrap: on
line source
package de.intevation.gnv.raster; import de.intevation.gnv.math.IJKey; import de.intevation.gnv.raster.Vectorizer.Edge; import gnu.trove.TIntHashSet; import gnu.trove.TIntObjectHashMap; import gnu.trove.TObjectProcedure; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; import java.util.List; /** * Vectorizer backend to generate iso lines as line strings * and custom labels on the chart. * * @author <a href="mailto:sascha.teichmann@intevation.de">Sascha L. Teichmann</a> */ 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<Edge, Integer> open; /** * Internal map to associate neighbors with open edges. */ protected HashMap<IJKey, TIntObjectHashMap> commonOpen; /** * Internal map to associate neighbors with complete rings. */ protected HashMap<IJKey, ArrayList<Edge>> 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 ) { super(minX, minY, maxX, maxY); open = new HashMap<Edge, Integer>(); commonOpen = new HashMap<IJKey, TIntObjectHashMap>(); complete = new HashMap<IJKey, ArrayList<Edge>>(); } public void handleRings( List<Edge> rings, int value, int width, int height ) { if (value == -1) { return; } this.width = width; this.height = height; Integer v = Integer.valueOf(value); for (Edge head: rings) { Edge current = head; do { Integer neighbor = open.remove(current); if (neighbor != null) { IJKey pair = new IJKey(value, neighbor.intValue()); pair.sort(); TIntObjectHashMap co = commonOpen.get(pair); if (co == null) { commonOpen.put(pair, co = new TIntObjectHashMap()); } Edge edge = new Edge(current); Edge otherA = (Edge)co.remove(edge.a); if (otherA != null) { otherA.chain(edge, edge.a); } Edge otherB = (Edge)co.remove(edge.b); if (otherB != null) { otherB.chain(edge, edge.b); } if (edge.isComplete()) { ArrayList list = complete.get(pair); if (list == null) { complete.put(pair, list = new ArrayList()); } list.add(Vectorizer.simplify(edge, width)); } else { if (otherA == null) { co.put(edge.a, edge); } if (otherB == null) { co.put(edge.b, edge); } } } else { Edge edge = new Edge(current.b, current.a); open.put(edge, v); } current = current.next; } while (current != head); } // for all rings } // handleRings /** * Join the pairs of neighbors i,j to have a distinct set. * @return The distinct pairs of neighbors. */ protected HashSet<IJKey> joinPairs() { HashSet<IJKey> pairs = new HashSet<IJKey>(); pairs.addAll(complete .keySet()); pairs.addAll(commonOpen.keySet()); 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<Edge> headList(TIntObjectHashMap map) { final ArrayList<Edge> headList = new ArrayList<Edge>(); map.forEachValue(new TObjectProcedure() { TIntHashSet headSet = new TIntHashSet(); public boolean execute(Object value) { Edge head = ((Edge)value).head(); if (headSet.add(head.a)) { headList.add(head); } return true; } }); return headList; } /** * Reset internal data structures to save some memory. */ public void clear() { open.clear(); complete.clear(); commonOpen.clear(); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :