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