root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / morphometry / surfaceSpecificPoints / SurfaceSpecificPointsAlgorithm.java @ 59
History | View | Annotate | Download (10.8 KB)
1 |
package es.unex.sextante.morphometry.surfaceSpecificPoints; |
---|---|
2 |
|
3 |
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue; |
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 |
import es.unex.sextante.exceptions.UnsupportedOutputChannelException; |
11 |
|
12 |
public class SurfaceSpecificPointsAlgorithm |
13 |
extends
|
14 |
GeoAlgorithm { |
15 |
|
16 |
private final static int m_iOffsetX[] = { 0, 1, 1, 1, 0, -1, -1, -1 }; |
17 |
private final static int m_iOffsetY[] = { 1, 1, 0, -1, -1, -1, 0, 1 }; |
18 |
|
19 |
public static final String METHOD = "METHOD"; |
20 |
public static final String DEM = "DEM"; |
21 |
public static final String THRESHOLD = "THRESHOLD"; |
22 |
public static final String RESULT = "RESULT"; |
23 |
|
24 |
IRasterLayer m_DEM = null;
|
25 |
IRasterLayer m_Result; |
26 |
double m_dThreshold;
|
27 |
int m_iNX, m_iNY;
|
28 |
|
29 |
|
30 |
@Override
|
31 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
32 |
|
33 |
final int iMethod = m_Parameters.getParameterValueAsInt(METHOD); |
34 |
m_DEM = m_Parameters.getParameterValueAsRasterLayer(DEM); |
35 |
m_dThreshold = m_Parameters.getParameterValueAsDouble(THRESHOLD); |
36 |
|
37 |
m_Result = getNewRasterLayer(RESULT, Sextante.getText("Result"), IRasterLayer.RASTER_DATA_TYPE_INT);
|
38 |
|
39 |
final AnalysisExtent extent = m_Result.getWindowGridExtent();
|
40 |
|
41 |
m_DEM.setWindowExtent(extent); |
42 |
|
43 |
m_iNX = m_DEM.getNX(); |
44 |
m_iNY = m_DEM.getNY(); |
45 |
|
46 |
switch (iMethod) {
|
47 |
case 0: |
48 |
doMarkHighestNB(); |
49 |
break;
|
50 |
case 1: |
51 |
doOppositeNB(); |
52 |
break;
|
53 |
case 2: |
54 |
doFlowDirection(); |
55 |
break;
|
56 |
case 3: |
57 |
doPeuckerDouglas(); |
58 |
break;
|
59 |
} |
60 |
|
61 |
return !m_Task.isCanceled();
|
62 |
|
63 |
} |
64 |
|
65 |
|
66 |
@Override
|
67 |
public void defineCharacteristics() { |
68 |
|
69 |
final String[] sMethod = { Sextante.getText("Mark_Highest_Neighbour"), Sextante.getText("Opposite_neighbours"), |
70 |
Sextante.getText("Flow_direction"), Sextante.getText("Peucker_&_Douglas") }; |
71 |
|
72 |
setUserCanDefineAnalysisExtent(true);
|
73 |
setGroup(Sextante.getText("Geomorphometry_and_terrain_analysis"));
|
74 |
setName(Sextante.getText("Landform_classification"));
|
75 |
|
76 |
try {
|
77 |
m_Parameters.addInputRasterLayer(DEM, Sextante.getText("Elevation"), true); |
78 |
m_Parameters.addSelection(METHOD, Sextante.getText("Method"), sMethod);
|
79 |
m_Parameters.addNumericalValue(THRESHOLD, Sextante.getText("Threshold__Peucker_&_Douglas"), 0.01, |
80 |
AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE); |
81 |
addOutputRasterLayer(RESULT, Sextante.getText("Result"));
|
82 |
} |
83 |
catch (final RepeatedParameterNameException e) { |
84 |
Sextante.addErrorToLog(e); |
85 |
} |
86 |
|
87 |
} |
88 |
|
89 |
|
90 |
private void doMarkHighestNB() throws UnsupportedOutputChannelException { |
91 |
|
92 |
int i, x, y, ix, iy, xlo, ylo, xhi, yhi;
|
93 |
double lo, hi, z;
|
94 |
|
95 |
IRasterLayer clo, chi; |
96 |
|
97 |
clo = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent()); |
98 |
chi = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent()); |
99 |
|
100 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
101 |
for (x = 0; x < m_iNX; x++) { |
102 |
lo = hi = m_DEM.getCellValueAsDouble(x, y); |
103 |
xhi = xlo = x; |
104 |
yhi = ylo = y; |
105 |
for (i = 0; i < 4; i++) { |
106 |
ix = x + m_iOffsetX[i]; |
107 |
iy = y + m_iOffsetY[i]; |
108 |
z = m_DEM.getCellValueAsDouble(ix, iy); |
109 |
if (!m_DEM.isNoDataValue(z)) {
|
110 |
if (z > hi) {
|
111 |
hi = z; |
112 |
xhi = ix; |
113 |
yhi = iy; |
114 |
} |
115 |
else if (z < lo) { |
116 |
lo = z; |
117 |
xlo = ix; |
118 |
ylo = iy; |
119 |
} |
120 |
} |
121 |
} |
122 |
this.setProgress(y, m_iNY);
|
123 |
clo.addToCellValue(xlo, ylo, 1);
|
124 |
chi.addToCellValue(xhi, yhi, 1);
|
125 |
} |
126 |
} |
127 |
|
128 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
129 |
for (x = 0; x < m_iNX; x++) { |
130 |
if (chi.getCellValueAsByte(x, y) == 0) { |
131 |
if (clo.getCellValueAsByte(x, y) == 0) { |
132 |
m_Result.setCellValue(x, y, 2);
|
133 |
} |
134 |
else {
|
135 |
m_Result.setCellValue(x, y, 1);
|
136 |
} |
137 |
} |
138 |
else if (clo.getCellValueAsByte(x, y) == 0) { |
139 |
m_Result.setCellValue(x, y, -1);
|
140 |
} |
141 |
else {
|
142 |
m_Result.setCellValue(x, y, 0);
|
143 |
} |
144 |
} |
145 |
} |
146 |
|
147 |
} |
148 |
|
149 |
|
150 |
private void doOppositeNB() throws UnsupportedOutputChannelException { |
151 |
|
152 |
int i, x, y, ix, iy, jx, jy;
|
153 |
double z, iz, jz;
|
154 |
|
155 |
IRasterLayer clo, chi; |
156 |
|
157 |
clo = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent()); |
158 |
chi = getTempRasterLayer(IRasterLayer.RASTER_DATA_TYPE_BYTE, m_Result.getWindowGridExtent()); |
159 |
|
160 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
161 |
for (x = 0; x < m_iNX; x++) { |
162 |
z = m_DEM.getCellValueAsDouble(x, y); |
163 |
for (i = 0; i < 4; i++) { |
164 |
ix = x + m_iOffsetX[i]; |
165 |
iy = y + m_iOffsetY[i]; |
166 |
iz = m_DEM.getCellValueAsDouble(ix, iy); |
167 |
if (!m_DEM.isNoDataValue(iz)) {
|
168 |
jx = x + m_iOffsetX[i + 4];
|
169 |
jy = y + m_iOffsetX[i + 4];
|
170 |
jz = m_DEM.getCellValueAsDouble(jx, jy); |
171 |
if (!m_DEM.isNoDataValue(jz)) {
|
172 |
if ((iz > z) && (jz > z)) {
|
173 |
chi.addToCellValue(x, y, 1);
|
174 |
} |
175 |
else if ((iz < z) && (jz < z)) { |
176 |
clo.addToCellValue(x, y, 1);
|
177 |
} |
178 |
} |
179 |
} |
180 |
} |
181 |
} |
182 |
} |
183 |
|
184 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
185 |
for (x = 0; x < m_iNX; x++) { |
186 |
if (chi.getCellValueAsByte(x, y) != 0) { |
187 |
if (clo.getCellValueAsByte(x, y) != 0) { |
188 |
m_Result.setCellValue(x, y, 5);
|
189 |
} |
190 |
else {
|
191 |
m_Result.setCellValue(x, y, chi.getCellValueAsByte(x, y)); |
192 |
} |
193 |
} |
194 |
else if (clo.getCellValueAsByte(x, y) != 0) { |
195 |
m_Result.setCellValue(x, y, -clo.getCellValueAsByte(x, y)); |
196 |
} |
197 |
else {
|
198 |
m_Result.setCellValue(x, y, 0);
|
199 |
} |
200 |
} |
201 |
} |
202 |
|
203 |
} |
204 |
|
205 |
|
206 |
private void doFlowDirection() { |
207 |
|
208 |
boolean bLower;
|
209 |
int x, y, i, ix, iy, xLow = 0, yLow = 0; |
210 |
double z, iz, zLow = 0.; |
211 |
|
212 |
m_Result.assign(0.0);
|
213 |
|
214 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
215 |
for (x = 0; x < m_iNX; x++) { |
216 |
z = m_DEM.getCellValueAsDouble(x, y); |
217 |
bLower = false;
|
218 |
for (i = 0; i < 8; i++) { |
219 |
ix = x + m_iOffsetX[i]; |
220 |
iy = y + m_iOffsetY[i]; |
221 |
iz = m_DEM.getCellValueAsDouble(ix, iy); |
222 |
if (!m_DEM.isNoDataValue(iz)) {
|
223 |
if (iz < z) {
|
224 |
if (!bLower) {
|
225 |
bLower = true;
|
226 |
zLow = iz; |
227 |
xLow = ix; |
228 |
yLow = iy; |
229 |
} |
230 |
else if (iz < zLow) { |
231 |
zLow = iz; |
232 |
xLow = ix; |
233 |
yLow = iy; |
234 |
} |
235 |
} |
236 |
} |
237 |
} |
238 |
|
239 |
if (bLower) {
|
240 |
m_Result.addToCellValue(xLow, yLow, 1);
|
241 |
} |
242 |
} |
243 |
} |
244 |
} |
245 |
|
246 |
|
247 |
private void doPeuckerDouglas() { |
248 |
|
249 |
boolean wasPlus;
|
250 |
int x, y, i, ix, iy, nSgn;
|
251 |
double d, dPlus, dMinus, z, iz, alt[]; |
252 |
|
253 |
alt = new double[8]; |
254 |
|
255 |
for (y = 0; (y < m_iNY) && setProgress(y, m_iNY); y++) { |
256 |
for (x = 0; x < m_iNX; x++) { |
257 |
z = m_DEM.getCellValueAsDouble(x, y); |
258 |
for (i = 0; i < 8; i++) { |
259 |
ix = x + m_iOffsetX[i]; |
260 |
iy = y + m_iOffsetY[i]; |
261 |
iz = m_DEM.getCellValueAsDouble(ix, iy); |
262 |
if (!m_DEM.isNoDataValue(iz)) {
|
263 |
alt[i] = iz; |
264 |
} |
265 |
else {
|
266 |
alt[i] = z; |
267 |
} |
268 |
} |
269 |
|
270 |
dPlus = dMinus = 0;
|
271 |
nSgn = 0;
|
272 |
wasPlus = (alt[7] - z > 0) ? true : false; |
273 |
|
274 |
for (i = 0; i < 8; i++) { |
275 |
d = alt[i] - z; |
276 |
if (d > 0) { |
277 |
dPlus += d; |
278 |
if (!wasPlus) {
|
279 |
nSgn++; |
280 |
wasPlus = true;
|
281 |
} |
282 |
} |
283 |
else if (d < 0) { |
284 |
dMinus -= d; |
285 |
if (wasPlus) {
|
286 |
nSgn++; |
287 |
wasPlus = false;
|
288 |
} |
289 |
} |
290 |
} |
291 |
|
292 |
i = 0;
|
293 |
if (dPlus == 0) { |
294 |
i = 9;
|
295 |
} |
296 |
else if (dMinus == 0) { |
297 |
i = -9;
|
298 |
} |
299 |
else if (nSgn == 4) { |
300 |
i = 1;
|
301 |
} |
302 |
else if (nSgn == 2) { |
303 |
i = nSgn = 0;
|
304 |
|
305 |
if (alt[7] > z) { |
306 |
while (alt[i++] > z) {
|
307 |
; |
308 |
} |
309 |
do {
|
310 |
nSgn++; |
311 |
} |
312 |
while (alt[i++] < z);
|
313 |
} |
314 |
else {
|
315 |
while (alt[i++] < z) {
|
316 |
; |
317 |
} |
318 |
do {
|
319 |
nSgn++; |
320 |
} |
321 |
while (alt[i++] > z);
|
322 |
} |
323 |
|
324 |
i = 0;
|
325 |
|
326 |
if (nSgn == 4) { |
327 |
if (dMinus - dPlus > m_dThreshold) {
|
328 |
i = 2;
|
329 |
} |
330 |
else if (dPlus - dMinus > m_dThreshold) { |
331 |
i = -2;
|
332 |
} |
333 |
} |
334 |
else { // lines: |
335 |
if (dMinus - dPlus > 0) { |
336 |
i = 7;
|
337 |
} |
338 |
else {
|
339 |
// Channel
|
340 |
i = -7;
|
341 |
} |
342 |
} |
343 |
} |
344 |
|
345 |
m_Result.setCellValue(x, y, i); |
346 |
} |
347 |
} |
348 |
|
349 |
} |
350 |
|
351 |
} |