Statistics
| Revision:

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

History | View | Annotate | Download (9.82 KB)

1

    
2

    
3
package es.unex.sextante.morphometry.anisotropicCoefficientOfVariation;
4

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

    
13

    
14
public class ACVAlgorithm
15
         extends
16
            GeoAlgorithm {
17

    
18
   private double             NO_DATA;
19

    
20
   public static final String DEM     = "DEM";
21
   public static final String RESULT  = "RESULT";
22

    
23
   IRasterLayer               m_ACV;
24
   IRasterLayer               m_DEM;
25
   IRasterLayer               m_DX, m_DY, m_DUp, m_DDown;
26
   int                        m_iNX, m_iNY;
27

    
28
   int                        m_iSize = 5;
29

    
30

    
31
   @Override
32
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
33

    
34
      int x, y;
35

    
36
      NO_DATA = m_OutputFactory.getDefaultNoDataValue();
37

    
38
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
39
      m_ACV = getNewRasterLayer(RESULT, Sextante.getText("Anisotropic_coefficient_of_variation"),
40
               IRasterLayer.RASTER_DATA_TYPE_FLOAT);
41

    
42
      final AnalysisExtent extent = m_ACV.getWindowGridExtent();
43

    
44
      m_DX = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, extent);
45
      m_DY = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, extent);
46
      m_DDown = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, extent);
47
      m_DUp = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, extent);
48

    
49
      m_DEM.setWindowExtent(extent);
50

    
51
      m_iNX = m_DEM.getNX();
52
      m_iNY = m_DEM.getNY();
53

    
54
      m_ACV.setNoDataValue(NO_DATA);
55

    
56
      calculateDerivatives();
57

    
58
      setProgressText(Sextante.getText("Calculating_coefficient") + "...");
59

    
60
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
61
         for (x = 0; x < m_iNX; x++) {
62
            m_ACV.setCellValue(x, y, getACV(x, y));
63
         }
64
      }
65

    
66
      return !m_Task.isCanceled();
67

    
68
   }
69

    
70

    
71
   @Override
72
   public void defineCharacteristics() {
73

    
74
      setUserCanDefineAnalysisExtent(true);
75
      setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
76
      setName(Sextante.getText("Anisotropic_coefficient_of_variation"));
77

    
78
      try {
79
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
80
         addOutputRasterLayer(RESULT, Sextante.getText("Anisotropic_coefficient_of_variation"));
81
      }
82
      catch (final RepeatedParameterNameException e) {
83
         Sextante.addErrorToLog(e);
84
      }
85

    
86
   }
87

    
88

    
89
   private void calculateDerivatives() throws UnsupportedOutputChannelException {
90

    
91
      int x, y;
92

    
93
      setProgressText(Sextante.getText("Calculating_derivatives") + "...");
94

    
95
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
96
         for (x = 0; x < m_iNX; x++) {
97
            m_DX.setCellValue(x, y, getDFDX(x, y));
98
            m_DY.setCellValue(x, y, getDFDY(x, y));
99
            m_DDown.setCellValue(x, y, getDFDDown(x, y));
100
            m_DUp.setCellValue(x, y, getDFDUp(x, y));
101
         }
102
      }
103
      smooth(m_DX);
104
      smooth(m_DY);
105
      smooth(m_DDown);
106
      smooth(m_DUp);
107

    
108
   }
109

    
110

    
111
   private void smooth(IRasterLayer driver) throws UnsupportedOutputChannelException {
112

    
113
      int i, j;
114
      int x, y;
115
      int iValidCells;
116
      double dSum;
117
      double dValue;
118
      final IRasterLayer temp = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, m_DEM.getWindowGridExtent());
119

    
120
      for (y = 1; y < m_iNY - 1; y++) {
121
         for (x = 1; x < m_iNX - 1; x++) {
122
            dSum = 0;
123
            iValidCells = 0;
124
            for (i = -1; i < 2; i++) {
125
               for (j = -1; j < 2; j++) {
126
                  dValue = driver.getCellValueAsDouble(x + i, y + j);
127
                  if (dValue != NO_DATA) {
128
                     dSum += dValue;
129
                     iValidCells++;
130
                  }
131
               }
132
            }
133
            if (iValidCells != 0) {
134
               temp.setCellValue(x, y, dSum / iValidCells);
135
            }
136
            else {
137
               temp.setNoData(x, y);
138
            }
139
         }
140
      }
