Mercurial > dive4elements > gnv-client
comparison gnv-artifacts/src/main/java/de/intevation/gnv/math/AreaInterpolation.java @ 474:ab29e4ff2fda
Added area interpolation needed for "Horizontalschnitt"
gnv-artifacts/trunk@540 c6561f87-3c4e-4783-a992-168aeb5c3f6f
author | Sascha L. Teichmann <sascha.teichmann@intevation.de> |
---|---|
date | Thu, 14 Jan 2010 10:34:05 +0000 |
parents | |
children | d47b478e662b |
comparison
equal
deleted
inserted
replaced
473:a6a33ef35809 | 474:ab29e4ff2fda |
---|---|
1 package de.intevation.gnv.math; | |
2 | |
3 import java.io.Serializable; | |
4 | |
5 import java.util.ArrayList; | |
6 import java.util.Arrays; | |
7 import java.util.List; | |
8 import java.util.HashMap; | |
9 import java.util.Collections; | |
10 | |
11 import java.awt.Dimension; | |
12 | |
13 import com.vividsolutions.jts.geom.Coordinate; | |
14 import com.vividsolutions.jts.geom.Envelope; | |
15 | |
16 import com.vividsolutions.jts.index.quadtree.Quadtree; | |
17 | |
18 import org.apache.log4j.Logger; | |
19 | |
20 /** | |
21 * @author Sascha L. Teichmann (sascha.teichmann@intevation.de) | |
22 */ | |
23 public class AreaInterpolation | |
24 implements Serializable | |
25 { | |
26 private static Logger log = Logger.getLogger(AreaInterpolation.class); | |
27 | |
28 protected double [] raster; | |
29 | |
30 protected int width; | |
31 protected int height; | |
32 | |
33 public AreaInterpolation() { | |
34 } | |
35 | |
36 public int getWidth() { | |
37 return width; | |
38 } | |
39 | |
40 public int getHeight() { | |
41 return height; | |
42 } | |
43 | |
44 public double [] getRaster() { | |
45 return raster; | |
46 } | |
47 | |
48 public boolean interpolate( | |
49 List<? extends Point2d> points, | |
50 Envelope boundingBox, | |
51 Dimension samples, | |
52 XYDepth depth | |
53 ) { | |
54 if (points == null || points.isEmpty()) { | |
55 return false; | |
56 } | |
57 | |
58 double [] buffer = Interpolation2D.calculateBuffer(points); | |
59 double dxMax = buffer[0]; | |
60 double dyMax = buffer[1]; | |
61 | |
62 Quadtree spatialIndex = new Quadtree(); | |
63 | |
64 for (int i = points.size()-1; i >= 0; --i) { | |
65 Point2d p = points.get(i); | |
66 spatialIndex.insert(p.envelope(), p); | |
67 } | |
68 | |
69 int W = samples.width; | |
70 int H = samples.height; | |
71 | |
72 double cellWidth = boundingBox.getWidth() / W; | |
73 double cellHeight = boundingBox.getHeight() / H; | |
74 | |
75 Envelope queryBuffer = new Envelope(); | |
76 Point2d [] neighbors = new Point2d[4]; | |
77 Coordinate center = new Coordinate(); | |
78 L1Comparator invL1 = new L1Comparator(center); | |
79 | |
80 double [] raster = new double[W*H]; | |
81 Arrays.fill(raster, Double.NaN); | |
82 | |
83 int row = 0; | |
84 for (int j = 0; j < H; ++j, row += W) { | |
85 double y = j*cellHeight + 0.5d*cellHeight; | |
86 double x = 0.5d*cellWidth; | |
87 for (int i = 0; i < W; ++i, x += cellWidth) { | |
88 queryBuffer.init( | |
89 x - dxMax, x + dxMax, | |
90 y - dyMax, y + dyMax); | |
91 | |
92 List potential = spatialIndex.query(queryBuffer); | |
93 | |
94 if (potential.isEmpty()) { | |
95 continue; | |
96 } | |
97 | |
98 center.x = x; center.y = y; | |
99 Collections.sort(potential, invL1); | |
100 | |
101 neighbors[0] = neighbors[1] = | |
102 neighbors[2] = neighbors[3] = null; | |
103 | |
104 int mask = 0; | |
105 // reversed order is essential here! | |
106 for (int k = potential.size()-1; k >= 0; --k) { | |
107 Point2d n = (Point2d)potential.get(k); | |
108 int code = n.x > center.x ? 1 : 0; | |
109 if (n.y > center.y) code |= 2; | |
110 neighbors[code] = n; | |
111 mask |= 1 << code; | |
112 } | |
113 | |
114 int numNeighbors = Integer.bitCount(mask); | |
115 | |
116 // only interpolate if we have all four neighbors | |
117 // we do not have any gaps and we are below surface. | |
118 if (numNeighbors == 4 | |
119 && !neighbors[0].hasIGap(neighbors[1]) | |
120 && !neighbors[1].hasJGap(neighbors[3]) | |
121 && !neighbors[3].hasIGap(neighbors[2]) | |
122 && !neighbors[2].hasJGap(neighbors[0]) | |
123 && depth.depth(center) <= 0d | |
124 ) { | |
125 double z1 = Interpolation2D.interpolate( | |
126 neighbors[0].x, neighbors[0].z, | |
127 neighbors[1].x, neighbors[1].z, | |
128 center.x); | |
129 double z2 = Interpolation2D.interpolate( | |
130 neighbors[2].x, neighbors[2].z, | |
131 neighbors[3].x, neighbors[3].z, | |
132 center.x); | |
133 double y1 = Interpolation2D.interpolate( | |
134 neighbors[0].x, neighbors[0].y, | |
135 neighbors[1].x, neighbors[1].y, | |
136 center.x); | |
137 double y2 = Interpolation2D.interpolate( | |
138 neighbors[2].x, neighbors[2].y, | |
139 neighbors[3].x, neighbors[3].y, | |
140 center.x); | |
141 raster[row+i] = Interpolation2D.interpolate( | |
142 y1, z1, | |
143 y2, z2, | |
144 center.y); | |
145 } | |
146 } | |
147 } | |
148 | |
149 this.raster = raster; | |
150 this.width = W; | |
151 this.height = H; | |
152 | |
153 return true; | |
154 } | |
155 } | |
156 // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 : |