Mercurial > dive4elements > gnv-client
view gnv-artifacts/src/main/java/de/intevation/gnv/math/GridCell.java @ 598:9681ac6b6527
Added the possibility to use the data which are send using the MapServer-Interface during the Workflow of the GNV-Artifacts.
gnv-artifacts/trunk@656 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Tim Englich <tim.englich@intevation.de> |
---|---|
date | Tue, 02 Feb 2010 13:12:11 +0000 |
parents | b248531fa20b |
children | c4156275c1e1 |
line wrap: on
line source
package de.intevation.gnv.math; import com.vividsolutions.jts.algorithm.CGAlgorithms; import com.vividsolutions.jts.geom.Coordinate; import com.vividsolutions.jts.geom.Envelope; import com.vividsolutions.jts.geom.Geometry; import com.vividsolutions.jts.geom.GeometryFactory; import com.vividsolutions.jts.geom.LinearRing; import com.vividsolutions.jts.geom.Point; import com.vividsolutions.jts.geom.Polygon; import com.vividsolutions.jts.index.ItemVisitor; import java.io.Serializable; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import org.apache.log4j.Logger; /** * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) */ public class GridCell implements Serializable { private static Logger log = Logger.getLogger(GridCell.class); public static final class CellFinder implements ItemVisitor { public GridCell found; protected Point point; public CellFinder() { } public void prepare(Coordinate center) { found = null; point = GEOMETRY_FACTORY.createPoint(center); } public void visitItem(Object item) { if (found == null) { GridCell cell = (GridCell)item; if (cell.contains(point)) { found = cell; } } } } // class CellFinder public Point2d p1; public Point2d p2; public Point2d p3; public Point2d p4; protected Polygon polygon; public static final GeometryFactory GEOMETRY_FACTORY = new GeometryFactory(); public GridCell() { } public GridCell(Point2d p1, Point2d p2, Point2d p3, Point2d p4) { this.p1 = p1; this.p2 = p2; this.p3 = p3; this.p4 = p4; createPolygon(); } protected void createPolygon() { Coordinate [] coords = new Coordinate [] { p1, p2, p3, p4, p1 }; if (!CGAlgorithms.isCCW(coords)) { for (int i = 0, j = coords.length-1; i < j; ++i, --j) { Coordinate c = coords[i]; coords[i] = coords[j]; coords[j] = c; } } LinearRing shell = GEOMETRY_FACTORY .createLinearRing(coords); if (!shell.isValid()) { log.warn("linear ring is not valid"); } polygon = GEOMETRY_FACTORY.createPolygon(shell, null); } public Envelope getEnvelope() { return polygon.getEnvelopeInternal(); } public boolean contains(Geometry coord) { return polygon.contains(coord); } public static List<GridCell> pointsToGridCells( List<? extends Point2d> points ) { return pointsToGridCells(points, null); } public static List<GridCell> pointsToGridCells( List<? extends Point2d> points, Envelope relevantArea ) { return pointsToGridCells(points, relevantArea, 0); } private static final int NEIGHBORS [][] = { { -1, -1 }, // 0 { -1, 0 }, // 1 { -1, +1 }, // 2 { 0, +1 }, // 3 { +1, +1 }, // 4 { +1, 0 }, // 5 { +1, -1 }, // 6 { 0, -1 } // 7 }; public static int extrapolate( HashMap<Integer, HashMap<Integer, Point2d>> rows, int minI, int maxI, int minJ, int maxJ, int rounds, Envelope relevantArea ) { Point2d [] neighbors = new Point2d[NEIGHBORS.length]; Point2d [] positions = new Point2d[NEIGHBORS.length]; int total = 0; ArrayList<ArrayList<IJKey>> prio = new ArrayList<ArrayList<IJKey>>(NEIGHBORS.length); for (int i = 0; i < NEIGHBORS.length; ++i) { prio.add(new ArrayList<IJKey>()); } while (rounds-- > 0) { for (int i = minI; i <= maxI; ++i) { for (int j = minJ; j <= maxJ; ++j) { Point2d p = get(rows, i, j); if (p != null) { continue; } int count = 0; for (int k = 0; k < neighbors.length; ++k) { neighbors[k] = positions[k] = null; int dij [] = NEIGHBORS[k]; Point2d n1 = get(rows, i+ dij[0], j+ dij[1]); Point2d n2 = get(rows, i+2*dij[0], j+2*dij[1]); if (n1 != null && n2 != null) { ++count; } } if (count > 0) { prio.get(count-1).add(new IJKey(i, j)); } } // for all columns } // for all rows int N = 0; for (int l = NEIGHBORS.length-1; l >= 0; --l) { ArrayList<IJKey> list = prio.get(l); for (IJKey ij: list) { int i = ij.i; int j = ij.j; for (int k = 0; k < neighbors.length; ++k) { neighbors[k] = positions[k] = null; int dij [] = NEIGHBORS[k]; Point2d n1 = get(rows, i+ dij[0], j+ dij[1]); Point2d n2 = get(rows, i+2*dij[0], j+2*dij[1]); if (n1 != null && n2 != null) { neighbors[k] = n1; positions[k] = n1.extrapolate(-1d, n2); } } Point2d avg = Point2d.average(positions); if (avg != null && avg.near(positions) && (relevantArea == null || relevantArea.contains(avg.x, avg.y))) { avg.i = i; avg.j = j; avg.inverseDistanceWeighting(neighbors); put(rows, avg, i, j); } } N += list.size(); list.clear(); } if (N == 0) { break; } total += N; } // for all rounds return total; } public static List<GridCell> pointsToGridCells( List<? extends Point2d> points, Envelope relevantArea, int extrapolationRounds ) { int minI = Integer.MAX_VALUE; int maxI = Integer.MIN_VALUE; int minJ = Integer.MAX_VALUE; int maxJ = Integer.MIN_VALUE; HashMap<Integer, HashMap<Integer, Point2d>> rows = new HashMap<Integer, HashMap<Integer, Point2d>>(); int culled = 0; for (Point2d p: points) { if (relevantArea != null && !relevantArea.contains(p.x, p.y)) { ++culled; continue; } if (p.i < minI) minI = p.i; if (p.i > maxI) maxI = p.i; if (p.j < minJ) minJ = p.j; if (p.j > maxJ) maxJ = p.j; HashMap<Integer, Point2d> row = rows.get(p.i); if (row == null) { rows.put(p.i, row = new HashMap<Integer, Point2d>()); } row.put(p.j, p); } ArrayList<GridCell> cells = new ArrayList<GridCell>(points.size()); int extrapolated = extrapolate( rows, minI, maxI, minJ, maxJ, extrapolationRounds, relevantArea); for (int i = minI + 1; i <= maxI; ++i) { HashMap<Integer, Point2d> row1 = rows.get(i-1); HashMap<Integer, Point2d> row2 = rows.get(i); if (row1 == null || row2 == null) { continue; } for (int j = minJ + 1; j < maxJ; ++j) { Point2d p1 = row1.get(j-1); Point2d p2 = row1.get(j); Point2d p3 = row2.get(j); Point2d p4 = row2.get(j-1); if (p1 != null && p2 != null && p3 != null && p4 != null) { cells.add(new GridCell(p1, p2, p3, p4)); } } } // for all rows if (log.isDebugEnabled()) { log.debug("culled points: " + culled); log.debug("extrapolated points: " + extrapolated); log.debug("min/max i: " + minI + " / " + maxI); log.debug("min/max j: " + minJ + " / " + maxJ); log.debug("cells found: " + cells.size()); } return cells; } private static Point2d get( HashMap<Integer, HashMap<Integer, Point2d>> rows, int i, int j ) { HashMap<Integer, Point2d> row = rows.get(i); return row != null ? row.get(j) : null; } private static void put( HashMap<Integer, HashMap<Integer, Point2d>> rows, Point2d point, int i, int j ) { Integer I = Integer.valueOf(i); HashMap<Integer, Point2d> row = rows.get(I); if (row == null) { rows.put(I, row = new HashMap<Integer, Point2d>()); } row.put(j, point); } } // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :