Statistics
| Revision:

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

History | View | Annotate | Download (9.67 KB)

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

    
3
import java.util.ArrayList;
4
import java.util.Arrays;
5

    
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.parameters.FixedTableModel;
13
import es.unex.sextante.rasterWrappers.GridCell;
14

    
15
public class AccCostAnisotropicBAlgorithm
16
         extends
17
            GeoAlgorithm {
18

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

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

    
30
   private final static int     m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 };
31
   private final static int     m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 };
32
   private final static double  m_dDist[]    = { 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.) };
33

    
34
   private int                  m_iNX, m_iNY;
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_CentralPoints, m_AdjPoints;
42
   private DeviationAndFactor[] m_Factors;
43

    
44

    
45
   @Override
46
   public void defineCharacteristics() {
47

    
48
      final String sColumnNames[] = new String[] { Sextante.getText("Difference"), Sextante.getText("Factor") };
49

    
50
      setName(Sextante.getText("Accumulated_cost__anisotropic") + "(B)");
51
      setGroup(Sextante.getText("Cost_distances_and_routes"));
52
      setUserCanDefineAnalysisExtent(true);
53
      setIsDeterminatedProcess(false);
54

    
55
      try {
56
         m_Parameters.addInputRasterLayer(COST, Sextante.getText("Maximum_unitary_cost"), true);
57
         m_Parameters.addInputRasterLayer(COSTDIR, Sextante.getText("Direction_of_maximum_cost_[degrees]"), true);
58
         m_Parameters.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true);
59
         m_Parameters.addFixedTable(FACTORS, Sextante.getText("Cost_variation_factors"), sColumnNames, 5, false);
60
         addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
61
         addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
62
      }
63
      catch (final RepeatedParameterNameException e) {
64
         Sextante.addErrorToLog(e);
65
      }
66

    
67
   }
68

    
69

    
70
   @Override
71
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
72

    
73
      int x, y;
74
      int iPoint = 1;
75
      double dValue;
76

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

    
80
      m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST);
81
      m_CostDir = m_Parameters.getParameterValueAsRasterLayer(COSTDIR);
82
      m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES);
83

    
84
      final FixedTableModel factors = (FixedTableModel) m_Parameters.getParameterValueAsObject(FACTORS);
85

    
86
      m_Factors = new DeviationAndFactor[factors.getRowCount()];
87
      for (int i = 0; i < factors.getRowCount(); i++) {
88
         final double dDeviation = Double.parseDouble(factors.getValueAt(i, 0).toString());
89
         final double dFactor = Double.parseDouble(factors.getValueAt(i, 1).toString());
90
         m_Factors[i] = new DeviationAndFactor(dDeviation, dFactor);
91
      }
92

    
93
      Arrays.sort(m_Factors);
94

    
95
      m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
96
      m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
97

    
98
      final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
99

    
100
      m_Cost.setWindowExtent(extent);
101
      m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
102

    
103
      m_CostDir.setWindowExtent(extent);
104
      m_CostDir.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline);
105

    
106
      m_Features.setWindowExtent(extent);
107
      m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour);
108

    
109
      m_iNX = m_Cost.getNX();
110
      m_iNY = m_Cost.getNY();
111

    
112
      m_Points = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent);
113

    
114
      m_Points2 = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent);
115

    
116
      m_Points.setNoDataValue(NO_DATA);
117
      m_Points.assignNoData();
118

    
119
      m_Points2.setNoDataValue(NO_DATA);
120
      m_Points2.assignNoData();
121

    
122
      m_AccCost.setNoDataValue(NO_DATA);
123
      m_AccCost.assignNoData();
124

    
125
      m_ClosestPoint.setNoDataValue(NO_DATA);
126
      m_ClosestPoint.assignNoData();
127

    
128
      for (y = 0; y < m_iNY; y++) {
129
         for (x = 0; x < m_iNX; x++) {
130
            dValue = m_Features.getCellValueAsDouble(x, y);
131
            if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) {
132
               m_CentralPoints.add(new GridCell(x, y, iPoint));
133
               m_AccCost.setCellValue(x, y, 0.0);
134
               m_ClosestPoint.setCellValue(x, y, iPoint);
135
               iPoint++;
136
            }
137
         }
138
      }
139

    
140
      calculateCost();
141

    
142
      return !m_Task.isCanceled();
143

    
144
   }
