Statistics
| Revision:

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

History | View | Annotate | Download (9.46 KB)

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

    
3
import java.util.ArrayList;
4

    
5
import es.unex.sextante.core.GeoAlgorithm;
6
import es.unex.sextante.core.AnalysisExtent;
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.rasterWrappers.GridCell;
12

    
13
public class AccCostAlgorithm
14
         extends
15
            GeoAlgorithm {
16

    
17
   public static final String COST         = "COST";
18
   public static final String FEATURES     = "FEATURES";
19
   public static final String ACCCOST      = "ACCCOST";
20
   public static final String CLOSESTPOINT = "CLOSESTPOINT";
21
   public static final String DISTANCE     = "DISTANCE";
22

    
23
   private static final int   NO_DATA      = -1;
24

    
25
   public static final int    EUCLIDEAN    = 0;
26
   public static final int    CHESSBOARD   = 1;
27
   public static final int    MANHATTAN    = 2;
28
   public static final int    CHAMFER      = 3;
29
   public static final int    WINDOW5X5    = 4;
30

    
31
   private int                m_iNX, m_iNY;
32
   private int                m_iDistance;
33
   private IRasterLayer       m_Cost;
34
   private IRasterLayer       m_Features;
35
   private IRasterLayer       m_AccCost;
36
   private IRasterLayer       m_ClosestPoint;
37
   private ArrayList          m_CentralPoints, m_AdjPoints;
38

    
39

    
40
   @Override
41
   public void defineCharacteristics() {
42

    
43
      final String[] sOptions = { Sextante.getText("Euclidean"), Sextante.getText("Chessboard"), Sextante.getText("Manhattan"),
44
               Sextante.getText("Chamfer_3-4"), " 5 X 5" };
45
      setName(Sextante.getText("Accumulated_cost__isotropic"));
46
      setGroup(Sextante.getText("Cost_distances_and_routes"));
47
      setUserCanDefineAnalysisExtent(true);
48
      setIsDeterminatedProcess(false);
49

    
50
      try {
51
         m_Parameters.addInputRasterLayer(COST, Sextante.getText("Unitary_cost"), true);
52
         m_Parameters.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true);
53
         addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
54
         addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
55
         m_Parameters.addSelection(DISTANCE, Sextante.getText("Type_of_distance"), sOptions);
56

    
57
      }
58
      catch (final RepeatedParameterNameException e) {
59
         Sextante.addErrorToLog(e);
60
      }
61

    
62
   }
63

    
64

    
65
   @Override
66
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
67

    
68
      int x, y;
69
      int iPoint = 1;
70
      double dValue;
71

    
72
      m_CentralPoints = new ArrayList();
73
      m_AdjPoints = new ArrayList();
74

    
75
      m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST);
76
      m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES);
77
      m_iDistance = m_Parameters.getParameterValueAsInt(DISTANCE);
78

    
79
      m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
80
      m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
81

    
82
      final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
83

    
84
      m_Cost.setWindowExtent(extent);
85
      m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
86

    
87
      m_Features.setWindowExtent(extent);
88
      m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour);
89

    
90
      m_iNX = m_Cost.getNX();
91
      m_iNY = m_Cost.getNY();
92

    
93
      m_AccCost.setNoDataValue(NO_DATA);
94
      m_AccCost.assignNoData();
95

    
96
      m_ClosestPoint.setNoDataValue(NO_DATA);
97
      m_ClosestPoint.assignNoData();
98

    
99
      for (y = 0; y < m_iNY; y++) {
100
         for (x = 0; x < m_iNX; x++) {
101
            dValue = m_Features.getCellValueAsDouble(x, y);
102
            if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) {
103
               m_CentralPoints.add(new GridCell(x, y, iPoint));
104
               m_AccCost.setCellValue(x, y, 0.0);
105
               m_ClosestPoint.setCellValue(x, y, iPoint);
106
               iPoint++;
107
            }
108
         }
109
      }
110

    
111
      if (m_iDistance != WINDOW5X5) {
112
         calculateCost3X3();
113
      }
114
      else {
115
         calculateCost5X5();
116
      }
117

    
118
      return !m_Task.isCanceled();
119

    
120
   }
121

    
122

    
123
   private void calculateCost5X5() {
124

    
125
      int i, j;
126
      int iPt;
127
      int iPoint;
128
      int x, y, x2, y2;
129
      double dAccCost;
130
      double dCost;
131
      double dPrevAccCost;
132
      GridCell cell;
133

    
134
      final double dDist[][] = new double[5][5];
135

    
136
      for (i = -2; i < 3; i++) {
137
         for (j = -1; j < 2; j++) {
138
            dDist[i + 2][j + 2] = Math.sqrt(i * i + j * j);
139
         }
140
      }
141

    
142

    
143
      while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) {
144
         for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) {
145
            cell = (GridCell) m_CentralPoints.get(iPt);
146
            x = cell.getX();
147
            y = cell.getY();
148
            iPoint = (int) cell.getValue();
149
            for (i = -2; i < 3; i++) {
150
               for (j = -2; j < 3; j++) {
151
                  x2 = x + i;
152
                  y2 = y + j;
153
                  dCost = getCostTo(x, y, i, j);
154
                  if (dCost != NO_DATA) {
155
                     dAccCost = m_AccCost.getCellValueAsDouble(x, y);
156
                     dAccCost += (dCost * dDist[i + 2][j + 2]);
157
                     dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2);
158
                     if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
159
                        m_AccCost.setCellValue(x2, y2, dAccCost);
160
                        m_ClosestPoint.setCellValue(x2, y2, iPoint);
161
                        m_AdjPoints.add(new GridCell(x2, y2, iPoint));
162
                     }
163
                  }
164
               }