141

    
142
      driver = temp;
143

    
144
      System.gc();
145

    
146
   }
147

    
148

    
149
   private double getACV(final int x,
150
                         final int y) {
151

    
152
      final double dX = m_DX.getCellValueAsDouble(x, y);
153
      final double dY = m_DY.getCellValueAsDouble(x, y);
154
      final double dUp = m_DUp.getCellValueAsDouble(x, y);
155
      final double dDown = m_DDown.getCellValueAsDouble(x, y);
156

    
157
      if ((dX == NO_DATA) || (dY == NO_DATA) || (dUp == NO_DATA) || (dDown == NO_DATA)) {
158
         return NO_DATA;
159
      }
160

    
161
      final double dAvg = (dX + dY + dUp + dDown) / 4.;
162
      double dDif = 0;
163
      double dZ;
164

    
165
      if ((dZ = m_DX.getCellValueAsDouble(x, y - 1)) != NO_DATA) {
166
         dDif += Math.pow(dAvg - dZ, 2.);
167
      }
168
      else {
169
         return NO_DATA;
170
      }
171

    
172
      if ((dZ = m_DX.getCellValueAsDouble(x, y + 1)) != NO_DATA) {
173
         dDif += Math.pow(dAvg - dZ, 2.);
174
      }
175
      else {
176
         return NO_DATA;
177
      }
178

    
179
      if ((dZ = m_DY.getCellValueAsDouble(x - 1, y)) != NO_DATA) {
180
         dDif += Math.pow(dAvg - dZ, 2.);
181
      }
182
      else {
183
         return NO_DATA;
184
      }
185

    
186
      if ((dZ = m_DY.getCellValueAsDouble(x + 1, y)) != NO_DATA) {
187
         dDif += Math.pow(dAvg - dZ, 2.);
188
      }
189
      else {
190
         return NO_DATA;
191
      }
192

    
193
      if ((dZ = m_DDown.getCellValueAsDouble(x - 1, y + 1)) != NO_DATA) {
194
         dDif += Math.pow(dAvg - dZ, 2.);
195
      }
196
      else {
197
         return NO_DATA;
198
      }
199
      if ((dZ = m_DDown.getCellValueAsDouble(x + 1, y - 1)) != NO_DATA) {
200
         dDif += Math.pow(dAvg - dZ, 2.);
201
      }
202
      else {
203
         return NO_DATA;
204
      }
205

    
206
      if ((dZ = m_DUp.getCellValueAsDouble(x - 1, y - 1)) != NO_DATA) {
207
         dDif += Math.pow(dAvg - dZ, 2.);
208
      }
209
      else {
210
         return NO_DATA;
211
      }
212

    
213
      if ((dZ = m_DUp.getCellValueAsDouble(x + 1, y + 1)) != NO_DATA) {
214
         dDif += Math.pow(dAvg - dZ, 2.);
215
      }
216
      else {
217
         return NO_DATA;
218
      }
219

    
220
      return Math.log(1 + Math.sqrt(dDif / 8.) / dAvg);
221

    
222
   }
223

    
224

    
225
   private double getDFDX(final int x,
226
                          final int y) {
227

    
228
      double dValue;
229
      final double dValues[] = new double[4];
230

    
231
      dValue = m_DEM.getCellValueAsDouble(x - 2, y);
232
      if (m_DEM.isNoDataValue(dValue)) {
233
         return NO_DATA;
234
      }
235
      dValues[0] = dValue;
236
      dValue = m_DEM.getCellValueAsDouble(x - 1, y);
237
      if (m_DEM.isNoDataValue(dValue)) {
238
         return NO_DATA;
239
      }
240
      dValues[1] = dValue;
241
      dValue = m_DEM.getCellValueAsDouble(x + 1, y);
242
      if (m_DEM.isNoDataValue(dValue)) {
243
         return NO_DATA;
244
      }
245
      dValues[2] = dValue;
246
      dValue = m_DEM.getCellValueAsDouble(x + 2, y);
247
      if (m_DEM.isNoDataValue(dValue)) {
248
         return NO_DATA;
249
      }
250
      dValues[3] = dValue;
251

    
252
      return Math.abs(dValues[0] + dValues[1] * -8 + dValues[2] * 8 + dValues[3] * -1);
253

    
254
   }
