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