Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / pointAnalysis / spatialCorrelation / SpatialCorrelationAlgorithm.java @ 59

History | View | Annotate | Download (8.19 KB)

1

    
2

    
3
package es.unex.sextante.pointAnalysis.spatialCorrelation;
4

    
5
import java.util.Arrays;
6

    
7
import com.vividsolutions.jts.geom.Coordinate;
8
import com.vividsolutions.jts.geom.Geometry;
9

    
10
import es.unex.sextante.additionalInfo.AdditionalInfoNumericalValue;
11
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
12
import es.unex.sextante.core.GeoAlgorithm;
13
import es.unex.sextante.core.Sextante;
14
import es.unex.sextante.dataObjects.IFeature;
15
import es.unex.sextante.dataObjects.IFeatureIterator;
16
import es.unex.sextante.dataObjects.ITable;
17
import es.unex.sextante.dataObjects.IVectorLayer;
18
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
19
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
20
import es.unex.sextante.exceptions.OptionalParentParameterException;
21
import es.unex.sextante.exceptions.RepeatedParameterNameException;
22
import es.unex.sextante.exceptions.UndefinedParentParameterNameException;
23
import es.unex.sextante.exceptions.UnsupportedOutputChannelException;
24

    
25

    
26
public class SpatialCorrelationAlgorithm
27
         extends
28
            GeoAlgorithm {
29

    
30
   public static final String CLOUD      = "CLOUD";
31
   public static final String RESULT     = "RESULT";
32
   public static final String INTERVAL   = "INTERVAL";
33
   public static final String POINTS     = "POINTS";
34
   public static final String FIELD      = "FIELD";
35
   private IVectorLayer       m_Layer;
36
   private int                m_iField;
37
   private double             m_dMaxDist = 0;
38
   private double             m_dInterval;
39
   private double             m_dMean;
40
   private double             m_dFieldValue[];
41
   private double             m_dMoran[];
42
   private double             m_dGeary[];
43
   private double             m_dSemivar[];
44

    
45

    
46
   @Override
47
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
48

    
49
      int i, j;
50
      double x1, x2, y1, y2;
51
      double dDifX, dDifY;
52
      double dValue;
53
      int iCount;
54

    
55
      m_dMean = 0;
56

    
57
      m_Layer = m_Parameters.getParameterValueAsVectorLayer(POINTS);
58
      if (!m_bIsAutoExtent) {
59
         m_Layer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
60
      }
61
      m_dInterval = m_Parameters.getParameterValueAsDouble(INTERVAL);
62
      m_iField = m_Parameters.getParameterValueAsInt(FIELD);
63
      iCount = m_Layer.getShapesCount();
64
      if (iCount == 0) {
65
         throw new GeoAlgorithmExecutionException("0 points in layer");
66
      }
67
      final double[][] d = new double[iCount][iCount];
68
      m_dFieldValue = new double[iCount];
69
      i = 0;
70
      final IFeatureIterator iter = m_Layer.iterator();
71
      while (iter.hasNext() && setProgress(i, iCount)) {
72
         final IFeature feature = iter.next();
73
         final Geometry geom = feature.getGeometry();
74
         final Coordinate coord = geom.getCoordinate();
75
         x1 = coord.x;
76
         y1 = coord.y;
77
         try {
78
            dValue = Double.parseDouble(feature.getRecord().getValue(m_iField).toString());
79
            m_dMean += dValue;
80
            m_dFieldValue[i] = dValue;
81
         }
82
         catch (final NumberFormatException e) {
83
            throw new GeoAlgorithmExecutionException(Sextante.getText("ERROR_Spatial_autocorrelation_Invalid_value_in_table"));
84
         }
85
         j = 0;
86
         final IFeatureIterator iter2 = m_Layer.iterator();
87
         while (iter2.hasNext()) {
88
            final IFeature feature2 = iter2.next();
89
            final Geometry geom2 = feature2.getGeometry();
90
            final Coordinate coord2 = geom2.getCoordinate();
91
            x2 = coord2.x;
92
            y2 = coord2.y;
93
            dDifX = x2 - x1;
94
            dDifY = y2 - y1;
95
            d[i][j] = Math.sqrt(dDifX * dDifX + dDifY * dDifY);
96
            m_dMaxDist = Math.max(m_dMaxDist, d[i][j]);
97
            j++;
98
         }
99
         iter2.close();
100
         i++;
101
      }
102
      iter.close();
103

    
104
      m_dMean /= iCount;
105

    
106
      if (calculate(d)) {
107
         createTables();
108
      }
109

    
110
      return !m_Task.isCanceled();
111

    
112
   }
