root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / morphometry / curvatures / CurvaturesAlgorithm.java @ 59
History | View | Annotate | Download (11.4 KB)
1 |
package es.unex.sextante.morphometry.curvatures; |
---|---|
2 |
|
3 |
import es.unex.sextante.core.GeoAlgorithm; |
4 |
import es.unex.sextante.core.AnalysisExtent; |
5 |
import es.unex.sextante.core.Sextante; |
6 |
import es.unex.sextante.dataObjects.IRasterLayer; |
7 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
8 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
9 |
|
10 |
public class CurvaturesAlgorithm |
11 |
extends
|
12 |
GeoAlgorithm { |
13 |
|
14 |
private final static double PLAN_THRESHOLD = 0.00001; |
15 |
private final static int m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; |
16 |
private final static int m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 }; |
17 |
|
18 |
public static final String METHOD = "METHOD"; |
19 |
public static final String DEM = "DEM"; |
20 |
public static final String HORZ = "HORZ"; |
21 |
public static final String VERT = "VERT"; |
22 |
public static final String GLOBAL = "GLOBAL"; |
23 |
public static final String CLASS = "CLASS"; |
24 |
|
25 |
IRasterLayer m_DEM = null;
|
26 |
IRasterLayer m_Curv; |
27 |
IRasterLayer m_hCurv; |
28 |
IRasterLayer m_vCurv; |
29 |
IRasterLayer m_CurvClass; |
30 |
|
31 |
private double _6DX; |
32 |
private double _2DX; |
33 |
private double _4_DX2; |
34 |
private double _DX2; |
35 |
|
36 |
|
37 |
@Override
|
38 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
39 |
|
40 |
int x, y;
|
41 |
int iNX, iNY;
|
42 |
|
43 |
final int iMethod = m_Parameters.getParameterValueAsInt(METHOD); |
44 |
m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM); |
45 |
|
46 |
m_hCurv = getNewRasterLayer(HORZ, Sextante.getText("Horizontal_curvature"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
|
47 |
m_vCurv = getNewRasterLayer(VERT, Sextante.getText("Vertical_curvature"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
|
48 |
m_Curv = getNewRasterLayer(GLOBAL, Sextante.getText("Curvature"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
|
49 |
m_CurvClass = getNewRasterLayer(CLASS, Sextante.getText("Classification"), IRasterLayer.RASTER_DATA_TYPE_SHORT);
|
50 |
final AnalysisExtent extent = m_hCurv.getWindowGridExtent();
|
51 |
|
52 |
m_DEM.setWindowExtent(extent); |
53 |
|
54 |
iNX = m_DEM.getNX(); |
55 |
iNY = m_DEM.getNY(); |
56 |
|
57 |
_2DX = m_DEM.getWindowCellSize() * 2.;
|
58 |
_DX2 = m_DEM.getWindowCellSize() * m_DEM.getWindowCellSize(); |
59 |
_4_DX2 = 4 * m_DEM.getWindowCellSize() * m_DEM.getWindowCellSize();
|
60 |
_6DX = m_DEM.getWindowCellSize() * 6.;
|
61 |
|
62 |
for (y = 0; (y < iNY) && setProgress(y, iNY); y++) { |
63 |
for (x = 0; x < iNX; x++) { |
64 |
switch (iMethod) {
|
65 |
case 0: |
66 |
Do_FD_BRM(x, y); |
67 |
break;
|
68 |
|
69 |
case 1: |
70 |
Do_FD_Heerdegen(x, y); |
71 |
break;
|
72 |
|
73 |
case 2: |
74 |
Do_FD_Zevenbergen(x, y); |
75 |
break;
|
76 |
|
77 |
case 3: |
78 |
Do_FD_Haralick(x, y); |
79 |
break;
|
80 |
} |
81 |
} |
82 |
} |
83 |
|
84 |
return !m_Task.isCanceled();
|
85 |
|
86 |
} |
87 |
|
88 |
|
89 |
@Override
|
90 |
public void defineCharacteristics() { |
91 |
|
92 |
final String[] sMethod = { Sextante.getText("Fit_2_Degree_Polynom__Bauer_Rohdenburg_Bork_1985"), |
93 |
Sextante.getText("Fit_2_Degree_Polynom__Heerdegen_&_Beran_1982"),
|
94 |
Sextante.getText("Fit_2_Degree_Polynom__Zevenbergen_&_Thorne_1987"),
|
95 |
Sextante.getText("Fit_3_Degree_Polynom__Haralick_1983") };
|
96 |
|
97 |
setName(Sextante.getText("Curvatures"));
|
98 |
setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
|
99 |
setUserCanDefineAnalysisExtent(true);
|
100 |
|
101 |
try {
|
102 |
m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true); |
103 |
m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
|
104 |
addOutputRasterLayer(HORZ, Sextante.getText("Horizontal_curvature"));
|
105 |
addOutputRasterLayer(VERT, Sextante.getText("Vertical_curvature"));
|
106 |
addOutputRasterLayer(GLOBAL, Sextante.getText("Curvature"));
|
107 |
addOutputRasterLayer(CLASS, Sextante.getText("Classification"));
|
108 |
} |
109 |
catch (final RepeatedParameterNameException e) { |
110 |
Sextante.addErrorToLog(e); |
111 |
} |
112 |
|
113 |
} |
114 |
|
115 |
|
116 |
private void Do_FD_BRM(final int x, |
117 |
final int y) { |
118 |
|
119 |
double zm[], D, E, F, G, H; |
120 |
|
121 |
zm = new double[9]; |
122 |
|
123 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
124 |
D = ((zm[0] + zm[2] + zm[3] + zm[5] + zm[6] + zm[8]) - 2 * (zm[1] + zm[4] + zm[7])) / _DX2; |
125 |
E = ((zm[0] + zm[6] + zm[1] + zm[7] + zm[2] + zm[8]) - 2 * (zm[3] + zm[4] + zm[5])) / _DX2; |
126 |
F = (zm[8] + zm[0] - zm[7]) / _4_DX2; |
127 |
G = ((zm[2] - zm[0]) + (zm[5] - zm[3]) + (zm[8] - zm[6])) / _6DX; |
128 |
H = ((zm[6] - zm[0]) + (zm[7] - zm[1]) + (zm[8] - zm[2])) / _6DX; |
129 |
|
130 |
Set_Parameters_Derive(x, y, D, E, F, G, H); |
131 |
} |
132 |
} |
133 |
|
134 |
|
135 |
private void Do_FD_Heerdegen(final int x, |
136 |
final int y) { |
137 |
|
138 |
double zm[], a, b, D, E, F, G, H; |
139 |
|
140 |
zm = new double[9]; |
141 |
|
142 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
143 |
a = zm[0] + zm[2] + zm[3] + zm[5] + zm[6] + zm[8]; |
144 |
b = zm[0] + zm[1] + zm[2] + zm[6] + zm[7] + zm[8]; |
145 |
D = (0.3 * a - 0.2 * b) / _DX2; |
146 |
E = (0.3 * b - 0.2 * a) / _DX2; |
147 |
F = (zm[0] - zm[2] - zm[6] + zm[8]) / _4_DX2; |
148 |
G = (-zm[0] + zm[2] - zm[3] + zm[5] - zm[6] + zm[8]) / _6DX; |
149 |
H = (-zm[0] - zm[1] - zm[2] + zm[6] + zm[7] + zm[8]) / _6DX; |
150 |
|
151 |
Set_Parameters_Derive(x, y, D, E, F, G, H); |
152 |
} |
153 |
} |
154 |
|
155 |
|
156 |
private void Do_FD_Zevenbergen(final int x, |
157 |
final int y) { |
158 |
|
159 |
double zm[], D, E, F, G, H; |
160 |
|
161 |
zm = new double[9]; |
162 |
|
163 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
164 |
|
165 |
D = ((zm[3] + zm[5]) / 2.0 - zm[4]) / _DX2; |
166 |
E = ((zm[1] + zm[7]) / 2.0 - zm[4]) / _DX2; |
167 |
F = (zm[0] - zm[2] - zm[6] + zm[8]) / _4_DX2; |
168 |
G = (zm[5] - zm[3]) / _2DX; |
169 |
H = (zm[7] - zm[1]) / _2DX; |
170 |
|
171 |
Set_Parameters_Derive(x, y, D, E, F, G, H); |
172 |
} |
173 |
} |
174 |
|
175 |
|
176 |
private void Do_FD_Haralick(final int x, |
177 |
final int y) { |
178 |
|
179 |
final int Mtrx[][][] = { |
180 |
{ { 31, -5, -17, -5, 31 }, { -44, -62, -68, -62, -44 }, { 0, 0, 0, 0, 0 }, { 44, 62, 68, 62, 44 }, |
181 |
{ -31, 5, 17, 5, -31 } }, |
182 |
{ { 31, -44, 0, 44, -31 }, { -5, -62, 0, 62, 5 }, { -17, -68, 0, 68, 17 }, { -5, -62, 0, 62, 5 }, |
183 |
{ 31, -44, 0, 44, -31 } }, |
184 |
{ { 2, 2, 2, 2, 2 }, { -1, -1, -1, -1, -1 }, { -2, -2, -2, -2, -2 }, { -1, -1, -1, -1, -1 }, { 2, 2, 2, 2, 2 } }, |
185 |
{ { 4, 2, 0, -2, -4 }, { 2, 1, 0, -1, -2 }, { 0, 0, 0, 0, 0 }, { -2, -1, 0, 1, 2 }, { -4, -2, 0, 2, 4 } }, |
186 |
{ { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 } } }; |
187 |
|
188 |
final int QMtrx[] = { 4200, 4200, 700, 1000, 700 }; |
189 |
|
190 |
int i, ix, iy, n;
|
191 |
double Sum, zm[], k[]; |
192 |
|
193 |
zm = new double[25]; |
194 |
k = new double[5]; |
195 |
|
196 |
if (Get_SubMatrix5x5(x, y, zm)) {
|
197 |
for (i = 0; i < 5; i++) { |
198 |
for (n = 0, Sum = 0.0, iy = 0; iy < 5; iy++) { |
199 |
for (ix = 0; ix < 5; ix++, n++) { |
200 |
Sum += zm[n] * Mtrx[i][ix][iy]; |
201 |
} |
202 |
} |
203 |
|
204 |
k[i] = Sum / QMtrx[i]; |
205 |
} |
206 |
|
207 |
Set_Parameters_Derive(x, y, k[4], k[2], k[3], k[1], k[0]); |
208 |
} |
209 |
} |
210 |
|
211 |
|
212 |
// additional methods
|
213 |
|
214 |
private void Set_Parameters(final int x, |
215 |
final int y, |
216 |
final double dCurv, |
217 |
final double dHCurv, |
218 |
final double dVCurv) { |
219 |
|
220 |
int iClass;
|
221 |
|
222 |
m_Curv.setCellValue(x, y, dCurv); |
223 |
m_hCurv.setCellValue(x, y, dHCurv); |
224 |
m_vCurv.setCellValue(x, y, dVCurv); |
225 |
|
226 |
|
227 |
iClass = dHCurv < -PLAN_THRESHOLD ? 0 : (dHCurv <= PLAN_THRESHOLD ? 3 : 6); |
228 |
iClass += dVCurv < -PLAN_THRESHOLD ? 0 : (dVCurv <= PLAN_THRESHOLD ? 1 : 2); |
229 |
|
230 |
m_CurvClass.setCellValue(x, y, iClass); |
231 |
|
232 |
} |
233 |
|
234 |
|
235 |
private void Set_Parameters_Derive(final int x, |
236 |
final int y, |
237 |
final double D, |
238 |
final double E, |
239 |
final double F, |
240 |
final double G, |
241 |
final double H) { |
242 |
|
243 |
double k1, k2, Curv, vCurv, hCurv;
|
244 |
|
245 |
k1 = F * G * H; |
246 |
k2 = G * G + H * H; |
247 |
|
248 |
if (k2 != 0) { |
249 |
Curv = -2.0 * (E + D);
|
250 |
vCurv = -2.0 * (D * G * G + E * H * H + k1) / k2;
|
251 |
hCurv = -2.0 * (D * H * H + E * G * G - k1) / k2;
|
252 |
|
253 |
} |
254 |
else {
|
255 |
Curv = vCurv = hCurv = 0.0;
|
256 |
} |
257 |
|
258 |
Set_Parameters(x, y, Curv, hCurv, vCurv); |
259 |
} |
260 |
|
261 |
|
262 |
private void Set_Parameters_NoData(final int x, |
263 |
final int y) { |
264 |
|
265 |
m_Curv.setNoData(x, y); |
266 |
m_hCurv.setNoData(x, y); |
267 |
m_vCurv.setNoData(x, y); |
268 |
|
269 |
} |
270 |
|
271 |
|
272 |
// ---------------------------------------------------------
|
273 |
// Indexing of the Submatrix:
|
274 |
//
|
275 |
// +-------+ +-------+
|
276 |
// | 7 0 1 | | 2 5 8 |
|
277 |
// | 6 * 2 | => | 1 4 7 |
|
278 |
// | 5 4 3 | | 0 3 6 |
|
279 |
// +-------+ +-------+
|
280 |
//
|
281 |
// ---------------------------------------------------------
|
282 |
private boolean Get_SubMatrix3x3(final int x, |
283 |
final int y, |
284 |
final double SubMatrix[]) { |
285 |
|
286 |
final int iSub[] = { 5, 8, 7, 6, 3, 0, 1, 2 }; |
287 |
|
288 |
int i;
|
289 |
double z, z2;
|
290 |
|
291 |
z = m_DEM.getCellValueAsDouble(x, y); |
292 |
|
293 |
if (m_DEM.isNoDataValue(z)) {
|
294 |
Set_Parameters_NoData(x, y); |
295 |
} |
296 |
else {
|
297 |
SubMatrix[4] = 0.0; |
298 |
for (i = 0; i < 8; i++) { |
299 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]); |
300 |
if (!m_DEM.isNoDataValue(z2)) {
|
301 |
SubMatrix[iSub[i]] = z2 - z; |
302 |
} |
303 |
else {
|
304 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetY[(i + 4) % 8], y + m_iOffsetY[(i + 4) % 8]); |
305 |
if (!m_DEM.isNoDataValue(z2)) {
|
306 |
SubMatrix[iSub[i]] = z - z2; |
307 |
} |
308 |
else {
|
309 |
SubMatrix[iSub[i]] = 0.0;
|
310 |
} |
311 |
} |
312 |
} |
313 |
|
314 |
return (true); |
315 |
} |
316 |
|
317 |
return (false); |
318 |
} |
319 |
|
320 |
|
321 |
private boolean Get_SubMatrix5x5(final int x, |
322 |
final int y, |
323 |
final double SubMatrix[]) { |
324 |
int i, ix, iy, jx, jy;
|
325 |
double z, z2;
|
326 |
|
327 |
z = m_DEM.getCellValueAsDouble(x, y); |
328 |
|
329 |
if (!m_DEM.isNoDataValue(z)) {
|
330 |
for (i = 0, iy = y - 2; iy <= y + 2; iy++) { |
331 |
jy = iy < 0 ? 0 : (iy >= m_DEM.getNY() ? m_DEM.getNY() - 1 : iy); |
332 |
for (ix = x - 2; ix <= x + 2; ix++, i++) { |
333 |
jx = ix < 0 ? 0 : (ix >= m_DEM.getNX() ? m_DEM.getNY() - 1 : ix); |
334 |
z2 = m_DEM.getCellValueAsDouble(jx, jy); |
335 |
if (!m_DEM.isNoDataValue(z2)) {
|
336 |
SubMatrix[i] = z2 - z; |
337 |
} |
338 |
else {
|
339 |
SubMatrix[i] = 0.0;
|
340 |
} |
341 |
} |
342 |
} |
343 |
|
344 |
return (true); |
345 |
} |
346 |
|
347 |
return (false); |
348 |
} |
349 |
|
350 |
|
351 |
} |