255

    
256

    
257
   private double getDFDY(final int x,
258
                          final int y) {
259

    
260
      double dValue;
261
      final double dValues[] = new double[4];
262

    
263
      dValue = m_DEM.getCellValueAsDouble(x, y - 2);
264
      if (m_DEM.isNoDataValue(dValue)) {
265
         return NO_DATA;
266
      }
267
      dValues[0] = dValue;
268
      dValue = m_DEM.getCellValueAsDouble(x, y - 1);
269
      if (m_DEM.isNoDataValue(dValue)) {
270
         return NO_DATA;
271
      }
272
      dValues[1] = dValue;
273
      dValue = m_DEM.getCellValueAsDouble(x, y + 1);
274
      if (m_DEM.isNoDataValue(dValue)) {
275
         return NO_DATA;
276
      }
277
      dValues[2] = dValue;
278
      dValue = m_DEM.getCellValueAsDouble(x, y + 2);
279
      if (m_DEM.isNoDataValue(dValue)) {
280
         return NO_DATA;
281
      }
282
      dValues[3] = dValue;
283

    
284
      return Math.abs(dValues[0] + dValues[1] * -8 + dValues[2] * 8 + dValues[3] * -1);
285

    
286
   }
287

    
288

    
289
   private double getDFDDown(final int x,
290
                             final int y) {
291

    
292
      double dValue;
293
      final double dValues[] = new double[4];
294

    
295
      dValue = m_DEM.getCellValueAsDouble(x - 2, y + 2);
296
      if (m_DEM.isNoDataValue(dValue)) {
297
         return NO_DATA;
298
      }
299
      dValues[0] = dValue;
300
      dValue = m_DEM.getCellValueAsDouble(x - 1, y + 1);
301
      if (m_DEM.isNoDataValue(dValue)) {
302
         return NO_DATA;
303
      }
304
      dValues[1] = dValue;
305
      dValue = m_DEM.getCellValueAsDouble(x + 1, y - 1);
306
      if (m_DEM.isNoDataValue(dValue)) {
307
         return NO_DATA;
308
      }
309
      dValues[2] = dValue;
310
      dValue = m_DEM.getCellValueAsDouble(x + 2, y - 2);
311
      if (m_DEM.isNoDataValue(dValue)) {
312
         return NO_DATA;
313
      }
314
      dValues[3] = dValue;
315

    
316
      return Math.abs(dValues[0] + dValues[1] * -8 + dValues[2] * 8 + dValues[3] * -1);
317

    
318
   }
319

    
320

    
321
   private double getDFDUp(final int x,
322
                           final int y) {
323

    
324
      double dValue;
325
      final double dValues[] = new double[4];
326

    
327
      dValue = m_DEM.getCellValueAsDouble(x - 2, y - 2);
328
      if (m_DEM.isNoDataValue(dValue)) {
329
         return NO_DATA;
330
      }
331
      dValues[0] = dValue;
332
      dValue = m_DEM.getCellValueAsDouble(x - 1, y - 1);
333
      if (m_DEM.isNoDataValue(dValue)) {
334
         return NO_DATA;
335
      }
336
      dValues[1] = dValue;
337
      dValue = m_DEM.getCellValueAsDouble(x + 1, y + 1);
338
      if (m_DEM.isNoDataValue(dValue)) {
339
         return NO_DATA;
340
      }
341
      dValues[2] = dValue;
342
      dValue = m_DEM.getCellValueAsDouble(x + 2, y + 2);
343
      if (m_DEM.isNoDataValue(dValue)) {
344
         return NO_DATA;
345
      }
346
      dValues[3] = dValue;
347

    
348
      return Math.abs(dValues[0] + dValues[1] * -8 + dValues[2] * 8 + dValues[3] * -1);
349

    
350
   }
351

    
352
}