root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / costInRoutes / CostInRoutesAlgorithm.java @ 59
History | View | Annotate | Download (5.51 KB)
1 |
package es.unex.sextante.gridAnalysis.costInRoutes; |
---|---|
2 |
|
3 |
|
4 |
import com.vividsolutions.jts.geom.Coordinate; |
5 |
import com.vividsolutions.jts.geom.Geometry; |
6 |
|
7 |
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
8 |
import es.unex.sextante.core.GeoAlgorithm; |
9 |
import es.unex.sextante.core.Sextante; |
10 |
import es.unex.sextante.dataObjects.IFeature; |
11 |
import es.unex.sextante.dataObjects.IFeatureIterator; |
12 |
import es.unex.sextante.dataObjects.IRasterLayer; |
13 |
import es.unex.sextante.dataObjects.IVectorLayer; |
14 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
15 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
16 |
import es.unex.sextante.outputs.IOutputChannel; |
17 |
import es.unex.sextante.outputs.Output; |
18 |
import es.unex.sextante.outputs.OutputVectorLayer; |
19 |
import es.unex.sextante.shapesTools.ShapesTools; |
20 |
|
21 |
public class CostInRoutesAlgorithm |
22 |
extends
|
23 |
GeoAlgorithm { |
24 |
|
25 |
public static final String ROUTES = "ROUTES"; |
26 |
public static final String COST = "COST"; |
27 |
public static final String RESULT = "RESULT"; |
28 |
|
29 |
private IRasterLayer m_Cost;
|
30 |
private double[] m_dDist; |
31 |
private double[] m_dCost; |
32 |
private double m_dLastX, m_dLastY; |
33 |
private int m_iPoints = 0; |
34 |
private int m_iCurrentRoute; |
35 |
|
36 |
|
37 |
@Override
|
38 |
public void defineCharacteristics() { |
39 |
|
40 |
setName(Sextante.getText("Cost_for_predefined_routes"));
|
41 |
setGroup(Sextante.getText("Cost_distances_and_routes"));
|
42 |
setUserCanDefineAnalysisExtent(true);
|
43 |
|
44 |
try {
|
45 |
m_Parameters.addInputVectorLayer(ROUTES, Sextante.getText("Routes"), AdditionalInfoVectorLayer.SHAPE_TYPE_LINE, true); |
46 |
m_Parameters.addInputRasterLayer(COST, Sextante.getText("Cost"), true); |
47 |
addOutputVectorLayer(RESULT, Sextante.getText("Routes_and_cost"));
|
48 |
} |
49 |
catch (final RepeatedParameterNameException e) { |
50 |
Sextante.addErrorToLog(e); |
51 |
} |
52 |
|
53 |
} |
54 |
|
55 |
|
56 |
@Override
|
57 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
58 |
|
59 |
final IVectorLayer routes = m_Parameters.getParameterValueAsVectorLayer(ROUTES);
|
60 |
m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST); |
61 |
|
62 |
if (routes.getShapesCount() == 0) { |
63 |
return false; |
64 |
} |
65 |
|
66 |
final int iShapesCount = routes.getShapesCount(); |
67 |
m_iCurrentRoute = 0;
|
68 |
m_Cost.setFullExtent(); |
69 |
m_dCost = new double[routes.getShapesCount()]; |
70 |
m_dDist = new double[routes.getShapesCount()]; |
71 |
final IFeatureIterator iter = routes.iterator();
|
72 |
while (iter.hasNext() && setProgress(m_iCurrentRoute, iShapesCount)) {
|
73 |
m_iPoints = 0;
|
74 |
final IFeature feature = iter.next();
|
75 |
final Geometry geom = feature.getGeometry();
|
76 |
processLine(geom.getCoordinates()); |
77 |
m_iCurrentRoute++; |
78 |
} |
79 |
iter.close(); |
80 |
|
81 |
if (m_Task.isCanceled()) {
|
82 |
return false; |
83 |
} |
84 |
|
85 |
final Object[][] values = new Object[2][routes.getShapesCount()]; |
86 |
final String[] sFields = { Sextante.getText("Distance"), Sextante.getText("Cost") }; |
87 |
final Class[] types = { Double.class, Double.class }; |
88 |
for (int i = 0; i < routes.getShapesCount(); i++) { |
89 |
values[0][i] = new Double(m_dDist[i]); |
90 |
values[1][i] = new Double(m_dCost[i]); |
91 |
} |
92 |
final IOutputChannel channel = getOutputChannel(RESULT);
|
93 |
final Output out = new OutputVectorLayer(); |
94 |
out.setName(RESULT); |
95 |
out.setDescription(Sextante.getText("Routes"));
|
96 |
out.setOutputChannel(channel); |
97 |
out.setOutputObject(ShapesTools.addFields(m_OutputFactory, routes, channel, sFields, values, types)); |
98 |
addOutputObject(out); |
99 |
|
100 |
return true; |
101 |
|
102 |
} |
103 |
|
104 |
|
105 |
private void processLine(final Coordinate coords[]) { |
106 |
|
107 |
int i;
|
108 |
double x, y, x2, y2;
|
109 |
|
110 |
for (i = 0; i < coords.length - 1; i++) { |
111 |
x = coords[i].x; |
112 |
y = coords[i].y; |
113 |
x2 = coords[i + 1].x;
|
114 |
y2 = coords[i + 1].y;
|
115 |
processSegment(x, y, x2, y2); |
116 |
} |
117 |
|
118 |
} |
119 |
|
120 |
|
121 |
private void processSegment(double x, |
122 |
double y,
|
123 |
final double x2, |
124 |
final double y2) { |
125 |
|
126 |
double dx, dy, d, n;
|
127 |
|
128 |
dx = Math.abs(x2 - x);
|
129 |
dy = Math.abs(y2 - y);
|
130 |
|
131 |
if ((dx > 0.0) || (dy > 0.0)) { |
132 |
if (dx > dy) {
|
133 |
dx /= m_Cost.getWindowCellSize(); |
134 |
n = dx; |
135 |
dy /= dx; |
136 |
dx = m_Cost.getWindowCellSize(); |
137 |
} |
138 |
else {
|
139 |
dy /= m_Cost.getWindowCellSize(); |
140 |
n = dy; |
141 |
dx /= dy; |
142 |
dy = m_Cost.getWindowCellSize(); |
143 |
} |
144 |
|
145 |
if (x2 < x) {
|
146 |
dx = -dx; |
147 |
} |
148 |
|
149 |
if (y2 < y) {
|
150 |
dy = -dy; |
151 |
} |
152 |
|
153 |
for (d = 0.0; d <= n; d++, x += dx, y += dy) { |
154 |
addPoint(x, y); |
155 |
} |
156 |
} |
157 |
|
158 |
} |
159 |
|
160 |
|
161 |
private void addPoint(final double x, |
162 |
final double y) { |
163 |
|
164 |
double dDX, dDY;
|
165 |
|
166 |
final double z = m_Cost.getValueAt(x, y); |
167 |
|
168 |
if (m_iPoints == 0) { |
169 |
m_dDist[m_iCurrentRoute] = 0.0;
|
170 |
m_dCost[m_iCurrentRoute] = 0.0;
|
171 |
} |
172 |
else {
|
173 |
dDX = x - m_dLastX; |
174 |
dDY = y - m_dLastY; |
175 |
m_dDist[m_iCurrentRoute] += Math.sqrt(dDX * dDX + dDY * dDY);
|
176 |
if (!m_Cost.isNoDataValue(z)) {
|
177 |
m_dCost[m_iCurrentRoute] += z; |
178 |
} |
179 |
} |
180 |
|
181 |
m_dLastX = x; |
182 |
m_dLastY = y; |
183 |
m_iPoints++; |
184 |
|
185 |
} |
186 |
|
187 |
} |