113

    
114

    
115
   private void createTables() throws UnsupportedOutputChannelException {
116

    
117
      int i;
118
      final int iClasses = (int) (m_dMaxDist / m_dInterval + 2);
119
      final String[] sFields = { Sextante.getText("Distance"), Sextante.getText("Moran_I"), Sextante.getText("Geary_c"),
120
               Sextante.getText("Semivariance") };
121
      final Class[] types = { Double.class, Double.class, Double.class, Double.class };
122
      final String sTableName = Sextante.getText("Spatial_autocorrelation_[") + m_Layer.getName() + "]";
123
      final Object[] values = new Object[4];
124
      final ITable driver = getNewTable(RESULT, sTableName, types, sFields);
125

    
126
      for (i = 0; i < iClasses; i++) {
127
         values[0] = new Double(m_dInterval * i);
128
         values[1] = new Double(m_dMoran[i]);
129
         values[2] = new Double(m_dGeary[i]);
130
         values[3] = new Double(m_dSemivar[i]);
131
         driver.addRecord(values);
132
      }
133

    
134
   }
135

    
136

    
137
   private boolean calculate(final double[][] dist) throws UnsupportedOutputChannelException {
138

    
139
      int i, j;
140
      int iClasses;
141
      int iClass;
142
      int[] iPointsInClass;
143
      double[] dDen;
144
      double dSemivar;
145
      boolean bIsInClass[];
146
      Object[] values = null;
147
      ITable driver = null;
148

    
149
      final String[] sFields = { Sextante.getText("Distance"), Sextante.getText("Semivariance") };
150
      final Class[] types = { Double.class, Double.class };
151
      final String sTableName = Sextante.getText("Variogram_cloud_[") + m_Layer.getName() + "]";
152
      values = new Object[2];
153
      driver = getNewTable(CLOUD, sTableName, types, sFields);
154

    
155
      iClasses = (int) (m_dMaxDist / m_dInterval + 2);
156
      m_dMoran = new double[iClasses];
157
      m_dGeary = new double[iClasses];
158
      dDen = new double[iClasses];
159
      m_dSemivar = new double[iClasses];
160
      iPointsInClass = new int[iClasses];
161
      bIsInClass = new boolean[iClasses];
162

    
163
      for (i = 0; (i < dist.length) && setProgress(i, dist.length); i++) {
164
         Arrays.fill(bIsInClass, false);
165
         for (j = 0; j < dist.length; j++) {
166
            iClass = (int) Math.floor((dist[i][j] + m_dInterval / 2.) / m_dInterval);
167
            iPointsInClass[iClass]++;
168
            dSemivar = Math.pow((m_dFieldValue[i] - m_dFieldValue[j]), 2.);
169
            values[0] = new Double(dist[i][j]);
170
            values[1] = new Double(dSemivar / 2.);
171
            driver.addRecord(values);
172
            m_dSemivar[iClass] += dSemivar;
173
            m_dMoran[iClass] += (m_dFieldValue[i] - m_dMean) * (m_dFieldValue[j] - m_dMean);
174
            m_dGeary[iClass] = m_dSemivar[iClass];
175
            bIsInClass[iClass] = true;
176
         }
177
         for (j = 0; j < iClasses; j++) {
178
            if (bIsInClass[j]) {
179
               dDen[j] += Math.pow(m_dFieldValue[i] - m_dMean, 2.);
180
            }
181
         }
182
      }
183

    
184
      for (i = 0; i < iClasses; i++) {
185
         if (dDen[i] != 0) {
186
            m_dMoran[i] /= dDen[i];
187
            m_dGeary[i] *= ((iPointsInClass[i] - 1) / (2. * iPointsInClass[i] * dDen[i]));
188
            m_dSemivar[i] /= (2. * iPointsInClass[i]);
189
         }
190
      }
191

    
192
      return !m_Task.isCanceled();
193

    
194
   }
195

    
196

    
197
   @Override
198
   public void defineCharacteristics() {
199

    
200
      setName(Sextante.getText("Spatial_autocorrelation"));
201
      setGroup(Sextante.getText("Tools_for_point_layers"));
202
      setUserCanDefineAnalysisExtent(true);
203
      try {
204
         m_Parameters.addInputVectorLayer(POINTS, Sextante.getText("Points"), AdditionalInfoVectorLayer.SHAPE_TYPE_POINT, true);
205
         m_Parameters.addTableField(FIELD, Sextante.getText("Field"), POINTS);
206
         m_Parameters.addNumericalValue(INTERVAL, Sextante.getText("Distance_interval"),
207
                  AdditionalInfoNumericalValue.NUMERICAL_VALUE_DOUBLE, 100, 0, Double.MAX_VALUE);
208
         addOutputTable(RESULT, Sextante.getText("Spatial_autocorrelation"));
209
         addOutputTable(CLOUD, Sextante.getText("Nube_del_variograma"));
210
      }
211
      catch (final RepeatedParameterNameException e) {
212
         Sextante.addErrorToLog(e);
213
      }
214
      catch (final UndefinedParentParameterNameException e) {
215
         Sextante.addErrorToLog(e);
216
      }
217
      catch (final OptionalParentParameterException e) {
218
         Sextante.addErrorToLog(e);
219
      }
220

    
221
   }
222

    
223
}