Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / accCostAnisotropic / AccCostAnisotropicAlgorithm.java @ 59

History | View | Annotate | Download (8.75 KB)

1
package es.unex.sextante.gridAnalysis.accCostAnisotropic;
2

    
3
import java.util.ArrayList;
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 AccCostAnisotropicAlgorithm
15
         extends
16
            GeoAlgorithm {
17

    
18
   public static final String  COST         = "COST";
19
   public static final String  COSTDIR      = "COSTDIR";
20
   public static final String  KFACTOR      = "KFACTOR";
21
   public static final String  FEATURES     = "FEATURES";
22
   public static final String  ACCCOST      = "ACCCOST";
23
   public static final String  CLOSESTPOINT = "CLOSESTPOINT";
24

    
25
   private final static int    m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
26
   private final static int    m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
27
   private final static double m_dDist[]    = { 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.) };
28

    
29
   private static final int    NO_DATA      = -1;
30
   private static final int    DATA         = 1;
31
   private static final double ANGLES[][]   = { { 135, 180, 225 }, { 90, 0, 270 }, { 45, 0, 315 } };
32

    
33
   private int                 m_iNX, m_iNY;
34
   private double              m_dK;
35
   private IRasterLayer        m_Cost;
36
   private IRasterLayer        m_CostDir;
37
   private IRasterLayer        m_Features;
38
   private IRasterLayer        m_AccCost;
39
   private IRasterLayer        m_ClosestPoint;
40
   private IRasterLayer        m_Points, m_Points2;
41
   private ArrayList           m_AdjPoints, m_CentralPoints;
42

    
43

    
44
   @Override
45
   public void defineCharacteristics() {
46

    
47
      setName(Sextante.getText("Accumulated_cost__anisotropic"));
48
      setGroup(Sextante.getText("Cost_distances_and_routes"));
49
      setUserCanDefineAnalysisExtent(true);
50
      setIsDeterminatedProcess(false);
51

    
52
      try {
53
         m_Parameters.addInputRasterLayer(COST, Sextante.getText("Maximum_unitary_cost"), true);
54
         m_Parameters.addInputRasterLayer(COSTDIR, Sextante.getText("Direction_of_maximum_cost_[degrees]"), true);
55
         m_Parameters.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true);
56
         m_Parameters.addNumericalValue(KFACTOR, Sextante.getText("K"), 2, AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE);
57
         addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
58
         addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
59
      }
60
      catch (final RepeatedParameterNameException e) {
61
         Sextante.addErrorToLog(e);
62
      }
63

    
64
   }
65

    
66

    
67
   @Override
68
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
69

    
70
      int x, y;
71
      int iPoint = 1;
72
      double dValue;
73

    
74
      m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST);
75
      m_CostDir = m_Parameters.getParameterValueAsRasterLayer(COSTDIR);
76
      m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES);
77

    
78
      m_AdjPoints = new ArrayList();
79
      m_CentralPoints = new ArrayList();
80

    
81
      m_dK = m_Parameters.getParameterValueAsDouble(KFACTOR);
82

    
83
      m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
84
      m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
85

    
86
      final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
87

    
88
      m_Cost.setWindowExtent(extent);
89
      m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
90

    
91
      m_CostDir.setWindowExtent(extent);
92
      m_CostDir.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
93

    
94
      m_Features.setWindowExtent(extent);
95
      m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour);
96

    
97
      m_iNX = m_Cost.getNX();
98
      m_iNY = m_Cost.getNY();
99

    
100
      m_AccCost.setNoDataValue(NO_DATA);
101
      m_AccCost.assignNoData();
102

    
103
      m_Points = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent);
104

    
105
      m_Points2 = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent);
106

    
107
      m_Points.setNoDataValue(NO_DATA);
108
      m_Points.assignNoData();
109

    
110
      m_Points2.setNoDataValue(NO_DATA);
111
      m_Points2.assignNoData();
112

    
113
      m_ClosestPoint.assign(0);
114

    
115
      for (y = 0; y < m_iNY; y++) {
116
         for (x = 0; x < m_iNX; x++) {
117
            dValue = m_Features.getCellValueAsDouble(x, y);
118
            if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) {
119
               m_Points.setCellValue(x, y, DATA);
120
               m_CentralPoints.add(new GridCell(x, y, iPoint));
121
               m_AccCost.setCellValue(x, y, 0.0);
122
               m_ClosestPoint.setCellValue(x, y, iPoint);
123
               iPoint++;
124
            }
125
         }
126
      }
