Statistics
| Revision:

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

History | View | Annotate | Download (10.8 KB)

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

    
3
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
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
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
11

    
12
public class SurfaceSpecificPointsAlgorithm
13
         extends
14
            GeoAlgorithm {
15

    
16
   private final static int   m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
17
   private final static int   m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
18

    
19
   public static final String METHOD       = "METHOD";
20
   public static final String DEM          = "DEM";
21
   public static final String THRESHOLD    = "THRESHOLD";
22
   public static final String RESULT       = "RESULT";
23

    
24
   IRasterLayer               m_DEM        = null;
25
   IRasterLayer               m_Result;
26
   double                     m_dThreshold;
27
   int                        m_iNX, m_iNY;
28

    
29

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

    
33
      final int iMethod = m_Parameters.getParameterValueAsInt(METHOD);
34
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
35
      m_dThreshold = m_Parameters.getParameterValueAsDouble(THRESHOLD);
36

    
37
      m_Result = getNewRasterLayer(RESULT, Sextante.getText("Result"), IRasterLayer.RASTER_DATA_TYPE_INT);
38

    
39
      final AnalysisExtent extent = m_Result.getWindowGridExtent();
40

    
41
      m_DEM.setWindowExtent(extent);
42

    
43
      m_iNX = m_DEM.getNX();
44
      m_iNY = m_DEM.getNY();
45

    
46
      switch (iMethod) {
47
         case 0:
48
            doMarkHighestNB();
49
            break;
50
         case 1:
51
            doOppositeNB();
52
            break;
53
         case 2:
54
            doFlowDirection();
55
            break;
56
         case 3:
57
            doPeuckerDouglas();
58
            break;
59
      }
60

    
61
      return !m_Task.isCanceled();
62

    
63
   }
64

    
65

    
66
   @Override
67
   public void defineCharacteristics() {
68

    
69
      final String[] sMethod = { Sextante.getText("Mark_Highest_Neighbour"), Sextante.getText("Opposite_neighbours"),
70
               Sextante.getText("Flow_direction"), Sextante.getText("Peucker_&_Douglas") };
71

    
72
      setUserCanDefineAnalysisExtent(true);
73
      setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
74
      setName(Sextante.getText("Landform_classification"));
75

    
76
      try {
77
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
78
         m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
79
         m_Parameters.addNumericalValue(THRESHOLD, Sextante.getText("Threshold__Peucker_&_Douglas"), 0.01,
80
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
81
         addOutputRasterLayer(RESULT, Sextante.getText("Result"));
82
      }
83
      catch (final RepeatedParameterNameException e) {
84
         Sextante.addErrorToLog(e);
85
      }
86

    
87
   }
88

    
89

    
90
   private void doMarkHighestNB() throws UnsupportedOutputChannelException {
91

    
92
      int i, x, y, ix, iy, xlo, ylo, xhi, yhi;
93
      double lo, hi, z;
94

    
95
      IRasterLayer clo, chi;
96

    
97
      clo = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent());
98
      chi = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent());
99

    
100
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
101
         for (x = 0; x < m_iNX; x++) {
102
            lo = hi = m_DEM.getCellValueAsDouble(x, y);
103
            xhi = xlo = x;
104
            yhi = ylo = y;
105
            for (i = 0; i < 4; i++) {
106
               ix = x + m_iOffsetX[i];
107
               iy = y + m_iOffsetY[i];
108
               z = m_DEM.getCellValueAsDouble(ix, iy);
109
               if (!m_DEM.isNoDataValue(z)) {
110
                  if (z > hi) {
111
                     hi = z;
112
                     xhi = ix;
113
                     yhi = iy;
114
                  }
115
                  else if (z < lo) {
116
                     lo = z;
117
                     xlo = ix;
118
                     ylo = iy;
119
                  }
120
               }
121
            }
122
            this.setProgress(y, m_iNY);
123
            clo.addToCellValue(xlo, ylo, 1);
124
            chi.addToCellValue(xhi, yhi, 1);
125
         }
126
      }
127

    
128
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
129
         for (x = 0; x < m_iNX; x++) {
130
            if (chi.getCellValueAsByte(x, y) == 0) {
131
               if (clo.getCellValueAsByte(x, y) == 0) {
132
                  m_Result.setCellValue(x, y, 2);
133
               }
134
               else {
135
                  m_Result.setCellValue(x, y, 1);
136
               }
137
            }
138
            else if (clo.getCellValueAsByte(x, y) == 0) {
139
               m_Result.setCellValue(x, y, -1);
140
            }
141
            else {
142
               m_Result.setCellValue(x, y, 0);
143
            }
144
         }
145
      }
146

    
147
   }
148

    
149

    
150
   private void doOppositeNB() throws UnsupportedOutputChannelException {
151

    
152
      int i, x, y, ix, iy, jx, jy;
153
      double z, iz, jz;
154

    
155
      IRasterLayer clo, chi;
156

    
157
      clo = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent());
158
      chi = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent());
