Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / gridCalculus / gridCalculator / GridCalculatorAlgorithm.java @ 59

History | View | Annotate | Download (7.67 KB)

1
package es.unex.sextante.gridCalculus.gridCalculator;
2

    
3
import java.awt.image.DataBuffer;
4
import java.util.ArrayList;
5
import java.util.HashMap;
6
import java.util.Iterator;
7
import java.util.List;
8
import java.util.Set;
9

    
10
import org.nfunk.jep.JEP;
11

    
12
import es.unex.sextante.additionalInfo.AdditionalInfoMultipleInput;
13
import es.unex.sextante.core.AnalysisExtent;
14
import es.unex.sextante.core.GeoAlgorithm;
15
import es.unex.sextante.core.Sextante;
16
import es.unex.sextante.dataObjects.IRasterLayer;
17
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
18
import es.unex.sextante.exceptions.RepeatedParameterNameException;
19
import es.unex.sextante.gui.modeler.ModelAlgorithm;
20
import es.unex.sextante.modeler.elements.ModelElementNumericalValue;
21
import es.unex.sextante.parameters.RasterLayerAndBand;
22
import es.unex.sextante.rasterWrappers.GridWrapper;
23

    
24

    
25
public class GridCalculatorAlgorithm
26
         extends
27
            GeoAlgorithm {
28

    
29
   public static final String LAYERS  = "LAYERS";
30
   public static final String FORMULA = "FORMULA";
31
   public static final String RESULT  = "RESULT";
32

    
33

    
34
   @Override
35
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
36

    
37
      int i;
38
      int x, y;
39
      double dValue;
40

    
41
      IRasterLayer layer;
42
      RasterLayerAndBand layerAndBand;
43
      final List<String> names = new ArrayList<String>();
44
      final ArrayList layers = m_Parameters.getParameterValueAsArrayList(LAYERS);
45
      String sFormula = m_Parameters.getParameterValueAsString(FORMULA).toLowerCase();
46
      final List<RasterLayerAndBand> bands = FormulaParser.getBandsFromFormula(sFormula, layers);
47

    
48
      if (bands == null) {
49
         throw new GeoAlgorithmExecutionException(Sextante.getText("Syntax_error"));
50
      }
51

    
52
      final IRasterLayer m_Result = getNewRasterLayer(RESULT, Sextante.getText("Result"), IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
53

    
54
      final IRasterLayer window[] = new IRasterLayer[bands.size()];
55
      final String sVariable[] = new String[bands.size()];
56
      final int iBands[] = new int[bands.size()];
57
      final AnalysisExtent extent = m_Result.getWindowGridExtent();
58
      final int iNX = m_Result.getWindowGridExtent().getNX();
59
      final int iNY = m_Result.getWindowGridExtent().getNY();
60

    
61
      final JEP jep = new JEP();
62
      jep.addStandardConstants();
63
      jep.addStandardFunctions();
64

    
65
      for (i = 0; i < bands.size(); i++) {
66
         layerAndBand = (RasterLayerAndBand) bands.get(i);
67
         layer = layerAndBand.getRasterLayer();
68
         iBands[i] = layerAndBand.getBand();
69
         String layerName = layer.getName();
70
         String normalizedName = FormulaParser.getNormalizedName(layerName);
71
         sFormula = FormulaParser.replaceVariables(sFormula, layerName, normalizedName);
72
         names.add(normalizedName);
73
         window[i] = layer;
74
         window[i].setWindowExtent(extent);
75
         if ((layer.getDataType() == DataBuffer.TYPE_FLOAT) || (layer.getDataType() == DataBuffer.TYPE_DOUBLE)) {
76
            window[i].setInterpolationMethod(GridWrapper.INTERPOLATION_BSpline);
77
         }
78
         else {
79
            window[i].setInterpolationMethod(GridWrapper.INTERPOLATION_NearestNeighbour);
80
         }
81

    
82
         sVariable[i] = layer.getName() + " Band " + Integer.toString(iBands[i] + 1);
83
         sVariable[i] = sVariable[i].toLowerCase();
84
         sVariable[i] = sVariable[i].replaceAll(" ", "");
85
         sVariable[i] = sVariable[i].replaceAll("\\[", "_");
86
         sVariable[i] = sVariable[i].replaceAll("\\]", "_");
87
         sVariable[i] = FormulaParser.replaceDots(sVariable[i]);
88
         sVariable[i] = FormulaParser.getNormalizedName(sVariable[i]);
89
         
90
         jep.addVariable(sVariable[i], 0.0);
91

    
92
      }
93

    
94
      sFormula = FormulaParser.prepareFormula(sFormula, names);
95
      sFormula = sFormula.toLowerCase().replaceAll(" ", "");
96
      sFormula = sFormula.replaceAll("\\[", "_");
97
      sFormula = sFormula.replaceAll("\\]", "_");
98
      sFormula = FormulaParser.replaceDots(sFormula);
99
      jep.parseExpression(sFormula);
100

    
101
      if (!jep.hasError()) {
102
         for (y = 0; (y < iNY) && setProgress(y, iNY); y++) {
103
            for (x = 0; x < iNX; x++) {
104
               for (i = 0; i < bands.size(); i++) {
105
                  dValue = window[i].getCellValueAsDouble(x, y, iBands[i]);
106
                  if (!window[i].isNoDataValue(dValue)) {
107
                     jep.addVariable(sVariable[i], dValue);
108
                  }
109
                  else {
110
                     m_Result.setNoData(x, y);
111
                     break;
112
                  }
113
               }
114
               if (i == bands.size()) {
115
                  dValue = jep.getValue();
116
                  if (!Double.isNaN(dValue)) {
117
                     m_Result.setCellValue(x, y, dValue);
118
                  }
119
                  else {
120
                     m_Result.setNoData(x, y);
121
                  }
122
               }
123
            }
124
         }
125
      }
126
      else {
127
         throw new GeoAlgorithmExecutionException(jep.getErrorInfo());
128
      }
129

    
130
      return !m_Task.isCanceled();
131

    
132
   }
133

    
134

    
135
   @Override
136
   public void defineCharacteristics() {
137

    
138
      setName(Sextante.getText("Raster_calculator"));
139
      setGroup(Sextante.getText("Calculus_tools_for_raster_layer"));
140
      setUserCanDefineAnalysisExtent(true);
141

    
142
      try {
143
         m_Parameters.addMultipleInput(LAYERS, Sextante.getText("Layers"), AdditionalInfoMultipleInput.DATA_TYPE_RASTER, true);
144
         m_Parameters.addString(FORMULA, Sextante.getText("Formula"));
145
         addOutputRasterLayer(RESULT, Sextante.getText("Result"));
146
      }
147
      catch (final RepeatedParameterNameException e) {
148
         Sextante.addErrorToLog(e);
149
      }
150

    
151
   }
152

    
153

    
154
   @Override
155
   public boolean preprocessForModeller(final Object obj) throws GeoAlgorithmExecutionException {
156

    
157
      final ModelAlgorithm model = (ModelAlgorithm) obj;
158
      try {
159
         String sFormula = m_Parameters.getParameterValueAsString(FORMULA).toLowerCase();
160
         String sKey = model.getInputAsignment(LAYERS, this);
161
         final HashMap inputs = model.getInputs();
162
         final ArrayList array = (ArrayList) inputs.get(sKey);
163
         final ArrayList<String> variables = new ArrayList<String>();
164
         for (int i = 0; i < array.size(); i++) {
165
            sKey = (String) array.get(i);
166
            final IRasterLayer layer = (IRasterLayer) inputs.get(sKey);
167
            String sVariableName = layer.getName();
168
            if (variables.contains(sVariableName)) {
169
               final char c = (char) ('a' + i);
170
               sVariableName = Character.toString(c) + "_" + sVariableName;
171
               layer.setName(sVariableName);
172
            }
173
            variables.add(sVariableName);
174
            sFormula = sFormula.replace(sKey.toLowerCase(), sVariableName);
175
         }
176
         final Set set = inputs.keySet();
177
         final Iterator iter = set.iterator();
178
         while (iter.hasNext()) {
179
            final Object key = iter.next();
180
            final Object input = inputs.get(key);
181
            if (input instanceof Double) {
182
               if (sFormula.contains(((String) key).toLowerCase())) {
183
                  sFormula = sFormula.replace(((String) key).toLowerCase(), input.toString());
184
               }
185
            }
186
            if (input instanceof ModelElementNumericalValue) {
187
               if (sFormula.contains(((String) key).toLowerCase())) {
188
                  return false;
189
               }
190
            }
191
         }
192
         m_Parameters.getParameter(FORMULA).setParameterValue(sFormula);
193
      }
194
      catch (final Exception e) {
195
         throw new GeoAlgorithmExecutionException(Sextante.getText("Syntax_error"));
196
      }
197

    
198
      return true;
199

    
200
   }
201

    
202

    
203
}