Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / profiles / leastCostPath / LeastCostPathAlgorithm.java @ 59

History | View | Annotate | Download (6.27 KB)

1
package es.unex.sextante.profiles.leastCostPath;
2

    
3
import java.awt.geom.Point2D;
4
import java.util.ArrayList;
5

    
6
import com.vividsolutions.jts.geom.Coordinate;
7
import com.vividsolutions.jts.geom.GeometryFactory;
8
import com.vividsolutions.jts.geom.LineString;
9

    
10
import es.unex.sextante.additionalInfo.AdditionalInfoMultipleInput;
11
import es.unex.sextante.core.GeoAlgorithm;
12
import es.unex.sextante.core.AnalysisExtent;
13
import es.unex.sextante.core.OutputObjectsSet;
14
import es.unex.sextante.core.Sextante;
15
import es.unex.sextante.dataObjects.IRasterLayer;
16
import es.unex.sextante.dataObjects.IVectorLayer;
17
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
18
import es.unex.sextante.exceptions.RepeatedParameterNameException;
19
import es.unex.sextante.outputs.OutputVectorLayer;
20
import es.unex.sextante.profiles.profile.ProfileAlgorithm;
21
import es.unex.sextante.rasterWrappers.GridCell;
22

    
23
public class LeastCostPathAlgorithm
24
         extends
25
            GeoAlgorithm {
26

    
27
   private final static int   m_iOffsetX[]  = { 0, 1, 1, 1, 0, -1, -1, -1 };
28
   private final static int   m_iOffsetY[]  = { 1, 1, 0, -1, -1, -1, 0, 1 };
29

    
30
   public static final String GRAPH         = "GRAPH";
31
   public static final String PROFILEPOINTS = "PROFILEPOINTS";
32
   public static final String POINT         = "POINT";
33
   public static final String LAYERS        = "LAYERS";
34
   public static final String ACCCOST       = "ACCCOST";
35
   public static final String PROFILELINE   = "PROFILELINE";
36

    
37
   private IRasterLayer       m_Cost;
38

    
39

    
40
   @Override
41
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
42

    
43
      int iDirection;
44
      boolean bContinue = true;
45
      final String sNames[] = { "ID" };
46
      final Class types[] = { Integer.class };
47
      final Object[] value = new Object[1];
48

    
49
      final ArrayList layers = m_Parameters.getParameterValueAsArrayList(LAYERS);
50
      m_Cost = m_Parameters.getParameterValueAsRasterLayer(ACCCOST);
51
      Point2D pt = m_Parameters.getParameterValueAsPoint(POINT);
52
      m_Cost.setFullExtent();
53
      final AnalysisExtent extent = m_Cost.getWindowGridExtent();
54
      final GridCell cell = extent.getGridCoordsFromWorldCoords(pt);
55
      final ArrayList coords = new ArrayList();
56
      coords.add(new Coordinate(pt.getX(), pt.getY()));
57

    
58
      do {
59
         iDirection = getDirToNextDownslopeCell(cell.getX(), cell.getY());
60
         if (iDirection >= 0) {
61
            cell.setX(cell.getX() + m_iOffsetX[iDirection]);
62
            cell.setY(cell.getY() + m_iOffsetY[iDirection]);
63
            pt = extent.getWorldCoordsFromGridCoords(cell);
64
            coords.add(new Coordinate(pt.getX(), pt.getY()));
65
         }
66
         else {
67
            bContinue = false;
68
         }
69
      }
70
      while (bContinue && !m_Task.isCanceled());
71

    
72
      if (m_Task.isCanceled()) {
73
         return false;
74
      }
75

    
76
      if (coords.size() > 1) {
77
         final IVectorLayer lines = getNewVectorLayer(PROFILELINE, Sextante.getText("Profile"), IVectorLayer.SHAPE_TYPE_LINE,
78
                  types, sNames);
79
         value[0] = new Double(1);
80
         final GeometryFactory gf = new GeometryFactory();
81
         final Coordinate[] coordinates = new Coordinate[coords.size()];
82
         for (int i = 0; i < coordinates.length; i++) {
83
            coordinates[i] = (Coordinate) coords.get(i);
84
         }
85
         final LineString line = gf.createLineString(coordinates);
86
         lines.addFeature(line, value);
87
         try {
88
            lines.postProcess();//we have to do this to use this as input
89
         }
90
         catch (final Exception e) {
91
            throw new GeoAlgorithmExecutionException(e.getMessage());
92
         }
93
         final ProfileAlgorithm profile = new ProfileAlgorithm();
94
         profile.getParameters().getParameter(ProfileAlgorithm.DEM).setParameterValue(m_Cost);
95
         profile.getParameters().getParameter(ProfileAlgorithm.LAYERS).setParameterValue(layers);
96
         profile.getParameters().getParameter(ProfileAlgorithm.ROUTE).setParameterValue(lines);
97
         final OutputObjectsSet outputs = profile.getOutputObjects();
98
         outputs.getOutput(ProfileAlgorithm.PROFILEPOINTS).setOutputChannel(getOutputChannel(PROFILEPOINTS));
99
         if (profile.execute(m_Task, m_OutputFactory)) {
100
            final IVectorLayer profilePts = (IVectorLayer) outputs.getOutput(ProfileAlgorithm.PROFILEPOINTS).getOutputObject();
101
            m_OutputObjects.getOutput(PROFILEPOINTS).setOutputObject(profilePts);
102
         }
103
         else {
104
            return false;
105
         }
106
      }
107
      else {
108
         throw new GeoAlgorithmExecutionException("zero lines in layer");
109
      }
110

    
111
      return !m_Task.isCanceled();
112

    
113
   }
