root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / accCost / AccCostAlgorithm.java @ 59
History | View | Annotate | Download (9.46 KB)
1 |
package es.unex.sextante.gridAnalysis.accCost; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
|
5 |
import es.unex.sextante.core.GeoAlgorithm; |
6 |
import es.unex.sextante.core.AnalysisExtent; |
7 |
import es.unex.sextante.core.Sextante; |
8 |
import es.unex.sextante.dataObjects.IRasterLayer; |
9 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
10 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
11 |
import es.unex.sextante.rasterWrappers.GridCell; |
12 |
|
13 |
public class AccCostAlgorithm |
14 |
extends
|
15 |
GeoAlgorithm { |
16 |
|
17 |
public static final String COST = "COST"; |
18 |
public static final String FEATURES = "FEATURES"; |
19 |
public static final String ACCCOST = "ACCCOST"; |
20 |
public static final String CLOSESTPOINT = "CLOSESTPOINT"; |
21 |
public static final String DISTANCE = "DISTANCE"; |
22 |
|
23 |
private static final int NO_DATA = -1; |
24 |
|
25 |
public static final int EUCLIDEAN = 0; |
26 |
public static final int CHESSBOARD = 1; |
27 |
public static final int MANHATTAN = 2; |
28 |
public static final int CHAMFER = 3; |
29 |
public static final int WINDOW5X5 = 4; |
30 |
|
31 |
private int m_iNX, m_iNY; |
32 |
private int m_iDistance; |
33 |
private IRasterLayer m_Cost;
|
34 |
private IRasterLayer m_Features;
|
35 |
private IRasterLayer m_AccCost;
|
36 |
private IRasterLayer m_ClosestPoint;
|
37 |
private ArrayList m_CentralPoints, m_AdjPoints; |
38 |
|
39 |
|
40 |
@Override
|
41 |
public void defineCharacteristics() { |
42 |
|
43 |
final String[] sOptions = { Sextante.getText("Euclidean"), Sextante.getText("Chessboard"), Sextante.getText("Manhattan"), |
44 |
Sextante.getText("Chamfer_3-4"), " 5 X 5" }; |
45 |
setName(Sextante.getText("Accumulated_cost__isotropic"));
|
46 |
setGroup(Sextante.getText("Cost_distances_and_routes"));
|
47 |
setUserCanDefineAnalysisExtent(true);
|
48 |
setIsDeterminatedProcess(false);
|
49 |
|
50 |
try {
|
51 |
m_Parameters.addInputRasterLayer(COST, Sextante.getText("Unitary_cost"), true); |
52 |
m_Parameters.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true); |
53 |
addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
|
54 |
addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
|
55 |
m_Parameters.addSelection(DISTANCE, Sextante.getText("Type_of_distance"), sOptions);
|
56 |
|
57 |
} |
58 |
catch (final RepeatedParameterNameException e) { |
59 |
Sextante.addErrorToLog(e); |
60 |
} |
61 |
|
62 |
} |
63 |
|
64 |
|
65 |
@Override
|
66 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
67 |
|
68 |
int x, y;
|
69 |
int iPoint = 1; |
70 |
double dValue;
|
71 |
|
72 |
m_CentralPoints = new ArrayList(); |
73 |
m_AdjPoints = new ArrayList(); |
74 |
|
75 |
m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST); |
76 |
m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES); |
77 |
m_iDistance = m_Parameters.getParameterValueAsInt(DISTANCE); |
78 |
|
79 |
m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
|
80 |
m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
|
81 |
|
82 |
final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
|
83 |
|
84 |
m_Cost.setWindowExtent(extent); |
85 |
m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline); |
86 |
|
87 |
m_Features.setWindowExtent(extent); |
88 |
m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour); |
89 |
|
90 |
m_iNX = m_Cost.getNX(); |
91 |
m_iNY = m_Cost.getNY(); |
92 |
|
93 |
m_AccCost.setNoDataValue(NO_DATA); |
94 |
m_AccCost.assignNoData(); |
95 |
|
96 |
m_ClosestPoint.setNoDataValue(NO_DATA); |
97 |
m_ClosestPoint.assignNoData(); |
98 |
|
99 |
for (y = 0; y < m_iNY; y++) { |
100 |
for (x = 0; x < m_iNX; x++) { |
101 |
dValue = m_Features.getCellValueAsDouble(x, y); |
102 |
if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) { |
103 |
m_CentralPoints.add(new GridCell(x, y, iPoint));
|
104 |
m_AccCost.setCellValue(x, y, 0.0);
|
105 |
m_ClosestPoint.setCellValue(x, y, iPoint); |
106 |
iPoint++; |
107 |
} |
108 |
} |
109 |
} |
110 |
|
111 |
if (m_iDistance != WINDOW5X5) {
|
112 |
calculateCost3X3(); |
113 |
} |
114 |
else {
|
115 |
calculateCost5X5(); |
116 |
} |
117 |
|
118 |
return !m_Task.isCanceled();
|
119 |
|
120 |
} |
121 |
|
122 |
|
123 |
private void calculateCost5X5() { |
124 |
|
125 |
int i, j;
|
126 |
int iPt;
|
127 |
int iPoint;
|
128 |
int x, y, x2, y2;
|
129 |
double dAccCost;
|
130 |
double dCost;
|
131 |
double dPrevAccCost;
|
132 |
GridCell cell; |
133 |
|
134 |
final double dDist[][] = new double[5][5]; |
135 |
|
136 |
for (i = -2; i < 3; i++) { |
137 |
for (j = -1; j < 2; j++) { |
138 |
dDist[i + 2][j + 2] = Math.sqrt(i * i + j * j); |
139 |
} |
140 |
} |
141 |
|
142 |
|
143 |
while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) { |
144 |
for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) { |
145 |
cell = (GridCell) m_CentralPoints.get(iPt); |
146 |
x = cell.getX(); |
147 |
y = cell.getY(); |
148 |
iPoint = (int) cell.getValue();
|
149 |
for (i = -2; i < 3; i++) { |
150 |
for (j = -2; j < 3; j++) { |
151 |
x2 = x + i; |
152 |
y2 = y + j; |
153 |
dCost = getCostTo(x, y, i, j); |
154 |
if (dCost != NO_DATA) {
|
155 |
dAccCost = m_AccCost.getCellValueAsDouble(x, y); |
156 |
dAccCost += (dCost * dDist[i + 2][j + 2]); |
157 |
dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2); |
158 |
if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
|
159 |
m_AccCost.setCellValue(x2, y2, dAccCost); |
160 |
m_ClosestPoint.setCellValue(x2, y2, iPoint); |
161 |
m_AdjPoints.add(new GridCell(x2, y2, iPoint));
|
162 |
} |
163 |
} |
164 |
} |
165 |
} |
166 |
} |
167 |
|
168 |
m_CentralPoints = m_AdjPoints; |
169 |
m_AdjPoints = new ArrayList(); |
170 |
} |
171 |
|
172 |
} |
173 |
|
174 |
|
175 |
private double getCostTo(final int x, |
176 |
final int y, |
177 |
final int i, |
178 |
final int j) { |
179 |
|
180 |
int n, nMax;
|
181 |
int iCells = 0; |
182 |
double di, dj;
|
183 |
double dCost = 0; |
184 |
double dPartialCost;
|
185 |
|
186 |
if ((i == 0) && (j == 0)) { |
187 |
return 0; |
188 |
} |
189 |
|
190 |
if (i > j) {
|
191 |
dj = Math.abs((double) j / (double) i) * Math.signum(j); |
192 |
di = Math.signum(i);
|
193 |
nMax = Math.abs(i);
|
194 |
} |
195 |
else {
|
196 |
di = Math.abs((double) i / (double) j) * Math.signum(i); |
197 |
dj = Math.signum(j);
|
198 |
nMax = Math.abs(j);
|
199 |
} |
200 |
|
201 |
double ii = 0; |
202 |
double jj = 0; |
203 |
for (n = 0; n <= nMax; n++, ii += di, jj += dj) { |
204 |
dPartialCost = m_Cost.getCellValueAsDouble((int) (x + ii), (int) (y + jj)); |
205 |
if (m_Cost.isNoDataValue(dPartialCost) || (dPartialCost <= 0)) { |
206 |
return NO_DATA;
|
207 |
} |
208 |
else {
|
209 |
dCost += dPartialCost; |
210 |
iCells++; |
211 |
} |
212 |
} |
213 |
|
214 |
return dCost / iCells;
|
215 |
|
216 |
} |
217 |
|
218 |
|
219 |
private void calculateCost3X3() { |
220 |
|
221 |
int i, j;
|
222 |
int iPt;
|
223 |
int iPoint;
|
224 |
int x, y, x2, y2;
|
225 |
double dAccCost;
|
226 |
double dCost1, dCost2;
|
227 |
double dPrevAccCost;
|
228 |
GridCell cell; |
229 |
|
230 |
double dDist[][] = new double[3][3]; |
231 |
|
232 |
switch (m_iDistance) {
|
233 |
case EUCLIDEAN:
|
234 |
default:
|
235 |
for (i = -1; i < 2; i++) { |
236 |
for (j = -1; j < 2; j++) { |
237 |
dDist[i + 1][j + 1] = Math.sqrt(i * i + j * j); |
238 |
} |
239 |
} |
240 |
break;
|
241 |
case CHESSBOARD:
|
242 |
final double chessboard[][] = { { 1, 1, 1 }, { 1, 0, 1 }, { 1, 1, 1 } }; |
243 |
dDist = chessboard; |
244 |
break;
|
245 |
case MANHATTAN:
|
246 |
final double manhattan[][] = { { 2, 1, 2 }, { 1, 0, 1 }, { 2, 1, 2 } }; |
247 |
dDist = manhattan; |
248 |
break;
|
249 |
case CHAMFER:
|
250 |
final double chamfer[][] = { { 4, 3, 4 }, { 3, 0, 3 }, { 4, 3, 4 } }; |
251 |
dDist = chamfer; |
252 |
break;
|
253 |
} |
254 |
|
255 |
while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) { |
256 |
for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) { |
257 |
cell = (GridCell) m_CentralPoints.get(iPt); |
258 |
x = cell.getX(); |
259 |
y = cell.getY(); |
260 |
iPoint = (int) cell.getValue();
|
261 |
dCost1 = m_Cost.getCellValueAsDouble(x, y); |
262 |
for (i = -1; i < 2; i++) { |
263 |
for (j = -1; j < 2; j++) { |
264 |
x2 = x + i; |
265 |
y2 = y + j; |
266 |
dCost2 = m_Cost.getCellValueAsDouble(x2, y2); |
267 |
if (!m_Cost.isNoDataValue(dCost1) && !m_Cost.isNoDataValue(dCost2) && (dCost1 > 0) && (dCost2 > 0)) { |
268 |
dAccCost = m_AccCost.getCellValueAsDouble(x, y); |
269 |
dAccCost += ((dCost1 + dCost2) / 2.0 * dDist[i + 1][j + 1]); |
270 |
dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2); |
271 |
if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
|
272 |
m_AccCost.setCellValue(x2, y2, dAccCost); |
273 |
m_ClosestPoint.setCellValue(x2, y2, iPoint); |
274 |
m_AdjPoints.add(new GridCell(x2, y2, iPoint));
|
275 |
} |
276 |
} |
277 |
} |
278 |
} |
279 |
} |
280 |
|
281 |
m_CentralPoints = m_AdjPoints; |
282 |
m_AdjPoints = new ArrayList(); |
283 |
setProgressText(Integer.toString(m_CentralPoints.size()));
|
284 |
} |
285 |
} |
286 |
|
287 |
} |