Statistics
| Revision:

root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / vectorTools / InPolygonSpatialJoin / InPolygonSpatialJoinAlgorithm.java @ 59

History | View | Annotate | Download (8.08 KB)

1
package es.unex.sextante.vectorTools.InPolygonSpatialJoin;
2

    
3
import com.vividsolutions.jts.geom.Geometry;
4

    
5
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
6
import es.unex.sextante.core.GeoAlgorithm;
7
import es.unex.sextante.core.Sextante;
8
import es.unex.sextante.dataObjects.IFeature;
9
import es.unex.sextante.dataObjects.IFeatureIterator;
10
import es.unex.sextante.dataObjects.IVectorLayer;
11
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
12
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
13
import es.unex.sextante.exceptions.RepeatedParameterNameException;
14
import es.unex.sextante.math.simpleStats.SimpleStats;
15
import es.unex.sextante.outputs.OutputVectorLayer;
16

    
17

    
18
public class InPolygonSpatialJoinAlgorithm
19
         extends
20
            GeoAlgorithm {
21

    
22
   public static final String     RESULT             = "RESULT";
23
   public static final String     POLYGONS           = "POLYGONS";
24
   public static final String     POINTS             = "POINTS";
25
   public static final String     GROUPING_FUNCTIONS = "GROUPING_FUNCTIONS";
26

    
27
   public static final int        SUM                = 0;
28
   public static final int        MIN                = 1;
29
   public static final int        MAX                = 2;
30
   public static final int        AVG                = 3;
31
   public static final int        COUNT              = 4;
32
   public static final String     FUNCTIONS[]        = { "SUM", "MIN", "MAX", "AVG", "COUNT" };
33

    
34

    
35
   private IVectorLayer           m_MainLayer;
36
   private IVectorLayer           m_SecondaryLayer;
37

    
38
   private IVectorLayer           m_Output;
39

    
40
   private NearestNeighbourFinder m_NNF;
41
   private Grouping[]             m_Groupings;
42

    
43

    
44
   @Override
45
   public void defineCharacteristics() {
46

    
47
      setName(Sextante.getText("InPolygonSpatialJoin"));
48
      setGroup(Sextante.getText("Tools_for_polygon_layers"));
49
      setUserCanDefineAnalysisExtent(true);
50

    
51
      try {
52
         m_Parameters.addInputVectorLayer(POLYGONS, Sextante.getText("Polygons_layer"),
53
                  AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON, true);
54
         m_Parameters.addInputVectorLayer(POINTS, Sextante.getText("Secondary_layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY,
55
                  true);
56
         m_Parameters.addString(GROUPING_FUNCTIONS, Sextante.getText("Summary_statistics"));
57
         addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_POLYGON, POLYGONS);
58

    
59
      }
60
      catch (final RepeatedParameterNameException e) {
61

    
62
      }
63

    
64
   }
65

    
66

    
67
   @Override
68
   public boolean processAlgorithm() throws GeoAlgorithmExecutionException {
69

    
70
      int i;
71
      int iShapeCount;
72

    
73
      m_MainLayer = m_Parameters.getParameterValueAsVectorLayer(POLYGONS);
74
      m_SecondaryLayer = m_Parameters.getParameterValueAsVectorLayer(POINTS);
75

    
76
      if (!m_bIsAutoExtent) {
77
         m_MainLayer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
78
         m_SecondaryLayer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
79
      }
80

    
81
      final String sGroupings = m_Parameters.getParameterValueAsString(GROUPING_FUNCTIONS);
82
      m_Groupings = getGroupings(sGroupings);
83

    
84
      final String[] sFields = new String[m_MainLayer.getFieldCount() + m_Groupings.length];
85
      final Class[] types = new Class[m_MainLayer.getFieldCount() + m_Groupings.length];
86
      for (i = 0; i < m_MainLayer.getFieldCount(); i++) {
87
         sFields[i] = m_MainLayer.getFieldName(i);
88
         types[i] = m_MainLayer.getFieldType(i);
89
      }
90
      for (i = 0; i < m_Groupings.length; i++) {
91
         sFields[m_MainLayer.getFieldCount() + i] = m_SecondaryLayer.getFieldName(m_Groupings[i].field) + "_"
92
                                                    + FUNCTIONS[m_Groupings[i].function];
93
         types[m_MainLayer.getFieldCount() + i] = Double.class;
94
      }
95

    
96
      m_Output = getNewVectorLayer(RESULT, m_MainLayer.getName(), m_MainLayer.getShapeType(), types, sFields);
97

    
98
      m_NNF = new NearestNeighbourFinder(m_SecondaryLayer, this.m_Task);
99

    
100
      iShapeCount = m_MainLayer.getShapesCount();
101
      i = 0;
102
      final IFeatureIterator iter = m_MainLayer.iterator();
103
      while (iter.hasNext() && setProgress(i, iShapeCount)) {
104
         final IFeature feature = iter.next();
105
         performSpatialJoin(feature);
106
         i++;
107
      }
108
      iter.close();
109

    
110
      return !m_Task.isCanceled();
111

    
112
   }
113

    
114

    
115
   private void performSpatialJoin(final IFeature feature) {
116

    
117
      final Geometry polygon = feature.getGeometry();
118
      final IFeature[] pts = m_NNF.getClosestPoints(polygon);
119

    
120
      final SimpleStats[] stats = new SimpleStats[m_SecondaryLayer.getFieldCount()];
121
      for (int i = 0; i < stats.length; i++) {
122
         stats[i] = new SimpleStats();
123
      }
124

    
125
      for (final IFeature element : pts) {
126
         if (polygon.contains(element.getGeometry())) {
127
            for (int j = 0; j < stats.length; j++) {
128
               final String sValue = element.getRecord().getValue(j).toString();
129
               try {
130
                  final double dValue = Double.parseDouble(sValue);
131
                  stats[j].addValue(dValue);
132
               }
133
               catch (final Exception e) {
134
                  e.printStackTrace();
135
               }
136
            }
137
         }
138
      }
139

    
140
      m_Output.addFeature(polygon, calculateRecord(stats, feature.getRecord().getValues()));
141

    
142
   }
143

    
144

    
145
   private Object[] calculateRecord(final SimpleStats[] stats,
146
                                    final Object[] record) {
147

    
148
      double dValue;
149
      final Object[] values = new Object[m_Groupings.length + record.length];
150
      System.arraycopy(record, 0, values, 0, record.length);
151
      for (int i = 0; i < m_Groupings.length; i++) {
152
         final int iField = m_Groupings[i].field;
153
         final int iFunction = m_Groupings[i].function;
154
         switch (iFunction) {
155
            case COUNT:
156
               dValue = stats[iField].getCount();
157
               break;
158
            case MIN:
159
               dValue = stats[iField].getMin();
160
               break;
161
            case MAX:
162
               dValue = stats[iField].getMax();
163
               break;
164
            case SUM:
165
               dValue = stats[iField].getSum();
166
               break;
167
            case AVG:
168
            default:
169
               dValue = stats[iField].getMean();
170
               break;
171
         }
172
         if (stats[iField].getCount() > 0) {
173
            values[i + record.length] = new Double(dValue);
174
         }
175
         else {
176
            values[i + record.length] = null;
177
         }
178
      }
179

    
180
      return values;
181

    
182
   }
183

    
184

    
185
   private Grouping[] getGroupings(final String sGroupings) throws GeoAlgorithmExecutionException {
186

    
187
      if (sGroupings.trim().equals("")) {
188
         return new Grouping[0];
189
      }
190
      try {
191
         final String[] sTokens = sGroupings.split(",");
192
         if (sTokens.length % 2 != 0) {
193
            throw new GeoAlgorithmExecutionException("Wrong groupings");
194
         }
195
         final Grouping[] groupings = new Grouping[sTokens.length / 2];
196

    
197
         int iGrouping = 0;
198
         for (int i = 0; i < sTokens.length; i++) {
199
            String sToken = sTokens[i];
200
            groupings[iGrouping] = new Grouping();
201
            groupings[iGrouping].field = Integer.parseInt(sToken);
202
            if ((groupings[iGrouping].field >= m_SecondaryLayer.getFieldCount()) || (groupings[iGrouping].field < 0)) {
203
               throw new GeoAlgorithmExecutionException("Wrong groupings");
204
            }
205
            i++;
206
            sToken = sTokens[i];
207
            groupings[iGrouping].function = Integer.parseInt(sToken);
208
            if ((groupings[iGrouping].function > 4) || (groupings[iGrouping].function < 0)) {
209
               throw new GeoAlgorithmExecutionException("Wrong groupings");
210
            }
211
            iGrouping++;
212
         }
213
         return groupings;
214
      }
215
      catch (final Exception e) {
216
         throw new GeoAlgorithmExecutionException("Wrong groupings");
217
      }
218

    
219

    
220
   }
221

    
222

    
223
   private class Grouping {
224

    
225
      public int field;
226
      public int function;
227

    
228

    
229
      public Grouping() {}
230

    
231
   }
232

    
233

    
234
}