114

    
115

    
116
   @Override
117
   public void defineCharacteristics() {
118

    
119
      setName(Sextante.getText("Least_cost_path"));
120
      setGroup(Sextante.getText("Cost_distances_and_routes"));
121
      setUserCanDefineAnalysisExtent(false);
122

    
123
      try {
124
         m_Parameters.addInputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), true);
125
         m_Parameters.addMultipleInput(LAYERS, Sextante.getText("Additional_layers"),
126
                  AdditionalInfoMultipleInput.DATA_TYPE_RASTER, false);
127
         m_Parameters.addPoint(POINT, Sextante.getText("Starting_point"));
128
         addOutputVectorLayer(PROFILEPOINTS, Sextante.getText("Route_[points]"), OutputVectorLayer.SHAPE_TYPE_POINT);
129
         addOutputVectorLayer(PROFILELINE, Sextante.getText("Route_[line]"), OutputVectorLayer.SHAPE_TYPE_LINE);
130
      }
131
      catch (final RepeatedParameterNameException e) {
132
         Sextante.addErrorToLog(e);
133
      }
134

    
135
   }
136

    
137

    
138
   public int getDirToNextDownslopeCell(final int x,
139
                                        final int y) {
140

    
141
      int i, iDir;
142
      double z, z2, dSlope, dMaxSlope;
143

    
144
      z = m_Cost.getCellValueAsDouble(x, y);
145

    
146
      if (m_Cost.isNoDataValue(z)) {
147
         return -1;
148
      }
149

    
150
      dMaxSlope = 0.0;
151
      for (iDir = -1, i = 0; i < 8; i++) {
152
         z2 = m_Cost.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]);
153
         if (!m_Cost.isNoDataValue(z2)) {
154
            dSlope = (z - z2) / m_Cost.getDistToNeighborInDir(i);
155
            if (dSlope > dMaxSlope) {
156
               iDir = i;
157
               dMaxSlope = dSlope;
158
            }
159
         }
160
      }
161

    
162
      return iDir;
163

    
164
   }
165

    
166

    
167
}