root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / morphometry / aspect / AspectAlgorithm.java @ 59
History | View | Annotate | Download (14.4 KB)
1 |
package es.unex.sextante.morphometry.aspect; |
---|---|
2 |
|
3 |
|
4 |
import es.unex.sextante.core.GeoAlgorithm; |
5 |
import es.unex.sextante.core.AnalysisExtent; |
6 |
import es.unex.sextante.core.Sextante; |
7 |
import es.unex.sextante.dataObjects.IRasterLayer; |
8 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
9 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
10 |
|
11 |
public class AspectAlgorithm |
12 |
extends
|
13 |
GeoAlgorithm { |
14 |
|
15 |
private final static int m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; |
16 |
private final static int m_iOffsetY[] = { -1, -1, 0, 1, 1, 1, 0, -1 }; |
17 |
|
18 |
public static final String ASPECT = "ASPECT"; |
19 |
public static final String METHOD = "METHOD"; |
20 |
public static final String UNITS = "UNITS"; |
21 |
public static final String DEM = "DEM"; |
22 |
|
23 |
public final static int UNITS_RADIANS = 0; |
24 |
public final static int UNITS_DEGREES = 1; |
25 |
public final static int UNITS_PERCENTAGE = 2; |
26 |
|
27 |
public final static int METHOD_MAXIMUM_SLOPE = 0; |
28 |
public final static int METHOD_TARBOTON = 1; |
29 |
public final static int METHOD_BURGESS = 2; |
30 |
public final static int METHOD_BAUER = 3; |
31 |
public final static int METHOD_HEERDEGEN = 4; |
32 |
public final static int METHOD_ZEVENBERGEN = 5; |
33 |
public final static int METHOD_HARALICK = 6; |
34 |
|
35 |
private static final double DEG_45_IN_RAD = Math.toRadians(45); |
36 |
private static final double DEG_90_IN_RAD = Math.toRadians(90); |
37 |
private static final double DEG_180_IN_RAD = Math.toRadians(180); |
38 |
private static final double DEG_270_IN_RAD = Math.toRadians(270); |
39 |
|
40 |
IRasterLayer m_DEM = null;
|
41 |
IRasterLayer m_Aspect; |
42 |
|
43 |
private double _6DX; |
44 |
private double _2DX; |
45 |
|
46 |
private int m_iUnits; |
47 |
|
48 |
|
49 |
@Override
|
50 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
51 |
|
52 |
int x, y;
|
53 |
int iNX, iNY;
|
54 |
|
55 |
final int iMethod = m_Parameters.getParameterValueAsInt(METHOD); |
56 |
|
57 |
m_iUnits = m_Parameters.getParameterValueAsInt(UNITS); |
58 |
|
59 |
m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM); |
60 |
|
61 |
m_Aspect = getNewRasterLayer(ASPECT, Sextante.getText("Aspect"), IRasterLayer.RASTER_DATA_TYPE_FLOAT);
|
62 |
|
63 |
final AnalysisExtent extent = m_Aspect.getWindowGridExtent();
|
64 |
|
65 |
m_DEM.setWindowExtent(extent); |
66 |
|
67 |
iNX = m_DEM.getNX(); |
68 |
iNY = m_DEM.getNY(); |
69 |
|
70 |
_2DX = m_DEM.getWindowCellSize() * 2.;
|
71 |
_6DX = m_DEM.getWindowCellSize() * 6.;
|
72 |
|
73 |
for (y = 0; (y < iNY) && setProgress(y, iNY); y++) { |
74 |
for (x = 0; x < iNX; x++) { |
75 |
switch (iMethod) {
|
76 |
case 0: |
77 |
Do_MaximumSlope(x, y); |
78 |
break;
|
79 |
|
80 |
case 1: |
81 |
Do_Tarboton(x, y); |
82 |
break;
|
83 |
|
84 |
case 2: |
85 |
Do_LeastSquare(x, y); |
86 |
break;
|
87 |
|
88 |
case 3: |
89 |
Do_FD_BRM(x, y); |
90 |
break;
|
91 |
|
92 |
case 4: |
93 |
Do_FD_Heerdegen(x, y); |
94 |
break;
|
95 |
|
96 |
case 5: |
97 |
Do_FD_Zevenbergen(x, y); |
98 |
break;
|
99 |
|
100 |
case 6: |
101 |
Do_FD_Haralick(x, y); |
102 |
break;
|
103 |
} |
104 |
} |
105 |
} |
106 |
|
107 |
return !m_Task.isCanceled();
|
108 |
|
109 |
} |
110 |
|
111 |
|
112 |
@Override
|
113 |
public void defineCharacteristics() { |
114 |
|
115 |
final String[] sMethod = { Sextante.getText("M\u00e1ximum_slope__Travis_et_al_1975"), |
116 |
Sextante.getText("Maximum_Triangle_Slope__Tarboton_1997"),
|
117 |
Sextante.getText("Plane_fitting__Costa-Cabral_&_Burgess_1996"),
|
118 |
Sextante.getText("Fit_2_Degree_Polynom__Bauer_Rohdenburg_Bork_1985"),
|
119 |
Sextante.getText("Fit_2_Degree_Polynom__Heerdegen_&_Beran_1982"),
|
120 |
Sextante.getText("Fit_2_Degree_Polynom__Zevenbergen_&_Thorne_1987"),
|
121 |
Sextante.getText("Fit_3_Degree_Polynom__Haralick_1983") };
|
122 |
|
123 |
final String[] sUnits = { Sextante.getText("Radians"), Sextante.getText("Degrees") }; |
124 |
|
125 |
setName(Sextante.getText("Aspect"));
|
126 |
setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
|
127 |
setUserCanDefineAnalysisExtent(true);
|
128 |
|
129 |
try {
|
130 |
m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true); |
131 |
|
132 |
m_Parameters.addSelection(UNITS, Sextante.getText("Units"), sUnits);
|
133 |
|
134 |
m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
|
135 |
addOutputRasterLayer(ASPECT, Sextante.getText("Aspect"));
|
136 |
} |
137 |
catch (final RepeatedParameterNameException e) { |
138 |
Sextante.addErrorToLog(e); |
139 |
} |
140 |
|
141 |
} |
142 |
|
143 |
|
144 |
private void Do_MaximumSlope(final int x, |
145 |
final int y) { |
146 |
|
147 |
int i, Aspect;
|
148 |
double z, z2, dSlope, dMaxSlope;
|
149 |
|
150 |
z = m_DEM.getCellValueAsDouble(x, y); |
151 |
|
152 |
if (m_DEM.isNoDataValue(z)) {
|
153 |
Set_Parameters_NoData(x, y); |
154 |
} |
155 |
else {
|
156 |
dMaxSlope = 0.0;
|
157 |
for (Aspect = -1, i = 0; i < 8; i++) { |
158 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]); |
159 |
if (!m_DEM.isNoDataValue(z2)) {
|
160 |
dSlope = Math.atan((z - z2) / m_DEM.getDistToNeighborInDir(i));
|
161 |
if (dSlope > dMaxSlope) {
|
162 |
Aspect = i; |
163 |
dMaxSlope = dSlope; |
164 |
} |
165 |
} |
166 |
} |
167 |
|
168 |
if (Aspect < 0.0) { |
169 |
Set_Parameters_NoData(x, y); |
170 |
} |
171 |
else {
|
172 |
Set_Parameters(x, y, Aspect * DEG_45_IN_RAD); |
173 |
} |
174 |
} |
175 |
} |
176 |
|
177 |
|
178 |
private void Do_Tarboton(final int x, |
179 |
final int y) { |
180 |
|
181 |
int i, j;
|
182 |
double z, z2, zm[], iSlope, iAspect, Slope, Aspect, G, H; |
183 |
|
184 |
zm = new double[8]; |
185 |
|
186 |
z = m_DEM.getCellValueAsDouble(x, y); |
187 |
|
188 |
if (m_DEM.isNoDataValue(z)) {
|
189 |
Set_Parameters_NoData(x, y); |
190 |
} |
191 |
else {
|
192 |
for (i = 0; i < 8; i++) { |
193 |
|
194 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]); |
195 |
if (!m_DEM.isNoDataValue(z2)) {
|
196 |
zm[i] = z2; |
197 |
} |
198 |
else {
|
199 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[(i + 4) % 8], y + m_iOffsetY[(i + 4) % 8]); |
200 |
if (!m_DEM.isNoDataValue(z2)) {
|
201 |
zm[i] = z - (z2 - z); |
202 |
} |
203 |
else {
|
204 |
zm[i] = z; |
205 |
} |
206 |
} |
207 |
} |
208 |
|
209 |
Slope = 0.0;
|
210 |
Aspect = -1.0;
|
211 |
|
212 |
for (i = 0, j = 1; i < 8; i++, j = (j + 1) % 8) { |
213 |
if ((i % 2) != 0) // i => diagonal |
214 |
{ |
215 |
G = (z - zm[j]) / m_DEM.getWindowCellSize(); |
216 |
H = (zm[j] - zm[i]) / m_DEM.getWindowCellSize(); |
217 |
} |
218 |
else // i => orthogonal |
219 |
{ |
220 |
G = (z - zm[i]) / m_DEM.getWindowCellSize(); |
221 |
H = (zm[i] - zm[j]) / m_DEM.getWindowCellSize(); |
222 |
} |
223 |
|
224 |
if (H < 0.0) { |
225 |
iAspect = 0.0;
|
226 |
iSlope = G; |
227 |
} |
228 |
else if (H > G) { |
229 |
iAspect = DEG_45_IN_RAD; |
230 |
iSlope = (z - zm[((i % 2) != 0) ? i : j]) / (Math.sqrt(2.0) * m_DEM.getWindowCellSize()); |
231 |
} |
232 |
else {
|
233 |
iAspect = Math.atan(H / G);
|
234 |
iSlope = Math.sqrt(G * G + H * H);
|
235 |
} |
236 |
|
237 |
if (iSlope > Slope) {
|
238 |
Aspect = i * DEG_45_IN_RAD + (((i % 2) != 0) ? DEG_45_IN_RAD - iAspect : iAspect); |
239 |
Slope = iSlope; |
240 |
} |
241 |
} |
242 |
|
243 |
if (Aspect < 0.0) { |
244 |
Set_Parameters_NoData(x, y); |
245 |
} |
246 |
else {
|
247 |
Set_Parameters(x, y, Aspect); |
248 |
} |
249 |
} |
250 |
} |
251 |
|
252 |
|
253 |
private void Do_LeastSquare(final int x, |
254 |
final int y) { |
255 |
|
256 |
double zm[], a, b; |
257 |
|
258 |
zm = new double[9]; |
259 |
|
260 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
261 |
a = ((zm[2] + 2 * zm[5] + zm[8]) - (zm[0] + 2 * zm[3] + zm[6])) / (8 * m_DEM.getWindowCellSize()); |
262 |
b = ((zm[6] + 2 * zm[7] + zm[8]) - (zm[0] + 2 * zm[1] + zm[2])) / (8 * m_DEM.getWindowCellSize()); |
263 |
|
264 |
if (a != 0.0) { |
265 |
Set_Parameters(x, y, DEG_180_IN_RAD + Math.atan2(b, a));
|
266 |
} |
267 |
else if (b > 0.0) { |
268 |
Set_Parameters(x, y, DEG_270_IN_RAD); |
269 |
} |
270 |
else if (b < 0.0) { |
271 |
Set_Parameters(x, y, DEG_90_IN_RAD); |
272 |
} |
273 |
else {
|
274 |
Set_Parameters_NoData(x, y); |
275 |
} |
276 |
} |
277 |
} |
278 |
|
279 |
|
280 |
private void Do_FD_BRM(final int x, |
281 |
final int y) { |
282 |
|
283 |
double zm[], G, H; |
284 |
|
285 |
zm = new double[9]; |
286 |
|
287 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
288 |
G = ((zm[2] - zm[0]) + (zm[5] - zm[3]) + (zm[8] - zm[6])) / _6DX; |
289 |
H = ((zm[6] - zm[0]) + (zm[7] - zm[1]) + (zm[8] - zm[2])) / _6DX; |
290 |
Set_Parameters_Derive(x, y, G, H); |
291 |
} |
292 |
} |
293 |
|
294 |
|
295 |
private void Do_FD_Heerdegen(final int x, |
296 |
final int y) { |
297 |
|
298 |
double zm[], G, H; |
299 |
|
300 |
zm = new double[9]; |
301 |
|
302 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
303 |
G = (-zm[0] + zm[2] - zm[3] + zm[5] - zm[6] + zm[8]) / _6DX; |
304 |
H = (-zm[0] - zm[1] - zm[2] + zm[6] + zm[7] + zm[8]) / _6DX; |
305 |
Set_Parameters_Derive(x, y, G, H); |
306 |
} |
307 |
} |
308 |
|
309 |
|
310 |
private void Do_FD_Zevenbergen(final int x, |
311 |
final int y) { |
312 |
|
313 |
double zm[], G, H; |
314 |
|
315 |
zm = new double[9]; |
316 |
|
317 |
if (Get_SubMatrix3x3(x, y, zm)) {
|
318 |
G = (zm[5] - zm[3]) / _2DX; |
319 |
H = (zm[7] - zm[1]) / _2DX; |
320 |
Set_Parameters_Derive(x, y, G, H); |
321 |
} |
322 |
} |
323 |
|
324 |
|
325 |
private void Do_FD_Haralick(final int x, |
326 |
final int y) { |
327 |
|
328 |
final int Mtrx[][][] = { |
329 |
{ { 31, -5, -17, -5, 31 }, { -44, -62, -68, -62, -44 }, { 0, 0, 0, 0, 0 }, { 44, 62, 68, 62, 44 }, |
330 |
{ -31, 5, 17, 5, -31 } }, |
331 |
{ { 31, -44, 0, 44, -31 }, { -5, -62, 0, 62, 5 }, { -17, -68, 0, 68, 17 }, { -5, -62, 0, 62, 5 }, |
332 |
{ 31, -44, 0, 44, -31 } }, |
333 |
{ { 2, 2, 2, 2, 2 }, { -1, -1, -1, -1, -1 }, { -2, -2, -2, -2, -2 }, { -1, -1, -1, -1, -1 }, { 2, 2, 2, 2, 2 } }, |
334 |
{ { 4, 2, 0, -2, -4 }, { 2, 1, 0, -1, -2 }, { 0, 0, 0, 0, 0 }, { -2, -1, 0, 1, 2 }, { -4, -2, 0, 2, 4 } }, |
335 |
{ { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 }, { 2, -1, -2, -1, 2 } } }; |
336 |
|
337 |
final int QMtrx[] = { 4200, 4200, 700, 1000, 700 }; |
338 |
|
339 |
int i, ix, iy, n;
|
340 |
double Sum, zm[], k[]; |
341 |
|
342 |
zm = new double[25]; |
343 |
k = new double[2]; |
344 |
|
345 |
if (Get_SubMatrix5x5(x, y, zm)) {
|
346 |
for (i = 0; i < 2; i++) { |
347 |
for (n = 0, Sum = 0.0, iy = 0; iy < 5; iy++) { |
348 |
for (ix = 0; ix < 5; ix++, n++) { |
349 |
Sum += zm[n] * Mtrx[i][ix][iy]; |
350 |
} |
351 |
} |
352 |
|
353 |
k[i] = Sum / QMtrx[i]; |
354 |
} |
355 |
|
356 |
Set_Parameters_Derive(x, y, k[1], k[0]); |
357 |
} |
358 |
} |
359 |
|
360 |
|
361 |
// additional methods
|
362 |
|
363 |
private void Set_Parameters(final int x, |
364 |
final int y, |
365 |
double dAspect) {
|
366 |
|
367 |
if (m_iUnits == UNITS_DEGREES) {
|
368 |
dAspect = Math.toDegrees(dAspect);
|
369 |
} |
370 |
|
371 |
m_Aspect.setCellValue(x, y, dAspect); |
372 |
|
373 |
} |
374 |
|
375 |
|
376 |
private void Set_Parameters_Derive(final int x, |
377 |
final int y, |
378 |
final double G, |
379 |
final double H) { |
380 |
|
381 |
if (G != 0.0) { |
382 |
Set_Parameters(x, y, DEG_180_IN_RAD + Math.atan2(H, G));
|
383 |
} |
384 |
else if (H > 0.0) { |
385 |
Set_Parameters(x, y, DEG_270_IN_RAD); |
386 |
} |
387 |
else if (H < 0.0) { |
388 |
Set_Parameters(x, y, DEG_90_IN_RAD); |
389 |
} |
390 |
else {
|
391 |
m_Aspect.setNoData(x, y); |
392 |
} |
393 |
} |
394 |
|
395 |
|
396 |
private void Set_Parameters_NoData(final int x, |
397 |
final int y) { |
398 |
|
399 |
m_Aspect.setNoData(x, y); |
400 |
|
401 |
} |
402 |
|
403 |
|
404 |
// ---------------------------------------------------------
|
405 |
// Indexing of the Submatrix:
|
406 |
//
|
407 |
// +-------+ +-------+
|
408 |
// | 7 0 1 | | 2 5 8 |
|
409 |
// | 6 * 2 | => | 1 4 7 |
|
410 |
// | 5 4 3 | | 0 3 6 |
|
411 |
// +-------+ +-------+
|
412 |
//
|
413 |
// ---------------------------------------------------------
|
414 |
private boolean Get_SubMatrix3x3(final int x, |
415 |
final int y, |
416 |
final double SubMatrix[]) { |
417 |
|
418 |
final int iSub[] = { 5, 8, 7, 6, 3, 0, 1, 2 }; |
419 |
|
420 |
int i;
|
421 |
double z, z2;
|
422 |
|
423 |
z = m_DEM.getCellValueAsDouble(x, y); |
424 |
|
425 |
if (m_DEM.isNoDataValue(z)) {
|
426 |
Set_Parameters_NoData(x, y); |
427 |
} |
428 |
else {
|
429 |
SubMatrix[4] = 0.0; |
430 |
for (i = 0; i < 8; i++) { |
431 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[i], y + m_iOffsetY[i]); |
432 |
if (!m_DEM.isNoDataValue(z2)) {
|
433 |
SubMatrix[iSub[i]] = z2 - z; |
434 |
} |
435 |
else {
|
436 |
z2 = m_DEM.getCellValueAsDouble(x + m_iOffsetX[(i + 4) % 8], y + m_iOffsetY[(i + 4) % 8]); |
437 |
if (!m_DEM.isNoDataValue(z2)) {
|
438 |
SubMatrix[iSub[i]] = z - z2; |
439 |
} |
440 |
else {
|
441 |
SubMatrix[iSub[i]] = 0.0;
|
442 |
} |
443 |
} |
444 |
} |
445 |
|
446 |
return (true); |
447 |
} |
448 |
|
449 |
return (false); |
450 |
} |
451 |
|
452 |
|
453 |
private boolean Get_SubMatrix5x5(final int x, |
454 |
final int y, |
455 |
final double SubMatrix[]) { |
456 |
int i, ix, iy, jx, jy;
|
457 |
double z, z2;
|
458 |
|
459 |
z = m_DEM.getCellValueAsDouble(x, y); |
460 |
|
461 |
if (!m_DEM.isNoDataValue(z)) {
|
462 |
for (i = 0, iy = y - 2; iy <= y + 2; iy++) { |
463 |
jy = iy < 0 ? 0 : (iy >= m_DEM.getNY() ? m_DEM.getNY() - 1 : iy); |
464 |
for (ix = x - 2; ix <= x + 2; ix++, i++) { |
465 |
jx = ix < 0 ? 0 : (ix >= m_DEM.getNX() ? m_DEM.getNY() - 1 : ix); |
466 |
z2 = m_DEM.getCellValueAsDouble(jx, jy); |
467 |
if (!m_DEM.isNoDataValue(z2)) {
|
468 |
SubMatrix[i] = z2 - z; |
469 |
} |
470 |
else {
|
471 |
SubMatrix[i] = 0.0;
|
472 |
} |
473 |
} |
474 |
} |
475 |
|
476 |
return (true); |
477 |
} |
478 |
|
479 |
return (false); |
480 |
} |
481 |
|
482 |
} |