Statistics
| Revision:

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

History | View | Annotate | Download (9.66 KB)

1 59 nbrodin
package es.unex.sextante.gridAnalysis.costInRoutesAnisotropicB;
2
3
import com.vividsolutions.jts.geom.Coordinate;
4
import com.vividsolutions.jts.geom.Geometry;
5
6
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
7
import es.unex.sextante.core.GeoAlgorithm;
8
import es.unex.sextante.core.Sextante;
9
import es.unex.sextante.dataObjects.IFeature;
10
import es.unex.sextante.dataObjects.IFeatureIterator;
11
import es.unex.sextante.dataObjects.IRasterLayer;
12
import es.unex.sextante.dataObjects.IVectorLayer;
13
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
14
import es.unex.sextante.exceptions.RepeatedParameterNameException;
15
import es.unex.sextante.outputs.IOutputChannel;
16
import es.unex.sextante.outputs.Output;
17
import es.unex.sextante.outputs.OutputVectorLayer;
18
import es.unex.sextante.parameters.FixedTableModel;
19
import es.unex.sextante.rasterWrappers.GridCell;
20
import es.unex.sextante.shapesTools.ShapesTools;
21
22
public class CostInRoutesAnisotropicBAlgorithm
23
         extends
24
            GeoAlgorithm {
25
26
   public static final String   ROUTES     = "ROUTES";
27
   public static final String   COST       = "COST";
28
   public static final String   COSTDIR    = "COSTDIR";
29
   public static final String   RESULT     = "RESULT";
30
   public static final String   FACTORS    = "FACTORS";
31
32
   private static final double  ANGLES[][] = { { 135, 180, 225 }, { 90, 0, 270 }, { 45, 0, 315 } };
33
   private static final double  NO_DATA    = -99999;
34
35
   private IRasterLayer         m_Cost;
36
   private double[]             m_dDist;
37
   private double[]             m_dCost;
38
   private int                  m_iLastX, m_iLastY;
39
   private int                  m_iPoints  = 0;
40
   private int                  m_iCurrentRoute;
41
   private IRasterLayer         m_CostDir;
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("Cost_for_predefined_routes__anisotropic") + "(B)");
51
      setGroup(Sextante.getText("Cost_distances_and_routes"));
52
      setUserCanDefineAnalysisExtent(true);
53
54
      try {
55
         m_Parameters.addInputVectorLayer(ROUTES, Sextante.getText("Routes"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE, true);
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.addFixedTable(FACTORS, Sextante.getText("Cost_variation_factors"), sColumnNames, 5, false);
59
         addOutputVectorLayer(RESULT, Sextante.getText("Routes_and_cost"), OutputVectorLayer.SHAPE_TYPE_LINE);
60
      }
61
      catch (final RepeatedParameterNameException e) {
62
         Sextante.addErrorToLog(e);
63
      }
64
65
   }
66
67
68
   @Override
69
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
70
71
      m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST);
72
      m_CostDir = m_Parameters.getParameterValueAsRasterLayer(COSTDIR);
73
74
      final FixedTableModel factors = (FixedTableModel) m_Parameters.getParameterValueAsObject(FACTORS);
75
76
      m_Factors = new DeviationAndFactor[factors.getRowCount()];
77
      for (int i = 0; i < factors.getRowCount(); i++) {
78
         final double dDeviation = Double.parseDouble(factors.getValueAt(i, 0).toString());
79
         final double dFactor = Double.parseDouble(factors.getValueAt(i, 1).toString());
80
         m_Factors[i] = new DeviationAndFactor(dDeviation, dFactor);
81
      }
82
83
      m_Cost.setFullExtent();
84
85
      m_CostDir.setWindowExtent(m_Cost.getWindowGridExtent());
86
87
      final IVectorLayer routes = m_Parameters.getParameterValueAsVectorLayer(ROUTES);
88
89
      if (routes.getShapesCount() == 0) {
90
         return false;
91
      }
92
      final int iShapesCount = routes.getShapesCount();
93
      m_iCurrentRoute = 0;
94
      m_Cost.setFullExtent();
95
      m_dCost = new double[routes.getShapesCount()];
96
      m_dDist = new double[routes.getShapesCount()];
97
      final IFeatureIterator iter = routes.iterator();
98
      while (iter.hasNext() && setProgress(m_iCurrentRoute, iShapesCount)) {
99
         m_iPoints = 0;
100
         final IFeature feature = iter.next();
101
         final Geometry geom = feature.getGeometry();
102
         processLine(geom.getCoordinates());
103
         m_iCurrentRoute++;
104
      }
105
      iter.close();
106
107
      if (m_Task.isCanceled()) {
108
         return false;
109
      }
110
111
      final Object[][] values = new Object[2][routes.getShapesCount()];
112
      final String[] sFields = { Sextante.getText("Distance"), Sextante.getText("Cost") };
113
      final Class[] types = { Double.class, Double.class };
114
      for (int i = 0; i < routes.getShapesCount(); i++) {
115
         values[0][i] = new Double(m_dDist[i]);
116
         values[1][i] = new Double(m_dCost[i]);
117
      }
118
119
      final IOutputChannel channel = getOutputChannel(RESULT);
120
      final Output out = new OutputVectorLayer();
121
      out.setName(RESULT);
122
      out.setDescription(Sextante.getText("Routes"));
123
      out.setOutputChannel(channel);
124
      out.setOutputObject(ShapesTools.addFields(m_OutputFactory, routes, channel, sFields, values, types));
