root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / accCostAnisotropicB / AccCostAnisotropicBAlgorithm.java @ 59
History | View | Annotate | Download (9.67 KB)
1 |
package es.unex.sextante.gridAnalysis.accCostAnisotropicB; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
import java.util.Arrays; |
5 |
|
6 |
import es.unex.sextante.core.GeoAlgorithm; |
7 |
import es.unex.sextante.core.AnalysisExtent; |
8 |
import es.unex.sextante.core.Sextante; |
9 |
import es.unex.sextante.dataObjects.IRasterLayer; |
10 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
11 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
12 |
import es.unex.sextante.parameters.FixedTableModel; |
13 |
import es.unex.sextante.rasterWrappers.GridCell; |
14 |
|
15 |
public class AccCostAnisotropicBAlgorithm |
16 |
extends
|
17 |
GeoAlgorithm { |
18 |
|
19 |
public static final String COST = "COST"; |
20 |
public static final String COSTDIR = "COSTDIR"; |
21 |
public static final String FEATURES = "FEATURES"; |
22 |
public static final String ACCCOST = "ACCCOST"; |
23 |
public static final String CLOSESTPOINT = "CLOSESTPOINT"; |
24 |
public static final String FACTORS = "FACTORS"; |
25 |
|
26 |
private static final int NO_DATA = -1; |
27 |
private static final int DATA = 1; |
28 |
private static final double ANGLES[][] = { { 135, 180, 225 }, { 90, 0, 270 }, { 45, 0, 315 } }; |
29 |
|
30 |
private final static int m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; |
31 |
private final static int m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 }; |
32 |
private final static double m_dDist[] = { 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.) }; |
33 |
|
34 |
private int m_iNX, m_iNY; |
35 |
private IRasterLayer m_Cost;
|
36 |
private IRasterLayer m_CostDir;
|
37 |
private IRasterLayer m_Features;
|
38 |
private IRasterLayer m_AccCost;
|
39 |
private IRasterLayer m_ClosestPoint;
|
40 |
private IRasterLayer m_Points, m_Points2;
|
41 |
private ArrayList m_CentralPoints, m_AdjPoints; |
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("Accumulated_cost__anisotropic") + "(B)"); |
51 |
setGroup(Sextante.getText("Cost_distances_and_routes"));
|
52 |
setUserCanDefineAnalysisExtent(true);
|
53 |
setIsDeterminatedProcess(false);
|
54 |
|
55 |
try {
|
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.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true); |
59 |
m_Parameters.addFixedTable(FACTORS, Sextante.getText("Cost_variation_factors"), sColumnNames, 5, false); |
60 |
addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
|
61 |
addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
|
62 |
} |
63 |
catch (final RepeatedParameterNameException e) { |
64 |
Sextante.addErrorToLog(e); |
65 |
} |
66 |
|
67 |
} |
68 |
|
69 |
|
70 |
@Override
|
71 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
72 |
|
73 |
int x, y;
|
74 |
int iPoint = 1; |
75 |
double dValue;
|
76 |
|
77 |
m_CentralPoints = new ArrayList(); |
78 |
m_AdjPoints = new ArrayList(); |
79 |
|
80 |
m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST); |
81 |
m_CostDir = m_Parameters.getParameterValueAsRasterLayer(COSTDIR); |
82 |
m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES); |
83 |
|
84 |
final FixedTableModel factors = (FixedTableModel) m_Parameters.getParameterValueAsObject(FACTORS);
|
85 |
|
86 |
m_Factors = new DeviationAndFactor[factors.getRowCount()];
|
87 |
for (int i = 0; i < factors.getRowCount(); i++) { |
88 |
final double dDeviation = Double.parseDouble(factors.getValueAt(i, 0).toString()); |
89 |
final double dFactor = Double.parseDouble(factors.getValueAt(i, 1).toString()); |
90 |
m_Factors[i] = new DeviationAndFactor(dDeviation, dFactor);
|
91 |
} |
92 |
|
93 |
Arrays.sort(m_Factors);
|
94 |
|
95 |
m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
|
96 |
m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
|
97 |
|
98 |
final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
|
99 |
|
100 |
m_Cost.setWindowExtent(extent); |
101 |
m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline); |
102 |
|
103 |
m_CostDir.setWindowExtent(extent); |
104 |
m_CostDir.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline); |
105 |
|
106 |
m_Features.setWindowExtent(extent); |
107 |
m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour); |
108 |
|
109 |
m_iNX = m_Cost.getNX(); |
110 |
m_iNY = m_Cost.getNY(); |
111 |
|
112 |
m_Points = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent); |
113 |
|
114 |
m_Points2 = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent); |
115 |
|
116 |
m_Points.setNoDataValue(NO_DATA); |
117 |
m_Points.assignNoData(); |
118 |
|
119 |
m_Points2.setNoDataValue(NO_DATA); |
120 |
m_Points2.assignNoData(); |
121 |
|
122 |
m_AccCost.setNoDataValue(NO_DATA); |
123 |
m_AccCost.assignNoData(); |
124 |
|
125 |
m_ClosestPoint.setNoDataValue(NO_DATA); |
126 |
m_ClosestPoint.assignNoData(); |
127 |
|
128 |
for (y = 0; y < m_iNY; y++) { |
129 |
for (x = 0; x < m_iNX; x++) { |
130 |
dValue = m_Features.getCellValueAsDouble(x, y); |
131 |
if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) { |
132 |
m_CentralPoints.add(new GridCell(x, y, iPoint));
|
133 |
m_AccCost.setCellValue(x, y, 0.0);
|
134 |
m_ClosestPoint.setCellValue(x, y, iPoint); |
135 |
iPoint++; |
136 |
} |
137 |
} |
138 |
} |
139 |
|
140 |
calculateCost(); |
141 |
|
142 |
return !m_Task.isCanceled();
|
143 |
|
144 |
} |
145 |
|
146 |
|
147 |
private void calculateCost() { |
148 |
|
149 |
int i;
|
150 |
int iPt;
|
151 |
int iPoint;
|
152 |
int x, y, x2, y2;
|
153 |
double dAccCost;
|
154 |
double dPrevAccCost;
|
155 |
GridCell cell; |
156 |
|
157 |
while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) { |
158 |
for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) { |
159 |
cell = (GridCell) m_CentralPoints.get(iPt); |
160 |
x = cell.getX(); |
161 |
y = cell.getY(); |
162 |
iPoint = (int) cell.getValue();
|
163 |
if (m_Points.getCellValueAsInt(x, y) == DATA) {
|
164 |
m_Points.setCellValue(x, y, NO_DATA); |
165 |
for (i = 0; i < 8; i++) { |
166 |
x2 = x + m_iOffsetX[i]; |
167 |
y2 = y + m_iOffsetY[i]; |
168 |
dAccCost = m_AccCost.getCellValueAsDouble(x, y); |
169 |
dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2); |
170 |
if ((dPrevAccCost > dAccCost) || m_AccCost.isNoDataValue(dPrevAccCost)) {
|
171 |
final double dCostInDir = getCostInDir(x, y, m_iOffsetX[i], m_iOffsetY[i]); |
172 |
if (dCostInDir != NO_DATA) {
|
173 |
dAccCost += dCostInDir * m_dDist[i]; |
174 |
if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
|
175 |
m_AccCost.setCellValue(x2, y2, dAccCost); |
176 |
m_ClosestPoint.setCellValue(x2, y2, iPoint); |
177 |
if (m_Points2.getCellValueAsInt(x2, y2) == NO_DATA) {
|
178 |
m_Points2.setCellValue(x2, y2, DATA); |
179 |
m_AdjPoints.add(new GridCell(x2, y2, iPoint));
|
180 |
} |
181 |
} |
182 |
} |
183 |
} |
184 |
} |
185 |
} |
186 |
} |
187 |
|
188 |
final IRasterLayer swap = m_Points;
|
189 |
m_Points = m_Points2; |
190 |
m_Points2 = swap; |
191 |
|
192 |
m_CentralPoints = m_AdjPoints; |
193 |
m_AdjPoints = new ArrayList(); |
194 |
|
195 |
setProgressText(Integer.toString(m_AdjPoints.size()));
|
196 |
|
197 |
} |
198 |
} |
199 |
|
200 |
|
201 |
private double getCostInDir(final int x, |
202 |
final int y, |
203 |
final int iH, |
204 |
final int iV) { |
205 |
|
206 |
final double dAngle = ANGLES[iV + 1][iH + 1]; |
207 |
|
208 |
final int x2 = x + iH; |
209 |
final int y2 = y + iV; |
210 |
|
211 |
final double dCostDir1 = m_CostDir.getCellValueAsDouble(x, y); |
212 |
final double dCostDir2 = m_CostDir.getCellValueAsDouble(x2, y2); |
213 |
double dCost1 = m_Cost.getCellValueAsDouble(x, y);
|
214 |
double dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
|
215 |
|
216 |
if (m_Cost.isNoDataValue(dCost1) || m_Cost.isNoDataValue(dCost1) || m_CostDir.isNoDataValue(dCostDir1)
|
217 |
|| m_CostDir.isNoDataValue(dCostDir1)) { |
218 |
return NO_DATA;
|
219 |
} |
220 |
else {
|
221 |
final double dDifAngle1 = Math.abs(dCostDir1 - dAngle); |
222 |
final double dDifAngle2 = Math.abs(dCostDir2 - dAngle); |
223 |
|
224 |
dCost1 = getWeigthedCost(dCost1, dDifAngle1); |
225 |
dCost2 = getWeigthedCost(dCost2, dDifAngle2); |
226 |
|
227 |
return dCost1 + dCost2;
|
228 |
} |
229 |
|
230 |
} |
231 |
|
232 |
|
233 |
private double getWeigthedCost(final double cost, |
234 |
final double difAngle) { |
235 |
|
236 |
for (int i = 0; i < m_Factors.length - 1; i++) { |
237 |
if ((m_Factors[i].deviation < difAngle) || (m_Factors[i + 1].deviation >= difAngle)) { |
238 |
return m_Factors[i].factor * cost / 2.; |
239 |
} |
240 |
} |
241 |
|
242 |
return cost / 2.; |
243 |
|
244 |
} |
245 |
|
246 |
private class DeviationAndFactor |
247 |
implements
|
248 |
Comparable {
|
249 |
|
250 |
public double factor; |
251 |
public double deviation; |
252 |
|
253 |
|
254 |
DeviationAndFactor(final double dDeviation, |
255 |
final double dFactor) { |
256 |
|
257 |
deviation = dDeviation; |
258 |
factor = dFactor; |
259 |
} |
260 |
|
261 |
|
262 |
public int compareTo(final Object ob) throws ClassCastException { |
263 |
|
264 |
if (!(ob instanceof DeviationAndFactor)) { |
265 |
throw new ClassCastException(); |
266 |
} |
267 |
|
268 |
final double dDeviation = ((DeviationAndFactor) ob).deviation; |
269 |
final double dDif = this.deviation - dDeviation; |
270 |
|
271 |
if (dDif > 0.0) { |
272 |
return 1; |
273 |
} |
274 |
else if (dDif < 0.0) { |
275 |
return -1; |
276 |
} |
277 |
else {
|
278 |
return 0; |
279 |
} |
280 |
|
281 |
} |
282 |
} |
283 |
|
284 |
} |