Statistics
| Revision:

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

History | View | Annotate | Download (5.62 KB)

1
package es.unex.sextante.morphometry.convergence;
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 ConvergenceAlgorithm
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  DEM            = "DEM";
19
   public static final String  METHOD         = "METHOD";
20
   public static final String  RESULT         = "RESULT";
21

    
22
   private static final double DEG_45_IN_RAD  = Math.toRadians(45);
23
   private static final double DEG_90_IN_RAD  = Math.toRadians(90);
24
   private static final double DEG_180_IN_RAD = Math.toRadians(180);
25
   private static final double DEG_360_IN_RAD = Math.toRadians(360);
26

    
27
   IRasterLayer                m_Convergence;
28
   IRasterLayer                m_DEM;
29

    
30

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

    
34
      int x, y;
35
      int iNX, iNY;
36

    
37
      final int iMethod = m_Parameters.getParameterValueAsInt(METHOD);
38
      m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM);
39

    
40
      m_Convergence = getNewRasterLayer(RESULT, Sextante.getText("Convergence"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
41

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

    
44
      m_DEM.setWindowExtent(extent);
45

    
46
      iNX = m_DEM.getNX();
47
      iNY = m_DEM.getNY();
48

    
49
      for (y = 0; (y < iNY) && setProgress(y, iNY); y++) {
50
         for (x = 0; x < iNX; x++) {
51
            switch (iMethod) {
52
               case 0:
53
                  Do_Aspect(x, y);
54
                  break;
55
               case 1:
56
                  Do_Gradient(x, y);
57
                  break;
58
            }
59
         }
60
      }
61

    
62

    
63
      return !m_Task.isCanceled();
64
   }
65

    
66

    
67
   @Override
68
   public void defineCharacteristics() {
69

    
70
      final String[] sMethod = { Sextante.getText("Aspect"), Sextante.getText("Gradient") };
71

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

    
76
      try {
77
         m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true);
78
         m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
79
         addOutputRasterLayer(RESULT, Sextante.getText("Convergence"));
80
      }
81
      catch (final RepeatedParameterNameException e) {
82
         Sextante.addErrorToLog(e);
83
      }
84

    
85
   }
86

    
87

    
88
   private void Do_Aspect(final int x,
89
                          final int y) {
90

    
91
      int i, n;
92
      double dAspect, dIAspect, d, dSum, z, z2;
93

    
94
      z = m_DEM.getCellValueAsDouble(x, y);
95

    
96
      if (m_DEM.isNoDataValue(z)) {
97
         m_Convergence.setNoData(x, y);
98
      }
99
      else {
100
         for (i = 0, n = 0, dSum = 0.0, dIAspect = -DEG_180_IN_RAD; i < 8; i++, dIAspect += DEG_45_IN_RAD) {
101
            z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
102
            if (!m_DEM.isNoDataValue(z2)) {
103
               dAspect = m_DEM.getAspect(x + m_iOffsetX[i], y + m_iOffsetY[i]);
104
               if (!m_DEM.isNoDataValue(dAspect) && (dAspect >= 0)) {
105
                  d = dAspect - dIAspect;
106
                  d = d % DEG_360_IN_RAD;
107
                  if (d < -DEG_180_IN_RAD) {
108
                     d += DEG_360_IN_RAD;
109
                  }
110
                  else if (d > DEG_180_IN_RAD) {
111
                     d -= DEG_360_IN_RAD;
112
                  }
113

    
114
                  dSum += Math.abs(d);
115
                  n++;
116
               }
117
            }
118
         }
119
         double res = dSum / n;
120
         res = (res - DEG_90_IN_RAD);
121
         res = res * 100.0 / DEG_90_IN_RAD;
122

    
123
         m_Convergence.setCellValue(x, y, n > 0 ? (dSum / n - DEG_90_IN_RAD) * 100.0 / DEG_90_IN_RAD : 0.0);
124
      }
125
   }
126

    
127

    
128
   private void Do_Gradient(final int x,
129
                            final int y) {
130

    
131
      int i, n;
132
      double dAspect, dIAspect, dSlope, dISlope, d, dSum, z, z2;
133

    
134
      z = m_DEM.getCellValueAsDouble(x, y);
135

    
136
      if (m_DEM.isNoDataValue(z)) {
137
         m_Convergence.setNoData(x, y);
138
      }
139
      else {
140
         for (i = 0, n = 0, dSum = 0.0, dIAspect = -DEG_180_IN_RAD; i < 8; i++, dIAspect += DEG_45_IN_RAD) {
141
            z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
142
            if (!m_DEM.isNoDataValue(z2)) {
143
               dSlope = m_DEM.getSlope(x + m_iOffsetX[i], y + m_iOffsetY[i]);
144
               dAspect = m_DEM.getAspect(x + m_iOffsetX[i], y + m_iOffsetY[i]);
145
               if (!m_DEM.isNoDataValue(dAspect) && (dAspect >= 0)) {
146
                  dISlope = Math.atan((z2 - z) / m_DEM.getDistToNeighborInDir(i));
147
                  d = Math.acos(Math.sin(dSlope) * Math.sin(dISlope) + Math.cos(dSlope) * Math.cos(dISlope)
148
                                * Math.cos(dIAspect - dAspect));
149
                  d = d % DEG_360_IN_RAD;
150

    
151
                  if (d < -DEG_180_IN_RAD) {
152
                     d += DEG_360_IN_RAD;
153
                  }
154
                  else if (d > DEG_180_IN_RAD) {
155
                     d -= DEG_360_IN_RAD;
156
                  }
157

    
158
                  dSum += Math.abs(d);
159
                  n++;
160

    
161
               }
162
            }
163
         }
164
         m_Convergence.setCellValue(x, y, n > 0 ? (dSum / n - DEG_90_IN_RAD) * 100.0 / DEG_90_IN_RAD : 0.0);
165
      }
166
   }
167

    
168
}