159

    
160
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
161
         for (x = 0; x < m_iNX; x++) {
162
            z = m_DEM.getCellValueAsDouble(x, y);
163
            for (i = 0; i < 4; i++) {
164
               ix = x + m_iOffsetX[i];
165
               iy = y + m_iOffsetY[i];
166
               iz = m_DEM.getCellValueAsDouble(ix, iy);
167
               if (!m_DEM.isNoDataValue(iz)) {
168
                  jx = x + m_iOffsetX[i + 4];
169
                  jy = y + m_iOffsetX[i + 4];
170
                  jz = m_DEM.getCellValueAsDouble(jx, jy);
171
                  if (!m_DEM.isNoDataValue(jz)) {
172
                     if ((iz > z) && (jz > z)) {
173
                        chi.addToCellValue(x, y, 1);
174
                     }
175
                     else if ((iz < z) && (jz < z)) {
176
                        clo.addToCellValue(x, y, 1);
177
                     }
178
                  }
179
               }
180
            }
181
         }
182
      }
183

    
184
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
185
         for (x = 0; x < m_iNX; x++) {
186
            if (chi.getCellValueAsByte(x, y) != 0) {
187
               if (clo.getCellValueAsByte(x, y) != 0) {
188
                  m_Result.setCellValue(x, y, 5);
189
               }
190
               else {
191
                  m_Result.setCellValue(x, y, chi.getCellValueAsByte(x, y));
192
               }
193
            }
194
            else if (clo.getCellValueAsByte(x, y) != 0) {
195
               m_Result.setCellValue(x, y, -clo.getCellValueAsByte(x, y));
196
            }
197
            else {
198
               m_Result.setCellValue(x, y, 0);
199
            }
200
         }
201
      }
202

    
203
   }
204

    
205

    
206
   private void doFlowDirection() {
207

    
208
      boolean bLower;
209
      int x, y, i, ix, iy, xLow = 0, yLow = 0;
210
      double z, iz, zLow = 0.;
211

    
212
      m_Result.assign(0.0);
213

    
214
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
215
         for (x = 0; x < m_iNX; x++) {
216
            z = m_DEM.getCellValueAsDouble(x, y);
217
            bLower = false;
218
            for (i = 0; i < 8; i++) {
219
               ix = x + m_iOffsetX[i];
220
               iy = y + m_iOffsetY[i];
221
               iz = m_DEM.getCellValueAsDouble(ix, iy);
222
               if (!m_DEM.isNoDataValue(iz)) {
223
                  if (iz < z) {
224
                     if (!bLower) {
225
                        bLower = true;
226
                        zLow = iz;
227
                        xLow = ix;
228
                        yLow = iy;
229
                     }
230
                     else if (iz < zLow) {
231
                        zLow = iz;
232
                        xLow = ix;
233
                        yLow = iy;
234
                     }
235
                  }
236
               }
237
            }
238

    
239
            if (bLower) {
240
               m_Result.addToCellValue(xLow, yLow, 1);
241
            }
242
         }
243
      }
244
   }
245

    
246

    
247
   private void doPeuckerDouglas() {
248

    
249
      boolean wasPlus;
250
      int x, y, i, ix, iy, nSgn;
251
      double d, dPlus, dMinus, z, iz, alt[];
252

    
253
      alt = new double[8];
254

    
255
      for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) {
256
         for (x = 0; x < m_iNX; x++) {
257
            z = m_DEM.getCellValueAsDouble(x, y);
258
            for (i = 0; i < 8; i++) {
259
               ix = x + m_iOffsetX[i];
260
               iy = y + m_iOffsetY[i];
261
               iz = m_DEM.getCellValueAsDouble(ix, iy);
262
               if (!m_DEM.isNoDataValue(iz)) {
263
                  alt[i] = iz;
264
               }
265
               else {
266
                  alt[i] = z;
267
               }
268
            }
269

    
270
            dPlus = dMinus = 0;
271
            nSgn = 0;
272
            wasPlus = (alt[7] - z > 0) ? true : false;
273

    
274
            for (i = 0; i < 8; i++) {
275
               d = alt[i] - z;
276
               if (d > 0) {
277
                  dPlus += d;
278
                  if (!wasPlus) {
279
                     nSgn++;
280
                     wasPlus = true;
281
                  }
282
               }
283
               else if (d < 0) {
284
                  dMinus -= d;
285
                  if (wasPlus) {
286
                     nSgn++;
287
                     wasPlus = false;
288
                  }
289
               }
290
            }
291

    
292
            i = 0;
293
            if (dPlus == 0) {
294
               i = 9;
295
            }
296
            else if (dMinus == 0) {
297
               i = -9;
298
            }
299
            else if (nSgn == 4) {
300
               i = 1;
301
            }
302
            else if (nSgn == 2) {
303
               i = nSgn = 0;
304

    
305
               if (alt[7] > z) {
306
                  while (alt[i++] > z) {
307
                     ;
308
                  }
309
                  do {
310
                     nSgn++;
311
                  }
312
                  while (alt[i++] < z);
313
               }
314
               else {
315
                  while (alt[i++] < z) {
316
                     ;
317
                  }
318
                  do {
319
                     nSgn++;
320
                  }
321
                  while (alt[i++] > z);
322
               }
323

    
324
               i = 0;
325

    
326
               if (nSgn == 4) {
327
                  if (dMinus - dPlus > m_dThreshold) {
328
                     i = 2;
329
                  }
330
                  else if (dPlus - dMinus > m_dThreshold) {
331
                     i = -2;
332
                  }
333
               }
334
               else { // lines:
335
                  if (dMinus - dPlus > 0) {
336
                     i = 7;
337
                  }
338
                  else {
339
                     // Channel
340
                     i = -7;
341
                  }
342
               }
343
            }
344

    
345
            m_Result.setCellValue(x, y, i);
346
         }
347
      }
348

    
349
   }
350

    
351
}