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
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
}