125
      addOutputObject(out);
126
127
      return true;
128
129
   }
130
131
132
   private void processLine(final Coordinate coords[]) {
133
134
      int i;
135
      double x, y, x2, y2;
136
137
      for (i = 0; i < coords.length - 1; i++) {
138
         x = coords[i].x;
139
         y = coords[i].y;
140
         x2 = coords[i + 1].x;
141
         y2 = coords[i + 1].y;
142
         processSegment(x, y, x2, y2);
143
      }
144
145
   }
146
147
148
   private void processSegment(double x,
149
                               double y,
150
                               final double x2,
151
                               final double y2) {
152
153
      double dx, dy, d, n;
154
155
      dx = Math.abs(x2 - x);
156
      dy = Math.abs(y2 - y);
157
158
      if ((dx > 0.0) || (dy > 0.0)) {
159
         if (dx > dy) {
160
            dx /= m_Cost.getWindowCellSize();
161
            n = dx;
162
            dy /= dx;
163
            dx = m_Cost.getWindowCellSize();
164
         }
165
         else {
166
            dy /= m_Cost.getWindowCellSize();
167
            n = dy;
168
            dx /= dy;
169
            dy = m_Cost.getWindowCellSize();
170
         }
171
172
         if (x2 < x) {
173
            dx = -dx;
174
         }
175
176
         if (y2 < y) {
177
            dy = -dy;
178
         }
179
180
         for (d = 0.0; d <= n; d++, x += dx, y += dy) {
181
            addPoint(x, y);
182
         }
183
      }
184
185
   }
186
187
188
   private void addPoint(final double x,
189
                         final double y) {
190
191
      int iDX, iDY;
192
      final GridCell cell = m_Cost.getWindowGridExtent().getGridCoordsFromWorldCoords(x, y);
193
      final int iX = cell.getX();
194
      final int iY = cell.getY();
195
196
      if (m_iPoints == 0) {
197
         m_dDist[m_iCurrentRoute] = 0.0;
198
         m_dCost[m_iCurrentRoute] = 0.0;
199
         m_iLastX = cell.getX();
200
         m_iLastY = cell.getY();
201
      }
202
      else {
203
         iDX = iX - m_iLastX;
204
         iDY = iY - m_iLastY;
205
         m_dDist[m_iCurrentRoute] += Math.sqrt(iDX * iDX + iDY * iDY) * m_Cost.getWindowCellSize();
206
         final double dCost = getCostInDir(m_iLastX, m_iLastY, iDX, iDY);
207
         if (dCost != NO_DATA) {
208
            m_dCost[m_iCurrentRoute] += dCost;
209
         }
210
         m_iLastX = iX;
211
         m_iLastY = iY;
212
      }
213
214
      m_iLastX = iX;
215
      m_iLastY = iY;
216
      m_iPoints++;
217
218
   }
219
220
221
   private double getCostInDir(final int x,
222
                               final int y,
223
                               final int iH,
224
                               final int iV) {
225
226
      final double dAngle = ANGLES[iV + 1][iH + 1];
227
228
      final int x2 = x + iH;
229
      final int y2 = y + iV;
230
231
      final double dCostDir1 = m_CostDir.getCellValueAsDouble(x, y);
232
      final double dCostDir2 = m_CostDir.getCellValueAsDouble(x2, y2);
233
      double dCost1 = m_Cost.getCellValueAsDouble(x, y);
234
      double dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
235
236
      if (m_Cost.isNoDataValue(dCost1) || m_Cost.isNoDataValue(dCost1) || m_CostDir.isNoDataValue(dCostDir1)
237
          || m_CostDir.isNoDataValue(dCostDir1)) {
238
         return NO_DATA;
239
      }
240
      else {
241
         final double dDifAngle1 = Math.abs(dCostDir1 - dAngle);
242
         final double dDifAngle2 = Math.abs(dCostDir2 - dAngle);
243
244
         dCost1 = getWeigthedCost(dCost1, dDifAngle1);
245
         dCost2 = getWeigthedCost(dCost2, dDifAngle2);
246
247
         return dCost1 + dCost2;
248
      }
249
250
   }
251
252
253
   private double getWeigthedCost(final double cost,
254
                                  final double difAngle) {
255
256
      for (int i = 0; i < m_Factors.length - 1; i++) {
257
         if ((m_Factors[i].deviation < difAngle) || (m_Factors[i + 1].deviation >= difAngle)) {
258
            return m_Factors[i].factor * cost / 2.;
259
         }
260
      }
261
262
      return cost / 2.;
263
264
   }
265
266
   private class DeviationAndFactor
267
            implements
268
               Comparable {
269
270
      public double factor;
271
      public double deviation;
272
273
274
      DeviationAndFactor(final double dDeviation,
275
                         final double dFactor) {
276
277
         deviation = dDeviation;
278
         factor = dFactor;
279
      }
280
281
282
      public int compareTo(final Object ob) throws ClassCastException {
283
284
         if (!(ob instanceof DeviationAndFactor)) {
285
            throw new ClassCastException();
286
         }
287
288
         final double dDeviation = ((DeviationAndFactor) ob).deviation;
289
         final double dDif = this.deviation - dDeviation;
290
291
         if (dDif > 0.0) {
292
            return 1;
293
         }
294
         else if (dDif < 0.0) {
295
            return -1;
296
         }
297
         else {
298
            return 0;
299
         }
300
301
      }
302
   }
303
304
}