Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / hydrology / slopeLength / SlopeLengthAlgorithm.java @ 59

History | View | Annotate | Download (5.39 KB)

1
package es.unex.sextante.hydrology.slopeLength;
2

    
3
import java.util.Arrays;
4

    
5
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
6
import es.unex.sextante.core.GeoAlgorithm;
7
import es.unex.sextante.core.AnalysisExtent;
8
import es.unex.sextante.core.Sextante;
9
import es.unex.sextante.dataObjects.IRasterLayer;
10
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
11
import es.unex.sextante.exceptions.RepeatedParameterNameException;
12
import es.unex.sextante.rasterWrappers.GridCell;
13

    
14
public class SlopeLengthAlgorithm
15
         extends
16
            GeoAlgorithm {
17

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

    
21
   public static final String DEM          = "DEM";
22
   public static final String USETHRESHOLD = "USETHRESHOLD";
23
   public static final String THRESHOLD    = "THRESHOLD";
24
   public static final String SLOPELENGTH  = "SLOPELENGTH";
25

    
26
   private int                m_iNX, m_iNY;
27

    
28
   private IRasterLayer       m_DEM        = null;
29
   private IRasterLayer       m_SlopeLength;
30
   private IRasterLayer       m_Slope;
31
   private double             m_dThreshold;
32
   private boolean            m_bUseThreshold;
33

    
34

    
35
   @Override
36
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
37

    
38
      int i;
39

    
40
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
41
      m_bUseThreshold = m_Parameters.getParameterValueAsBoolean(USETHRESHOLD);
42
      m_dThreshold = Math.abs(m_Parameters.getParameterValueAsDouble(THRESHOLD));
43

    
44
      m_SlopeLength = getNewRasterLayer(SLOPELENGTH, Sextante.getText("Slope_length"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
45

    
46
      m_SlopeLength.assign(0.0);
47

    
48
      final AnalysisExtent extent = m_SlopeLength.getWindowGridExtent();
49

    
50
      m_Slope = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_FLOAT, extent);
51

    
52
      m_DEM.setWindowExtent(extent);
53

    
54
      m_iNX = m_DEM.getNX();
55
      m_iNY = m_DEM.getNY();
56

    
57
      if (m_bUseThreshold) {
58
         createSlopeLayer();
59
      }
60

    
61
      final GridCell[] cells = getSortedArrayOfCells(m_DEM);
62
      final int iCells = cells.length;
63

    
64
      for (i = iCells - 1; (i > -1) && setProgress(iCells - i, iCells); i--) {
65
         setLength(cells[i].getX(), cells[i].getY());
66
      }
67

    
68
      return !m_Task.isCanceled();
69

    
70
   }
71

    
72

    
73
   @Override
74
   public void defineCharacteristics() {
75

    
76
      setName(Sextante.getText("Slope_length"));
77
      setGroup(Sextante.getText("Indices_and_other_hydrological_parameters"));
78
      setUserCanDefineAnalysisExtent(true);
79

    
80
      try {
81
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
82
         m_Parameters.addNumericalValue(THRESHOLD, Sextante.getText("Slope_change_threshold"), 0.5,
83
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
84
         m_Parameters.addBoolean(USETHRESHOLD, Sextante.getText("Use_threshold"), true);
85
         addOutputRasterLayer(SLOPELENGTH, Sextante.getText("Slope_length"));
86
      }
87
      catch (final RepeatedParameterNameException e) {
88
         Sextante.addErrorToLog(e);
89
      }
90

    
91
   }
92

    
93

    
94
   private void createSlopeLayer() {
95

    
96
      int x, y;
97

    
98
      for (y = 0; y < m_iNY; y++) {
99
         for (x = 0; x < m_iNX; x++) {
100
            m_Slope.setCellValue(x, y, m_DEM.getSlope(x, y));
101
         }
102
      }
103

    
104
   }
105

    
106

    
107
   private void setLength(final int x,
108
                          final int y) {
109

    
110
      int i, ix, iy;
111
      double dSlope, dSlope2;
112
      double dLength;
113
      double dValue;
114

    
115
      dValue = m_DEM.getCellValueAsDouble(x, y);
116
      if (!m_DEM.isNoDataValue(dValue) && ((i = m_DEM.getDirToNextDownslopeCell(x, y)) >= 0)) {
117
         ix = x + m_iOffsetX[i];
118
         iy = y + m_iOffsetY[i];
119
         dValue = m_DEM.getCellValueAsDouble(ix, iy);
120
         if (!m_DEM.isNoDataValue(dValue)) {
121
            if (m_bUseThreshold) {
122
               dSlope = m_Slope.getCellValueAsDouble(x, y);
123
               dSlope2 = m_Slope.getCellValueAsDouble(ix, iy);
124
               if (Math.abs(dSlope2) > m_dThreshold * Math.abs(dSlope)) {
125
                  dLength = m_SlopeLength.getCellValueAsDouble(x, y) + m_DEM.getDistToNeighborInDir(i);
126
               }
127
               else {
128
                  dLength = m_DEM.getDistToNeighborInDir(i);
129
               }
130
               if (dLength > m_SlopeLength.getCellValueAsDouble(ix, iy)) {
131
                  m_SlopeLength.setCellValue(ix, iy, dLength);
132
               }
133
            }
134
            else {
135
               dLength = m_SlopeLength.getCellValueAsDouble(x, y) + m_DEM.getDistToNeighborInDir(i);
136
               if (dLength > m_SlopeLength.getCellValueAsDouble(ix, iy)) {
137
                  m_SlopeLength.setCellValue(ix, iy, dLength);
138
               }
139
            }
140
         }
141
      }
142
      else {
143
         m_SlopeLength.setNoData(x, y);
144
      }
145

    
146
   }
147

    
148

    
149
   public GridCell[] getSortedArrayOfCells(final IRasterLayer layer) {
150

    
151
      int i;
152
      int iX, iY;
153
      final int iNX = layer.getNX();
154
      final int iCells = layer.getNX() * layer.getNY();
155
      GridCell[] cells;
156
      GridCell cell;
157

    
158
      cells = new GridCell[iCells];
159

    
160
      for (i = 0; i < iCells; i++) {
161
         iX = i % iNX;
162
         iY = i / iNX;
163
         cell = new GridCell(iX, iY, layer.getCellValueAsDouble(iX, iY));
164
         cells[i] = cell;
165
      }
166

    
167
      Arrays.sort(cells);
168

    
169
      return cells;
170

    
171
   }
172

    
173

    
174
}