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