165
            }
166
         }
167

    
168
         m_CentralPoints = m_AdjPoints;
169
         m_AdjPoints = new ArrayList();
170
      }
171

    
172
   }
173

    
174

    
175
   private double getCostTo(final int x,
176
                            final int y,
177
                            final int i,
178
                            final int j) {
179

    
180
      int n, nMax;
181
      int iCells = 0;
182
      double di, dj;
183
      double dCost = 0;
184
      double dPartialCost;
185

    
186
      if ((i == 0) && (j == 0)) {
187
         return 0;
188
      }
189

    
190
      if (i > j) {
191
         dj = Math.abs((double) j / (double) i) * Math.signum(j);
192
         di = Math.signum(i);
193
         nMax = Math.abs(i);
194
      }
195
      else {
196
         di = Math.abs((double) i / (double) j) * Math.signum(i);
197
         dj = Math.signum(j);
198
         nMax = Math.abs(j);
199
      }
200

    
201
      double ii = 0;
202
      double jj = 0;
203
      for (n = 0; n <= nMax; n++, ii += di, jj += dj) {
204
         dPartialCost = m_Cost.getCellValueAsDouble((int) (x + ii), (int) (y + jj));
205
         if (m_Cost.isNoDataValue(dPartialCost) || (dPartialCost <= 0)) {
206
            return NO_DATA;
207
         }
208
         else {
209
            dCost += dPartialCost;
210
            iCells++;
211
         }
212
      }
213

    
214
      return dCost / iCells;
215

    
216
   }
217

    
218

    
219
   private void calculateCost3X3() {
220

    
221
      int i, j;
222
      int iPt;
223
      int iPoint;
224
      int x, y, x2, y2;
225
      double dAccCost;
226
      double dCost1, dCost2;
227
      double dPrevAccCost;
228
      GridCell cell;
229

    
230
      double dDist[][] = new double[3][3];
231

    
232
      switch (m_iDistance) {
233
         case EUCLIDEAN:
234
         default:
235
            for (i = -1; i < 2; i++) {
236
               for (j = -1; j < 2; j++) {
237
                  dDist[i + 1][j + 1] = Math.sqrt(i * i + j * j);
238
               }
239
            }
240
            break;
241
         case CHESSBOARD:
242
            final double chessboard[][] = { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } };
243
            dDist = chessboard;
244
            break;
245
         case MANHATTAN:
246
            final double manhattan[][] = { { 2, 1, 2 }, { 1, 0, 1 }, { 2, 1, 2 } };
247
            dDist = manhattan;
248
            break;
249
         case CHAMFER:
250
            final double chamfer[][] = { { 4, 3, 4 }, { 3, 0, 3 }, { 4, 3, 4 } };
251
            dDist = chamfer;
252
            break;
253
      }
254

    
255
      while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) {
256
         for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) {
257
            cell = (GridCell) m_CentralPoints.get(iPt);
258
            x = cell.getX();
259
            y = cell.getY();
260
            iPoint = (int) cell.getValue();
261
            dCost1 = m_Cost.getCellValueAsDouble(x, y);
262
            for (i = -1; i < 2; i++) {
263
               for (j = -1; j < 2; j++) {
264
                  x2 = x + i;
265
                  y2 = y + j;
266
                  dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
267
                  if (!m_Cost.isNoDataValue(dCost1) && !m_Cost.isNoDataValue(dCost2) && (dCost1 > 0) && (dCost2 > 0)) {
268
                     dAccCost = m_AccCost.getCellValueAsDouble(x, y);
269
                     dAccCost += ((dCost1 + dCost2) / 2.0 * dDist[i + 1][j + 1]);
270
                     dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2);
271
                     if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
272
                        m_AccCost.setCellValue(x2, y2, dAccCost);
273
                        m_ClosestPoint.setCellValue(x2, y2, iPoint);
274
                        m_AdjPoints.add(new GridCell(x2, y2, iPoint));
275
                     }
276
                  }
277
               }
278
            }
279
         }
280

    
281
         m_CentralPoints = m_AdjPoints;
282
         m_AdjPoints = new ArrayList();
283
         setProgressText(Integer.toString(m_CentralPoints.size()));
284
      }
285
   }
286

    
287
}