145

    
146

    
147
   private void calculateCost() {
148

    
149
      int i;
150
      int iPt;
151
      int iPoint;
152
      int x, y, x2, y2;
153
      double dAccCost;
154
      double dPrevAccCost;
155
      GridCell cell;
156

    
157
      while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) {
158
         for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) {
159
            cell = (GridCell) m_CentralPoints.get(iPt);
160
            x = cell.getX();
161
            y = cell.getY();
162
            iPoint = (int) cell.getValue();
163
            if (m_Points.getCellValueAsInt(x, y) == DATA) {
164
               m_Points.setCellValue(x, y, NO_DATA);
165
               for (i = 0; i < 8; i++) {
166
                  x2 = x + m_iOffsetX[i];
167
                  y2 = y + m_iOffsetY[i];
168
                  dAccCost = m_AccCost.getCellValueAsDouble(x, y);
169
                  dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2);
170
                  if ((dPrevAccCost > dAccCost) || m_AccCost.isNoDataValue(dPrevAccCost)) {
171
                     final double dCostInDir = getCostInDir(x, y, m_iOffsetX[i], m_iOffsetY[i]);
172
                     if (dCostInDir != NO_DATA) {
173
                        dAccCost += dCostInDir * m_dDist[i];
174
                        if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
175
                           m_AccCost.setCellValue(x2, y2, dAccCost);
176
                           m_ClosestPoint.setCellValue(x2, y2, iPoint);
177
                           if (m_Points2.getCellValueAsInt(x2, y2) == NO_DATA) {
178
                              m_Points2.setCellValue(x2, y2, DATA);
179
                              m_AdjPoints.add(new GridCell(x2, y2, iPoint));
180
                           }
181
                        }
182
                     }
183
                  }
184
               }
185
            }
186
         }
187

    
188
         final IRasterLayer swap = m_Points;
189
         m_Points = m_Points2;
190
         m_Points2 = swap;
191

    
192
         m_CentralPoints = m_AdjPoints;
193
         m_AdjPoints = new ArrayList();
194

    
195
         setProgressText(Integer.toString(m_AdjPoints.size()));
196

    
197
      }
198
   }
199

    
200

    
201
   private double getCostInDir(final int x,
202
                               final int y,
203
                               final int iH,
204
                               final int iV) {
205

    
206
      final double dAngle = ANGLES[iV + 1][iH + 1];
207

    
208
      final int x2 = x + iH;
209
      final int y2 = y + iV;
210

    
211
      final double dCostDir1 = m_CostDir.getCellValueAsDouble(x, y);
212
      final double dCostDir2 = m_CostDir.getCellValueAsDouble(x2, y2);
213
      double dCost1 = m_Cost.getCellValueAsDouble(x, y);
214
      double dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
215

    
216
      if (m_Cost.isNoDataValue(dCost1) || m_Cost.isNoDataValue(dCost1) || m_CostDir.isNoDataValue(dCostDir1)
217
          || m_CostDir.isNoDataValue(dCostDir1)) {
218
         return NO_DATA;
219
      }
220
      else {
221
         final double dDifAngle1 = Math.abs(dCostDir1 - dAngle);
222
         final double dDifAngle2 = Math.abs(dCostDir2 - dAngle);
223

    
224
         dCost1 = getWeigthedCost(dCost1, dDifAngle1);
225
         dCost2 = getWeigthedCost(dCost2, dDifAngle2);
226

    
227
         return dCost1 + dCost2;
228
      }
229

    
230
   }
231

    
232

    
233
   private double getWeigthedCost(final double cost,
234
                                  final double difAngle) {
235

    
236
      for (int i = 0; i < m_Factors.length - 1; i++) {
237
         if ((m_Factors[i].deviation < difAngle) || (m_Factors[i + 1].deviation >= difAngle)) {
238
            return m_Factors[i].factor * cost / 2.;
239
         }
240
      }
241

    
242
      return cost / 2.;
243

    
244
   }
245

    
246
   private class DeviationAndFactor
247
            implements
248
               Comparable {
249

    
250
      public double factor;
251
      public double deviation;
252

    
253

    
254
      DeviationAndFactor(final double dDeviation,
255
                         final double dFactor) {
256

    
257
         deviation = dDeviation;
258
         factor = dFactor;
259
      }
260

    
261

    
262
      public int compareTo(final Object ob) throws ClassCastException {
263

    
264
         if (!(ob instanceof DeviationAndFactor)) {
265
            throw new ClassCastException();
266
         }
267

    
268
         final double dDeviation = ((DeviationAndFactor) ob).deviation;
269
         final double dDif = this.deviation - dDeviation;
270

    
271
         if (dDif > 0.0) {
272
            return 1;
273
         }
274
         else if (dDif < 0.0) {
275
            return -1;
276
         }
277
         else {
278
            return 0;
279
         }
280

    
281
      }
282
   }
283

    
284
}