root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridAnalysis / accCostAnisotropic / AccCostAnisotropicAlgorithm.java @ 59
History | View | Annotate | Download (8.75 KB)
1 |
package es.unex.sextante.gridAnalysis.accCostAnisotropic; |
---|---|
2 |
|
3 |
import java.util.ArrayList; |
4 |
|
5 |
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue; |
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.rasterWrappers.GridCell; |
13 |
|
14 |
public class AccCostAnisotropicAlgorithm |
15 |
extends
|
16 |
GeoAlgorithm { |
17 |
|
18 |
public static final String COST = "COST"; |
19 |
public static final String COSTDIR = "COSTDIR"; |
20 |
public static final String KFACTOR = "KFACTOR"; |
21 |
public static final String FEATURES = "FEATURES"; |
22 |
public static final String ACCCOST = "ACCCOST"; |
23 |
public static final String CLOSESTPOINT = "CLOSESTPOINT"; |
24 |
|
25 |
private final static int m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; |
26 |
private final static int m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 }; |
27 |
private final static double m_dDist[] = { 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.), 1, Math.sqrt(2.) }; |
28 |
|
29 |
private static final int NO_DATA = -1; |
30 |
private static final int DATA = 1; |
31 |
private static final double ANGLES[][] = { { 135, 180, 225 }, { 90, 0, 270 }, { 45, 0, 315 } }; |
32 |
|
33 |
private int m_iNX, m_iNY; |
34 |
private double m_dK; |
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_AdjPoints, m_CentralPoints; |
42 |
|
43 |
|
44 |
@Override
|
45 |
public void defineCharacteristics() { |
46 |
|
47 |
setName(Sextante.getText("Accumulated_cost__anisotropic"));
|
48 |
setGroup(Sextante.getText("Cost_distances_and_routes"));
|
49 |
setUserCanDefineAnalysisExtent(true);
|
50 |
setIsDeterminatedProcess(false);
|
51 |
|
52 |
try {
|
53 |
m_Parameters.addInputRasterLayer(COST, Sextante.getText("Maximum_unitary_cost"), true); |
54 |
m_Parameters.addInputRasterLayer(COSTDIR, Sextante.getText("Direction_of_maximum_cost_[degrees]"), true); |
55 |
m_Parameters.addInputRasterLayer(FEATURES, Sextante.getText("Origin-destination_points"), true); |
56 |
m_Parameters.addNumericalValue(KFACTOR, Sextante.getText("K"), 2, AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE); |
57 |
addOutputRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"));
|
58 |
addOutputRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"));
|
59 |
} |
60 |
catch (final RepeatedParameterNameException e) { |
61 |
Sextante.addErrorToLog(e); |
62 |
} |
63 |
|
64 |
} |
65 |
|
66 |
|
67 |
@Override
|
68 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
69 |
|
70 |
int x, y;
|
71 |
int iPoint = 1; |
72 |
double dValue;
|
73 |
|
74 |
m_Cost = m_Parameters.getParameterValueAsRasterLayer(COST); |
75 |
m_CostDir = m_Parameters.getParameterValueAsRasterLayer(COSTDIR); |
76 |
m_Features = m_Parameters.getParameterValueAsRasterLayer(FEATURES); |
77 |
|
78 |
m_AdjPoints = new ArrayList(); |
79 |
m_CentralPoints = new ArrayList(); |
80 |
|
81 |
m_dK = m_Parameters.getParameterValueAsDouble(KFACTOR); |
82 |
|
83 |
m_AccCost = getNewRasterLayer(ACCCOST, Sextante.getText("Accumulated_cost"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
|
84 |
m_ClosestPoint = getNewRasterLayer(CLOSESTPOINT, Sextante.getText("Closest_points"), IRasterLayer.RASTER_DATA_TYPE_INT);
|
85 |
|
86 |
final AnalysisExtent extent = m_AccCost.getWindowGridExtent();
|
87 |
|
88 |
m_Cost.setWindowExtent(extent); |
89 |
m_Cost.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline); |
90 |
|
91 |
m_CostDir.setWindowExtent(extent); |
92 |
m_CostDir.setInterpolationMethod(IRasterLayer.INTERPOLATION_BSpline); |
93 |
|
94 |
m_Features.setWindowExtent(extent); |
95 |
m_Features.setInterpolationMethod(IRasterLayer.INTERPOLATION_NearestNeighbour); |
96 |
|
97 |
m_iNX = m_Cost.getNX(); |
98 |
m_iNY = m_Cost.getNY(); |
99 |
|
100 |
m_AccCost.setNoDataValue(NO_DATA); |
101 |
m_AccCost.assignNoData(); |
102 |
|
103 |
m_Points = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent); |
104 |
|
105 |
m_Points2 = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_INT, extent); |
106 |
|
107 |
m_Points.setNoDataValue(NO_DATA); |
108 |
m_Points.assignNoData(); |
109 |
|
110 |
m_Points2.setNoDataValue(NO_DATA); |
111 |
m_Points2.assignNoData(); |
112 |
|
113 |
m_ClosestPoint.assign(0);
|
114 |
|
115 |
for (y = 0; y < m_iNY; y++) { |
116 |
for (x = 0; x < m_iNX; x++) { |
117 |
dValue = m_Features.getCellValueAsDouble(x, y); |
118 |
if ((dValue != 0.0) && !m_Features.isNoDataValue(dValue)) { |
119 |
m_Points.setCellValue(x, y, DATA); |
120 |
m_CentralPoints.add(new GridCell(x, y, iPoint));
|
121 |
m_AccCost.setCellValue(x, y, 0.0);
|
122 |
m_ClosestPoint.setCellValue(x, y, iPoint); |
123 |
iPoint++; |
124 |
} |
125 |
} |
126 |
} |
127 |
|
128 |
calculateCost(); |
129 |
|
130 |
return !m_Task.isCanceled();
|
131 |
|
132 |
} |
133 |
|
134 |
|
135 |
private void calculateCost() { |
136 |
|
137 |
int i;
|
138 |
int iPt;
|
139 |
int iPoint;
|
140 |
int x, y, x2, y2;
|
141 |
double dAccCost;
|
142 |
double dPrevAccCost;
|
143 |
GridCell cell; |
144 |
|
145 |
while ((m_CentralPoints.size() != 0) && !m_Task.isCanceled()) { |
146 |
for (iPt = 0; iPt < m_CentralPoints.size(); iPt++) { |
147 |
cell = (GridCell) m_CentralPoints.get(iPt); |
148 |
x = cell.getX(); |
149 |
y = cell.getY(); |
150 |
iPoint = (int) cell.getValue();
|
151 |
if (m_Points.getCellValueAsInt(x, y) == DATA) {
|
152 |
m_Points.setCellValue(x, y, NO_DATA); |
153 |
for (i = 0; i < 8; i++) { |
154 |
x2 = x + m_iOffsetX[i]; |
155 |
y2 = y + m_iOffsetY[i]; |
156 |
dAccCost = m_AccCost.getCellValueAsDouble(x, y); |
157 |
dPrevAccCost = m_AccCost.getCellValueAsDouble(x2, y2); |
158 |
if ((dPrevAccCost > dAccCost) || m_AccCost.isNoDataValue(dPrevAccCost)) {
|
159 |
final double dCostInDir = getCostInDir(x, y, m_iOffsetX[i], m_iOffsetY[i]); |
160 |
if (dCostInDir != NO_DATA) {
|
161 |
dAccCost += dCostInDir * m_dDist[i]; |
162 |
if (m_AccCost.isNoDataValue(dPrevAccCost) || (dPrevAccCost > dAccCost)) {
|
163 |
m_AccCost.setCellValue(x2, y2, dAccCost); |
164 |
m_ClosestPoint.setCellValue(x2, y2, iPoint); |
165 |
if (m_Points2.getCellValueAsInt(x2, y2) == NO_DATA) {
|
166 |
m_Points2.setCellValue(x2, y2, DATA); |
167 |
m_AdjPoints.add(new GridCell(x2, y2, iPoint));
|
168 |
} |
169 |
} |
170 |
} |
171 |
} |
172 |
} |
173 |
} |
174 |
} |
175 |
|
176 |
final IRasterLayer swap = m_Points;
|
177 |
m_Points = m_Points2; |
178 |
m_Points2 = swap; |
179 |
|
180 |
m_CentralPoints = m_AdjPoints; |
181 |
m_AdjPoints = new ArrayList(); |
182 |
|
183 |
setProgressText(Integer.toString(m_AdjPoints.size()));
|
184 |
|
185 |
} |
186 |
} |
187 |
|
188 |
|
189 |
private double getCostInDir(final int x, |
190 |
final int y, |
191 |
final int iH, |
192 |
final int iV) { |
193 |
|
194 |
final double dAngle = ANGLES[iV + 1][iH + 1]; |
195 |
|
196 |
final int x2 = x + iH; |
197 |
final int y2 = y + iV; |
198 |
|
199 |
double dCost1 = m_Cost.getCellValueAsDouble(x, y);
|
200 |
double dCost2 = m_Cost.getCellValueAsDouble(x2, y2);
|
201 |
|
202 |
final double dCostDir1 = m_CostDir.getCellValueAsDouble(x, y); |
203 |
final double dCostDir2 = m_CostDir.getCellValueAsDouble(x2, y2); |
204 |
|
205 |
if (m_Cost.isNoDataValue(dCost1) || m_Cost.isNoDataValue(dCost2) || m_CostDir.isNoDataValue(dCostDir1)
|
206 |
|| m_CostDir.isNoDataValue(dCostDir2) || (dCost1 <= 0) || (dCost2 <= 0)) { |
207 |
return NO_DATA;
|
208 |
} |
209 |
else {
|
210 |
double dDifAngle1 = Math.abs(dCostDir1 - dAngle); |
211 |
double dDifAngle2 = Math.abs(dCostDir2 - dAngle); |
212 |
|
213 |
dDifAngle1 = Math.toRadians(dDifAngle1);
|
214 |
dDifAngle2 = Math.toRadians(dDifAngle2);
|
215 |
|
216 |
final double dCos1 = Math.cos(dDifAngle1); |
217 |
final double dCos2 = Math.cos(dDifAngle2); |
218 |
|
219 |
final int dSgn1 = signum(dCos1); |
220 |
final int dSgn2 = signum(dCos2); |
221 |
|
222 |
final double dExp1 = dSgn1 * Math.pow(Math.abs(dCos1), m_dK); |
223 |
final double dExp2 = dSgn2 * Math.pow(Math.abs(dCos2), m_dK); |
224 |
|
225 |
dCost1 = Math.pow(dCost1, dExp1) / 2.; |
226 |
dCost2 = Math.pow(dCost2, dExp2) / 2.; |
227 |
|
228 |
return dCost1 + dCost2;
|
229 |
} |
230 |
|
231 |
} |
232 |
|
233 |
|
234 |
private int signum(final double difAngle) { |
235 |
|
236 |
if (difAngle < 0) { |
237 |
return -1; |
238 |
} |
239 |
else {
|
240 |
return 1; |
241 |
} |
242 |
|
243 |
} |
244 |
|
245 |
} |