127

    
128
      calculateCost();
129

    
130
      return !m_Task.isCanceled();
131

    
132
   }
133

    
134

    
135
   private void calculateCost() {
136

    
137
      int i;
138
      int iPt;
139
      int iPoint;
140
      int x, y, x2, y2;
141
      double dAccCost;
142
      double dPrevAccCost;
143
      GridCell cell;
144

    
145
      while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) {
146
         for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) {
147
            cell = (GridCell) m_CentralPoints.get(iPt);
148
            x = cell.getX();
149
            y = cell.getY();
150
            iPoint = (int) cell.getValue();
151
            if (m_Points.getCellValueAsInt(x, y) == DATA) {
152
               m_Points.setCellValue(x, y, NO_DATA);
153
               for (i = 0; i < 8; i++) {
154
                  x2 = x + m_iOffsetX[i];
155
                  y2 = y + m_iOffsetY[i];
156
                  dAccCost = m_AccCost.getCellValueAsDouble(x, y);
157
                  dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2);
158
                  if ((dPrevAccCost > dAccCost) || m_AccCost.isNoDataValue(dPrevAccCost)) {
159
                     final double dCostInDir = getCostInDir(x, y, m_iOffsetX[i], m_iOffsetY[i]);
160
                     if (dCostInDir != NO_DATA) {
161
                        dAccCost += dCostInDir * m_dDist[i];
162
                        if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
163
                           m_AccCost.setCellValue(x2, y2, dAccCost);
164
                           m_ClosestPoint.setCellValue(x2, y2, iPoint);
165
                           if (m_Points2.getCellValueAsInt(x2, y2) == NO_DATA) {
166
                              m_Points2.setCellValue(x2, y2, DATA);
167
                              m_AdjPoints.add(new GridCell(x2, y2, iPoint));
168
                           }
169
                        }
170
                     }
171
                  }
172
               }
173
            }
174
         }
175

    
176
         final IRasterLayer swap = m_Points;
177
         m_Points = m_Points2;
178
         m_Points2 = swap;
179

    
180
         m_CentralPoints = m_AdjPoints;
181
         m_AdjPoints = new ArrayList();
182

    
183
         setProgressText(Integer.toString(m_AdjPoints.size()));
184

    
185
      }
186
   }
187

    
188

    
189
   private double getCostInDir(final int x,
190
                               final int y,
191
                               final int iH,
192
                               final int iV) {
193

    
194
      final double dAngle = ANGLES[iV + 1][iH + 1];
195

    
196
      final int x2 = x + iH;
197
      final int y2 = y + iV;
198

    
199
      double dCost1 = m_Cost.getCellValueAsDouble(x, y);
200
      double dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
201

    
202
      final double dCostDir1 = m_CostDir.getCellValueAsDouble(x, y);
203
      final double dCostDir2 = m_CostDir.getCellValueAsDouble(x2, y2);
204

    
205
      if (m_Cost.isNoDataValue(dCost1) || m_Cost.isNoDataValue(dCost2) || m_CostDir.isNoDataValue(dCostDir1)
206
          || m_CostDir.isNoDataValue(dCostDir2) || (dCost1 <= 0) || (dCost2 <= 0)) {
207
         return NO_DATA;
208
      }
209
      else {
210
         double dDifAngle1 = Math.abs(dCostDir1 - dAngle);
211
         double dDifAngle2 = Math.abs(dCostDir2 - dAngle);
212

    
213
         dDifAngle1 = Math.toRadians(dDifAngle1);
214
         dDifAngle2 = Math.toRadians(dDifAngle2);
215

    
216
         final double dCos1 = Math.cos(dDifAngle1);
217
         final double dCos2 = Math.cos(dDifAngle2);
218

    
219
         final int dSgn1 = signum(dCos1);
220
         final int dSgn2 = signum(dCos2);
221

    
222
         final double dExp1 = dSgn1 * Math.pow(Math.abs(dCos1), m_dK);
223
         final double dExp2 = dSgn2 * Math.pow(Math.abs(dCos2), m_dK);
224

    
225
         dCost1 = Math.pow(dCost1, dExp1) / 2.;
226
         dCost2 = Math.pow(dCost2, dExp2) / 2.;
227

    
228
         return dCost1 + dCost2;
229
      }
230

    
231
   }
232

    
233

    
234
   private int signum(final double difAngle) {
235

    
236
      if (difAngle < 0) {
237
         return -1;
238
      }
239
      else {
240
         return 1;
241
      }
242

    
243
   }
244

    
245
}