Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / morphometry / aspect / AspectAlgorithm.java @ 59

History | View | Annotate | Download (14.4 KB)

1
package es.unex.sextante.morphometry.aspect;
2

    
3

    
4
import es.unex.sextante.core.GeoAlgorithm;
5
import es.unex.sextante.core.AnalysisExtent;
6
import es.unex.sextante.core.Sextante;
7
import es.unex.sextante.dataObjects.IRasterLayer;
8
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
9
import es.unex.sextante.exceptions.RepeatedParameterNameException;
10

    
11
public class AspectAlgorithm
12
         extends
13
            GeoAlgorithm {
14

    
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  ASPECT               = "ASPECT";
19
   public static final String  METHOD               = "METHOD";
20
   public static final String  UNITS                = "UNITS";
21
   public static final String  DEM                  = "DEM";
22

    
23
   public final static int     UNITS_RADIANS        = 0;
24
   public final static int     UNITS_DEGREES        = 1;
25
   public final static int     UNITS_PERCENTAGE     = 2;
26

    
27
   public final static int     METHOD_MAXIMUM_SLOPE = 0;
28
   public final static int     METHOD_TARBOTON      = 1;
29
   public final static int     METHOD_BURGESS       = 2;
30
   public final static int     METHOD_BAUER         = 3;
31
   public final static int     METHOD_HEERDEGEN     = 4;
32
   public final static int     METHOD_ZEVENBERGEN   = 5;
33
   public final static int     METHOD_HARALICK      = 6;
34

    
35
   private static final double DEG_45_IN_RAD        = Math.toRadians(45);
36
   private static final double DEG_90_IN_RAD        = Math.toRadians(90);
37
   private static final double DEG_180_IN_RAD       = Math.toRadians(180);
38
   private static final double DEG_270_IN_RAD       = Math.toRadians(270);
39

    
40
   IRasterLayer                m_DEM                = null;
41
   IRasterLayer                m_Aspect;
42

    
43
   private double              _6DX;
44
   private double              _2DX;
45

    
46
   private int                 m_iUnits;
47

    
48

    
49
   @Override
50
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
51

    
52
      int x, y;
53
      int iNX, iNY;
54

    
55
      final int iMethod = m_Parameters.getParameterValueAsInt(METHOD);
56

    
57
      m_iUnits = m_Parameters.getParameterValueAsInt(UNITS);
58

    
59
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
60

    
61
      m_Aspect = getNewRasterLayer(ASPECT, Sextante.getText("Aspect"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
62

    
63
      final AnalysisExtent extent = m_Aspect.getWindowGridExtent();
64

    
65
      m_DEM.setWindowExtent(extent);
66

    
67
      iNX = m_DEM.getNX();
68
      iNY = m_DEM.getNY();
69

    
70
      _2DX = m_DEM.getWindowCellSize() * 2.;
71
      _6DX = m_DEM.getWindowCellSize() * 6.;
72

    
73
      for (y = 0; (y < iNY) && setProgress(y, iNY); y++) {
74
         for (x = 0; x < iNX; x++) {
75
            switch (iMethod) {
76
               case 0:
77
                  Do_MaximumSlope(x, y);
78
                  break;
79

    
80
               case 1:
81
                  Do_Tarboton(x, y);
82
                  break;
83

    
84
               case 2:
85
                  Do_LeastSquare(x, y);
86
                  break;
87

    
88
               case 3:
89
                  Do_FD_BRM(x, y);
90
                  break;
91

    
92
               case 4:
93
                  Do_FD_Heerdegen(x, y);
94
                  break;
95

    
96
               case 5:
97
                  Do_FD_Zevenbergen(x, y);
98
                  break;
99

    
100
               case 6:
101
                  Do_FD_Haralick(x, y);
102
                  break;
103
            }
104
         }
105
      }
106

    
107
      return !m_Task.isCanceled();
108

    
109
   }
110

    
111

    
112
   @Override
113
   public void defineCharacteristics() {
114

    
115
      final String[] sMethod = { Sextante.getText("M\u00e1ximum_slope__Travis_et_al_1975"),
116
               Sextante.getText("Maximum_Triangle_Slope__Tarboton_1997"),
117
               Sextante.getText("Plane_fitting__Costa-Cabral_&_Burgess_1996"),
118
               Sextante.getText("Fit_2_Degree_Polynom__Bauer_Rohdenburg_Bork_1985"),
119
               Sextante.getText("Fit_2_Degree_Polynom__Heerdegen_&_Beran_1982"),
120
               Sextante.getText("Fit_2_Degree_Polynom__Zevenbergen_&_Thorne_1987"),
121
               Sextante.getText("Fit_3_Degree_Polynom__Haralick_1983") };
122

    
123
      final String[] sUnits = { Sextante.getText("Radians"), Sextante.getText("Degrees") };
124

    
125
      setName(Sextante.getText("Aspect"));
126
      setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
127
      setUserCanDefineAnalysisExtent(true);
128

    
129
      try {
130
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
131

    
132
         m_Parameters.addSelection(UNITS, Sextante.getText("Units"), sUnits);
133

    
134
         m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
135
         addOutputRasterLayer(ASPECT, Sextante.getText("Aspect"));
136
      }
137
      catch (final RepeatedParameterNameException e) {
138
         Sextante.addErrorToLog(e);
139
      }
140

    
141
   }
142

    
143

    
144
   private void Do_MaximumSlope(final int x,
145
                                final int y) {
146

    
147
      int i, Aspect;
148
      double z, z2, dSlope, dMaxSlope;
149

    
150
      z = m_DEM.getCellValueAsDouble(x, y);
151

    
152
      if (m_DEM.isNoDataValue(z)) {
153
         Set_Parameters_NoData(x, y);
154
      }
155
      else {
156
         dMaxSlope = 0.0;
157
         for (Aspect = -1, i = 0; i < 8; i++) {
158
            z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
159
            if (!m_DEM.isNoDataValue(z2)) {
160
               dSlope = Math.atan((z - z2) / m_DEM.getDistToNeighborInDir(i));
161
               if (dSlope > dMaxSlope) {
162
                  Aspect = i;
163
                  dMaxSlope = dSlope;
164
               }
165
            }
166
         }
167

    
168
         if (Aspect < 0.0) {
169
            Set_Parameters_NoData(x, y);
170
         }
171
         else {
172
            Set_Parameters(x, y, Aspect * DEG_45_IN_RAD);
173
         }
174
      }
175
   }
176

    
177

    
178
   private void Do_Tarboton(final int x,
179
                            final int y) {
180

    
181
      int i, j;
182
      double z, z2, zm[], iSlope, iAspect, Slope, Aspect, G, H;
183

    
184
      zm = new double[8];
185

    
186
      z = m_DEM.getCellValueAsDouble(x, y);
187

    
188
      if (m_DEM.isNoDataValue(z)) {
189
         Set_Parameters_NoData(x, y);
190
      }
191
      else {
192
         for (i = 0; i < 8; i++) {
193

    
194
            z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
195
            if (!m_DEM.isNoDataValue(z2)) {
196
               zm[i] = z2;
197
            }
198
            else {
199
               z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[(i + 4) % 8], y + m_iOffsetY[(i + 4) % 8]);
200
               if (!m_DEM.isNoDataValue(z2)) {
201
                  zm[i] = z - (z2 - z);
202
               }
203
               else {
204
                  zm[i] = z;
205
               }
206
            }
207
         }
208

    
209
         Slope = 0.0;
210
         Aspect = -1.0;
211

    
212
         for (i = 0, j = 1; i < 8; i++, j = (j + 1) % 8) {
213
            if ((i % 2) != 0) // i => diagonal
214
            {
215
               G = (z - zm[j]) / m_DEM.getWindowCellSize();
216
               H = (zm[j] - zm[i]) / m_DEM.getWindowCellSize();
217
            }
218
            else // i => orthogonal
219
            {
220
               G = (z - zm[i]) / m_DEM.getWindowCellSize();
221
               H = (zm[i] - zm[j]) / m_DEM.getWindowCellSize();
222
            }
223

    
224
            if (H < 0.0) {
225
               iAspect = 0.0;
226
               iSlope = G;
227
            }
228
            else if (H > G) {
229
               iAspect = DEG_45_IN_RAD;
230
               iSlope = (z - zm[((i % 2) != 0) ? i : j]) / (Math.sqrt(2.0) * m_DEM.getWindowCellSize());
231
            }
232
            else {
233
               iAspect = Math.atan(H / G);
234
               iSlope = Math.sqrt(G * G + H * H);
235
            }
236

    
237
            if (iSlope > Slope) {
238
               Aspect = i * DEG_45_IN_RAD + (((i % 2) != 0) ? DEG_45_IN_RAD - iAspect : iAspect);
239
               Slope = iSlope;
240
            }
241
         }
242

    
243
         if (Aspect < 0.0) {
244
            Set_Parameters_NoData(x, y);
245
         }
246
         else {
247
            Set_Parameters(x, y, Aspect);
248
         }
249
      }
250
   }
251

    
252

    
253
   private void Do_LeastSquare(final int x,
254
                               final int y) {
255

    
256
      double zm[], a, b;
257

    
258
      zm = new double[9];
259

    
260
      if (Get_SubMatrix3x3(x, y, zm)) {
261
         a = ((zm[2] + 2 * zm[5] + zm[8]) - (zm[0] + 2 * zm[3] + zm[6])) / (8 * m_DEM.getWindowCellSize());
262
         b = ((zm[6] + 2 * zm[7] + zm[8]) - (zm[0] + 2 * zm[1] + zm[2])) / (8 * m_DEM.getWindowCellSize());
263

    
264
         if (a != 0.0) {
265
            Set_Parameters(x, y, DEG_180_IN_RAD + Math.atan2(b, a));
266
         }
267
         else if (b > 0.0) {
268
            Set_Parameters(x, y, DEG_270_IN_RAD);
269
         }
270
         else if (b < 0.0) {
271
            Set_Parameters(x, y, DEG_90_IN_RAD);
272
         }
273
         else {
274
            Set_Parameters_NoData(x, y);
275
         }
276
      }
277
   }
278

    
279

    
280
   private void Do_FD_BRM(final int x,
281
                          final int y) {
282

    
283
      double zm[], G, H;
284

    
285
      zm = new double[9];
286

    
287
      if (Get_SubMatrix3x3(x, y, zm)) {
288
         G = ((zm[2] - zm[0]) + (zm[5] - zm[3]) + (zm[8] - zm[6])) / _6DX;
289
         H = ((zm[6] - zm[0]) + (zm[7] - zm[1]) + (zm[8] - zm[2])) / _6DX;
290
         Set_Parameters_Derive(x, y, G, H);
291
      }
292
   }
293

    
294

    
295
   private void Do_FD_Heerdegen(final int x,
296
                                final int y) {
297

    
298
      double zm[], G, H;
299

    
300
      zm = new double[9];
301

    
302
      if (Get_SubMatrix3x3(x, y, zm)) {
303
         G = (-zm[0] + zm[2] - zm[3] + zm[5] - zm[6] + zm[8]) / _6DX;
304
         H = (-zm[0] - zm[1] - zm[2] + zm[6] + zm[7] + zm[8]) / _6DX;
305
         Set_Parameters_Derive(x, y, G, H);
306
      }
307
   }
308

    
309

    
310
   private void Do_FD_Zevenbergen(final int x,
311
                                  final int y) {
312

    
313
      double zm[], G, H;
314

    
315
      zm = new double[9];
316

    
317
      if (Get_SubMatrix3x3(x, y, zm)) {
318
         G = (zm[5] - zm[3]) / _2DX;
319
         H = (zm[7] - zm[1]) / _2DX;
320
         Set_Parameters_Derive(x, y, G, H);
321
      }
322
   }
323

    
324

    
325
   private void Do_FD_Haralick(final int x,
326
                               final int y) {
327

    
328
      final int Mtrx[][][] = {
329
               { { 31, -5, -17, -5, 31 }, { -44, -62, -68, -62, -44 }, { 0, 0, 0, 0, 0 }, { 44, 62, 68, 62, 44 },
330
                        { -31, 5, 17, 5, -31 } },
331
               { { 31, -44, 0, 44, -31 }, { -5, -62, 0, 62, 5 }, { -17, -68, 0, 68, 17 }, { -5, -62, 0, 62, 5 },
332
                        { 31, -44, 0, 44, -31 } },
333
               { { 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 } },
334
               { { 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 } },
335
               { { 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 } } };
336

    
337
      final int QMtrx[] = { 4200, 4200, 700, 1000, 700 };
338

    
339
      int i, ix, iy, n;
340
      double Sum, zm[], k[];
341

    
342
      zm = new double[25];
343
      k = new double[2];
344

    
345
      if (Get_SubMatrix5x5(x, y, zm)) {
346
         for (i = 0; i < 2; i++) {
347
            for (n = 0, Sum = 0.0, iy = 0; iy < 5; iy++) {
348
               for (ix = 0; ix < 5; ix++, n++) {
349
                  Sum += zm[n] * Mtrx[i][ix][iy];
350
               }
351
            }
352

    
353
            k[i] = Sum / QMtrx[i];
354
         }
355

    
356
         Set_Parameters_Derive(x, y, k[1], k[0]);
357
      }
358
   }
359

    
360

    
361
   //        additional methods
362

    
363
   private void Set_Parameters(final int x,
364
                               final int y,
365
                               double dAspect) {
366

    
367
      if (m_iUnits == UNITS_DEGREES) {
368
         dAspect = Math.toDegrees(dAspect);
369
      }
370

    
371
      m_Aspect.setCellValue(x, y, dAspect);
372

    
373
   }
374

    
375

    
376
   private void Set_Parameters_Derive(final int x,
377
                                      final int y,
378
                                      final double G,
379
                                      final double H) {
380

    
381
      if (G != 0.0) {
382
         Set_Parameters(x, y, DEG_180_IN_RAD + Math.atan2(H, G));
383
      }
384
      else if (H > 0.0) {
385
         Set_Parameters(x, y, DEG_270_IN_RAD);
386
      }
387
      else if (H < 0.0) {
388
         Set_Parameters(x, y, DEG_90_IN_RAD);
389
      }
390
      else {
391
         m_Aspect.setNoData(x, y);
392
      }
393
   }
394

    
395

    
396
   private void Set_Parameters_NoData(final int x,
397
                                      final int y) {
398

    
399
      m_Aspect.setNoData(x, y);
400

    
401
   }
402

    
403

    
404
   //        ---------------------------------------------------------
405
   //        Indexing of the Submatrix:
406
   //
407
   //        +-------+    +-------+
408
   //        | 7 0 1 |    | 2 5 8 |
409
   //        | 6 * 2 | => | 1 4 7 |
410
   //        | 5 4 3 |    | 0 3 6 |
411
   //        +-------+    +-------+
412
   //
413
   //        ---------------------------------------------------------
414
   private boolean Get_SubMatrix3x3(final int x,
415
                                    final int y,
416
                                    final double SubMatrix[]) {
417

    
418
      final int iSub[] = { 5, 8, 7, 6, 3, 0, 1, 2 };
419

    
420
      int i;
421
      double z, z2;
422

    
423
      z = m_DEM.getCellValueAsDouble(x, y);
424

    
425
      if (m_DEM.isNoDataValue(z)) {
426
         Set_Parameters_NoData(x, y);
427
      }
428
      else {
429
         SubMatrix[4] = 0.0;
430
         for (i = 0; i < 8; i++) {
431
            z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
432
            if (!m_DEM.isNoDataValue(z2)) {
433
               SubMatrix[iSub[i]] = z2 - z;
434
            }
435
            else {
436
               z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[(i + 4) % 8], y + m_iOffsetY[(i + 4) % 8]);
437
               if (!m_DEM.isNoDataValue(z2)) {
438
                  SubMatrix[iSub[i]] = z - z2;
439
               }
440
               else {
441
                  SubMatrix[iSub[i]] = 0.0;
442
               }
443
            }
444
         }
445

    
446
         return (true);
447
      }
448

    
449
      return (false);
450
   }
451

    
452

    
453
   private boolean Get_SubMatrix5x5(final int x,
454
                                    final int y,
455
                                    final double SubMatrix[]) {
456
      int i, ix, iy, jx, jy;
457
      double z, z2;
458

    
459
      z = m_DEM.getCellValueAsDouble(x, y);
460

    
461
      if (!m_DEM.isNoDataValue(z)) {
462
         for (i = 0, iy = y - 2; iy <= y + 2; iy++) {
463
            jy = iy < 0 ? 0 : (iy >= m_DEM.getNY() ? m_DEM.getNY() - 1 : iy);
464
            for (ix = x - 2; ix <= x + 2; ix++, i++) {
465
               jx = ix < 0 ? 0 : (ix >= m_DEM.getNX() ? m_DEM.getNY() - 1 : ix);
466
               z2 = m_DEM.getCellValueAsDouble(jx, jy);
467
               if (!m_DEM.isNoDataValue(z2)) {
468
                  SubMatrix[i] = z2 - z;
469
               }
470
               else {
471
                  SubMatrix[i] = 0.0;
472
               }
473
            }
474
         }
475

    
476
         return (true);
477
      }
478

    
479
      return (false);
480
   }
481

    
482
}