Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / rasterize / universalKriging / UniversalKrigingAlgorithm.java @ 59

History | View | Annotate | Download (9.89 KB)

1
package es.unex.sextante.rasterize.universalKriging;
2

    
3
import java.awt.geom.Point2D;
4
import java.util.ArrayList;
5
import java.util.Arrays;
6

    
7
import Jama.Matrix;
8
import es.unex.sextante.additionalInfo.AdditionalInfoMultipleInput;
9
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
10
import es.unex.sextante.closestpts.Point3D;
11
import es.unex.sextante.closestpts.PtAndDistance;
12
import es.unex.sextante.core.Sextante;
13
import es.unex.sextante.dataObjects.IRasterLayer;
14
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
15
import es.unex.sextante.exceptions.RepeatedParameterNameException;
16
import es.unex.sextante.rasterWrappers.GridCell;
17
import es.unex.sextante.rasterize.interpolationBase.BaseInterpolationAlgorithm;
18

    
19

    
20
public class UniversalKrigingAlgorithm
21
         extends
22
            BaseInterpolationAlgorithm {
23

    
24
   public static final String GRIDS           = "GRIDS";
25
   public static final String MINPOINTS       = "MINPOINTS";
26
   public static final String MAXPOINTS       = "MAXPOINTS";
27
   public static final String MODEL           = "MODEL";
28
   public static final String NUGGET          = "NUGGET";
29
   public static final String SILL            = "SILL";
30
   public static final String RANGE           = "RANGE";
31
   public static final String CROSSVALIDATION = "CROSSVALIDATION";
32
   public static final String VARIANCE        = "VARIANCE";
33

    
34
   private double             m_dNugget;
35
   private double             m_dScale;
36
   private double             m_dRange;
37
   private double             m_dGammas[];
38
   private int                m_iMinPoints;
39
   private int                m_iMaxPoints;
40
   private int                m_iModel;
41
   private boolean            m_bCreateVarianceLayer;
42
   private double             m_dWeights[][];
43
   private Matrix             m_Matrix;
44
   private IRasterLayer       m_Variance;
45
   private IRasterLayer[]     m_Grids;
46

    
47

    
48
   @Override
49
   public void defineCharacteristics() {
50

    
51
      super.defineCharacteristics();
52
      setGroup(Sextante.getText("Rasterization_and_interpolation"));
53
      setName(Sextante.getText("Universal_Kriging"));
54

    
55
      final String sModels[] = { Sextante.getText("Spherical"), Sextante.getText("Exponential"), Sextante.getText("Gaussian") };
56

    
57
      try {
58
         m_Parameters.addMultipleInput(GRIDS, Sextante.getText("Predictors"), AdditionalInfoMultipleInput.DATA_TYPE_RASTER, false);
59
         m_Parameters.addNumericalValue(MINPOINTS, Sextante.getText("Minimum_number_of_points"),
60
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 4, 1, Integer.MAX_VALUE);
61
         m_Parameters.addNumericalValue(MAXPOINTS, Sextante.getText("Maximum_number_of_points"),
62
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_INTEGER, 25, 1, Integer.MAX_VALUE);
63
         m_Parameters.addSelection(MODEL, Sextante.getText("Model"), sModels);
64
         m_Parameters.addNumericalValue(NUGGET, "Nugget", AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 0, 0,
65
                  Double.MAX_VALUE);
66
         m_Parameters.addNumericalValue(SILL, "Sill", AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 10, 0,
67
                  Double.MAX_VALUE);
68
         m_Parameters.addNumericalValue(RANGE, Sextante.getText("Range"), AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE,
69
                  100, 0, Double.MAX_VALUE);
70
         addOutputTable(CROSSVALIDATION, Sextante.getText("Cross_validation"));
71
         addOutputRasterLayer(VARIANCE, Sextante.getText("Variances"));
72
      }
73
      catch (final RepeatedParameterNameException e) {
74
         Sextante.addErrorToLog(e);
75
      }
76

    
77
   }
78

    
79

    
80
   @Override
81
   protected void setValues() throws GeoAlgorithmExecutionException {
82

    
83
      super.setValues();
84

    
85
      m_iMaxPoints = m_Parameters.getParameterValueAsInt(MAXPOINTS);
86
      m_iMinPoints = m_Parameters.getParameterValueAsInt(MINPOINTS);
87
      m_iModel = m_Parameters.getParameterValueAsInt(MODEL);
88
      m_dNugget = m_Parameters.getParameterValueAsDouble(NUGGET);
89
      m_dScale = m_Parameters.getParameterValueAsDouble(SILL) - m_dNugget;
90
      m_dRange = m_Parameters.getParameterValueAsDouble(RANGE);
91
      m_bCreateVarianceLayer = true;//m_Parameters.getParameterValueAsBoolean("VARIANCE");
92
      final ArrayList grids = m_Parameters.getParameterValueAsArrayList(GRIDS);
93
      final int n = m_iMaxPoints + 1 + grids.size();
94
      m_dWeights = new double[n][n];
95
      m_Matrix = new Matrix(m_dWeights);
96
      m_dGammas = new double[n];
97

    
98
      m_Grids = new IRasterLayer[grids.size()];
99
      for (int i = 0; i < grids.size(); i++) {
100
         m_Grids[i] = (IRasterLayer) grids.get(i);
101
         m_Grids[i].setWindowExtent(m_AnalysisExtent);
102
      }
103

    
104
      if (m_bCreateVarianceLayer) {
105
         m_Variance = getNewRasterLayer(VARIANCE, m_Layer.getName() + "[var]", IRasterLayer.RASTER_DATA_TYPE_DOUBLE);
106
      }
107

    
108
   }
109

    
110

    
111
   @Override
112
   protected double getValueAt(final int x,
113
                               final int y) {
114

    
115
      final Point2D pt = m_AnalysisExtent.getWorldCoordsFromGridCoords(new GridCell(x, y, 0));
116
      final PtAndDistance[] nearestPoints = m_SearchEngine.getClosestPoints(pt.getX(), pt.getY(), m_dDistance);
117

    
118
      Arrays.sort(nearestPoints);
119

    
120
      final int n = Math.min(nearestPoints.length, m_iMaxPoints);
121
      m_NearestPoints = new PtAndDistance[n];
122
      System.arraycopy(nearestPoints, 0, m_NearestPoints, 0, n);
123

    
124
      final double dValue = interpolate(pt.getX(), pt.getY());
125

    
126
      return dValue;
127

    
128
   }
129

    
130

    
131
   @Override
132
   protected double getValueAt(final double x,
133
                               final double y) {
134

    
135
      try {
136
         final PtAndDistance[] nearestPoints = m_SearchEngine.getClosestPoints(x, y, m_dDistance);
137
         Arrays.sort(nearestPoints);
138
         final int n = Math.min(nearestPoints.length, m_iMaxPoints) - 1;
139
         m_NearestPoints = new PtAndDistance[n];
140
         System.arraycopy(nearestPoints, 1, m_NearestPoints, 0, n);
141

    
142
         return interpolate(x, y);
143
      }
144
      catch (final Exception e) {
145
         return NO_DATA;
146
      }
147

    
148
   }
149

    
150

    
151
   @Override
152
   protected double interpolate(final double x,
153
                                final double y) {
154

    
155
      int i, j, nPoints;
156
      final int nGrids = m_Grids.length;
157
      double dLambda, dValue, dVariance;
158
      Point3D pt;
159

    
160
      if ((nPoints = getWeights(x, y)) >= m_iMinPoints) {
161
         for (i = 0; i < nPoints; i++) {
162
            /*pt =  m_NearestPoints[i].getPt();
163
            dx = pt.getX() - x;
164
            dy = pt.getY() - y;*/
165
            m_dGammas[i] = getWeight(m_NearestPoints[i].getDist());
166
         }
167

    
168
         m_dGammas[nPoints] = 1.0;
169

    
170
         for (i = 0, j = nPoints + 1; i < nGrids; i++, j++) {
171
            m_dGammas[j] = m_Grids[i].getValueAt(x, y);
172
         }
173

    
174
         for (i = 0, dValue = 0.0, dVariance = 0.0; i < nPoints; i++) {
175

    
176
            pt = m_NearestPoints[i].getPt();
177

    
178
            for (j = 0, dLambda = 0.0; j <= nPoints + nGrids; j++) {
179
               dLambda += m_dWeights[i][j] * m_dGammas[j];
180
            }
181

    
182
            dValue += dLambda * pt.getZ();
183

    
184
            if (m_bCreateVarianceLayer) {
185
               dVariance += dLambda * m_dGammas[i];
186
            }
187
         }
188

    
189
         if (m_bCreateVarianceLayer) {
190
            final GridCell cell = m_AnalysisExtent.getGridCoordsFromWorldCoords(x, y);
191
            m_Variance.setCellValue(cell.getX(), cell.getY(), dVariance);
192
         }
193

    
194
         return dValue;
195
      }
196

    
197
      if (m_bCreateVarianceLayer) {
198
         final GridCell cell = m_AnalysisExtent.getGridCoordsFromWorldCoords(x, y);
199
         m_Variance.setNoData(cell.getX(), cell.getY());
200
      }
201

    
202
      return NO_DATA;
203
   }
204

    
205

    
206
   private double getWeight(double d) {
207

    
208
      if (d == 0.0) {
209
         d = 0.0001;
210
      }
211

    
212
      switch (m_iModel) {
213
         case 0: // Spherical Model
214
            if (d >= m_dRange) {
215
               d = m_dNugget + m_dScale;
216
            }
217
            else {
218
               d = m_dNugget + m_dScale * (3 * d / (2 * m_dRange) - d * d * d / (2 * m_dRange * m_dRange * m_dRange));
219
            }
220
            break;
221

    
222
         case 1: // Exponential Model
223
            d = m_dNugget + m_dScale * (1 - Math.exp(-3 * d / m_dRange));
224
            break;
225

    
226
         case 2: // Gaussian Model
227
            d = 1 - Math.exp(-3 * d / (m_dRange * m_dRange));
228
            d = m_dNugget + m_dScale * d * d;
229
            break;
230
      }
231

    
232
      return (d);
233
   }
234

    
235

    
236
   private int getWeights(final double x,
237
                          final double y) {
238

    
239
      int i, j, n, iGrid;
240
      final int nGrids = m_Grids.length;
241
      double dx, dy;
242
      Point3D pt, pt2;
243

    
244
      m_dWeights = m_Matrix.getArray();
245

    
246
      if ((n = Math.min(m_NearestPoints.length, m_iMaxPoints)) >= m_iMinPoints) {
247

    
248
         for (i = 0; i < n; i++) {
249
            pt = m_NearestPoints[i].getPt();
250
            m_dWeights[i][i] = 0.0;
251
            m_dWeights[i][n] = m_dWeights[n][i] = 1.0;
252
            for (j = i + 1; j < n; j++) {
253
               pt2 = m_NearestPoints[j].getPt();
254
               dx = pt.getX() - pt2.getX();
255
               dy = pt.getY() - pt2.getY();
256
               m_dWeights[i][j] = m_dWeights[j][i] = getWeight(Math.sqrt(dx * dx + dy * dy));
257
            }
258
            //pt = (Point3D) m_ClosestPoints.get(i);
259
            for (iGrid = 0, j = n + 1; iGrid < nGrids; iGrid++, j++) {
260
               m_dWeights[i][j] = m_dWeights[j][i] = m_Grids[iGrid].getValueAt(pt.getX(), pt.getY());
261
            }
262
         }
263

    
264
         for (i = n; i <= n + nGrids; i++) {
265
            for (j = n; j <= n + nGrids; j++) {
266
               m_dWeights[i][j] = 0.0;
267
            }
268
         }
269

    
270
         final Matrix subMatrix = m_Matrix.getMatrix(0, n, 0, n);
271

    
272
         try {
273
            final Matrix inverse = subMatrix.inverse();
274
            m_Matrix.setMatrix(0, n, 0, n, inverse);
275
         }
276
         catch (final RuntimeException e) {
277
            return 0;
278
         }
279

    
280
      }
281

    
282
      return n;
283

    
284
   }
285

    
286
}