Statistics
| Revision:

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

History | View | Annotate | Download (9.23 KB)

1

    
2

    
3
package es.unex.sextante.vectorTools.dissolveMultiple;
4

    
5
import java.util.ArrayList;
6
import java.util.HashMap;
7
import java.util.Iterator;
8
import java.util.Set;
9

    
10
import com.vividsolutions.jts.geom.Geometry;
11
import com.vividsolutions.jts.geom.GeometryFactory;
12

    
13
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer;
14
import es.unex.sextante.core.GeoAlgorithm;
15
import es.unex.sextante.core.Sextante;
16
import es.unex.sextante.dataObjects.IFeature;
17
import es.unex.sextante.dataObjects.IFeatureIterator;
18
import es.unex.sextante.dataObjects.IRecord;
19
import es.unex.sextante.dataObjects.IVectorLayer;
20
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter;
21
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException;
22
import es.unex.sextante.exceptions.RepeatedParameterNameException;
23
import es.unex.sextante.math.simpleStats.SimpleStats;
24
import es.unex.sextante.outputs.OutputVectorLayer;
25

    
26

    
27
public class DissolveMultipleAlgorithm
28
         extends
29
            GeoAlgorithm {
30

    
31
   public static final String RESULT             = "RESULT";
32
   public static final String LAYER              = "LAYER";
33
   public static final String GROUPING_FIELDS    = "GROUPING_FIELD";
34
   public static final String GROUPING_FUNCTIONS = "GROUPING_FUNCTIONS";
35

    
36
   public static final int    SUM                = 0;
37
   public static final int    MIN                = 1;
38
   public static final int    MAX                = 2;
39
   public static final int    AVG                = 3;
40
   public static final String FUNCTIONS[]        = { "SUM", "MIN", "MAX", "AVG" };
41

    
42
   private IVectorLayer       m_LayerIn;
43
   private int[]              m_iFields;
44
   private Grouping[]         m_Groupings;
45

    
46

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

    
50
      m_LayerIn = m_Parameters.getParameterValueAsVectorLayer(LAYER);
51
      if (!m_bIsAutoExtent) {
52
         m_LayerIn.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
53
      }
54
      m_iFields = getFields(m_Parameters.getParameterValueAsString(GROUPING_FIELDS));
55
      final String sGroupings = m_Parameters.getParameterValueAsString(GROUPING_FUNCTIONS);
56
      m_Groupings = getGroupings(sGroupings);
57

    
58
      final String[] sFields = new String[m_iFields.length + m_Groupings.length];
59
      final Class[] types = new Class[m_iFields.length + m_Groupings.length];
60
      for (int i = 0; i < types.length; i++) {
61
         sFields[i] = m_LayerIn.getFieldName(m_iFields[i]);
62
         types[i] = m_LayerIn.getFieldType(m_iFields[i]);
63
      }
64
      for (int i = 0; i < m_Groupings.length; i++) {
65
         sFields[i + m_iFields.length] = m_LayerIn.getFieldName(m_Groupings[i].field) + "_" + FUNCTIONS[m_Groupings[i].function];
66
         types[i + m_iFields.length] = Double.class;
67
      }
68

    
69
      final IVectorLayer output = getNewVectorLayer(RESULT, m_LayerIn.getName(), m_LayerIn.getShapeType(), types, sFields);
70

    
71
      final int iShapesCount = m_LayerIn.getShapesCount();
72

    
73
      final HashMap<ArrayList, Geometry> geoms = new HashMap<ArrayList, Geometry>();
74
      final HashMap[] stats = new HashMap[m_LayerIn.getFieldCount()];
75
      for (int i = 0; i < stats.length; i++) {
76
         stats[i] = new HashMap();
77
      }
78
      final IFeatureIterator iter = m_LayerIn.iterator();
79
      int i = 0;
80
      while (iter.hasNext() && setProgress(i, iShapesCount)) {
81
         final IFeature feature = iter.next();
82
         //String sClass = "";
83
         final ArrayList clazz = new ArrayList();
84
         final IRecord record = feature.getRecord();
85
         //sClass = record.getValue(m_iFields[0]).toString();
86
         for (int j = 0; j < m_iFields.length; j++) {
87
            clazz.add(record.getValue(m_iFields[j]));
88
            //sClass = sClass + "@" + record.getValue(m_iFields[j]).toString();
89
         }
90

    
91
         final Geometry geom = geoms.get(clazz);
92
         if (geom == null) {
93
            geoms.put(clazz, feature.getGeometry());
94
            for (final HashMap element : stats) {
95
               element.put(clazz, new SimpleStats());
96
            }
97
         }
98
         else {
99
            final Geometry[] geomsToUnion = new Geometry[2];
100
            geomsToUnion[0] = geom;
101
            geomsToUnion[1] = feature.getGeometry();
102
            final GeometryFactory fact = geom.getFactory();
103
            final Geometry geomColl = fact.createGeometryCollection(geomsToUnion);
104
            geoms.put(clazz, geomColl);
105
         }
106
         for (int j = 0; j < stats.length; j++) {
107
            try {
108
               final double dValue = Double.parseDouble(record.getValue(j).toString());
109
               ((SimpleStats) stats[j].get(clazz)).addValue(dValue);
110
            }
111
            catch (final Exception e) {
112
            }
113
         }
114

    
115
         i++;
116
      }
117

    
118
      if (m_Task.isCanceled()) {
119
         return false;
120
      }
121

    
122
      final Set set = geoms.keySet();
123
      final Iterator keys = set.iterator();
124
      i = 0;
125
      while (keys.hasNext() && setProgress(i, geoms.size())) {
126
         final ArrayList clazz = (ArrayList) keys.next();
127
         final Geometry geom = geoms.get(clazz).union();
128
         final SimpleStats stat[] = new SimpleStats[m_LayerIn.getFieldCount()];
129
         for (int j = 0; j < stat.length; j++) {
130
            stat[j] = (SimpleStats) stats[j].get(clazz);
131
         }
132
         final Object[] values = calculateRecord(stat, clazz);
133
         output.addFeature(geom, values);
134
         i++;
135
      }
136

    
137
      return !m_Task.isCanceled();
138

    
139
   }
140

    
141

    
142
   private int[] getFields(final String sFields) throws GeoAlgorithmExecutionException {
143

    
144
      final String[] fields = sFields.split(",");
145

    
146
      if (fields.length == 0) {
147
         throw new GeoAlgorithmExecutionException(Sextante.getText("At_Least_One_Field_Needed"));
148
      }
149
      final int[] iFields = new int[fields.length];
150
      for (int i = 0; i < fields.length; i++) {
151
         iFields[i] = m_LayerIn.getFieldIndexByName(fields[i]);
152
         if (iFields[i] == -1) {
153
            throw new GeoAlgorithmExecutionException(Sextante.getText("Wrong_Field_Name") + ":" + fields[i]);
154
         }
155
      }
156
      return iFields;
157

    
158
   }
159

    
160

    
161
   private Object[] calculateRecord(final SimpleStats[] stats,
162
                                    final ArrayList clazz) {
163

    
164
      double dValue;
165
      final Object[] values = new Object[m_Groupings.length + m_iFields.length];
166
      //final String[] sClasses = clazz.split("@");
167
      for (int i = 0; i < m_iFields.length; i++) {
168
         values[i] = clazz.get(i);//sClasses[i];
169
      }
170
      for (int i = 0; i < m_Groupings.length; i++) {
171
         final int iField = m_Groupings[i].field;
172
         final int iFunction = m_Groupings[i].function;
173
         switch (iFunction) {
174
            case MIN:
175
               dValue = stats[iField].getMin();
176
               break;
177
            case MAX:
178
               dValue = stats[iField].getMax();
179
               break;
180
            case SUM:
181
               dValue = stats[iField].getSum();
182
               break;
183
            case AVG:
184
            default:
185
               dValue = stats[iField].getMean();
186
               break;
187
         }
188
         if (stats[iField].getCount() > 0) {
189
            values[i + m_iFields.length] = new Double(dValue);
190
         }
191
         else {
192
            values[i + m_iFields.length] = null;
193
         }
194
      }
195

    
196
      return values;
197

    
198
   }
199

    
200

    
201
   private Grouping[] getGroupings(final String sGroupings) throws GeoAlgorithmExecutionException {
202

    
203
      if (sGroupings.trim().equals("")) {
204
         return new Grouping[0];
205
      }
206
      try {
207
         final String[] sTokens = sGroupings.split(",");
208
         if (sTokens.length % 2 != 0) {
209
            throw new GeoAlgorithmExecutionException("Wrong groupings");
210
         }
211
         final Grouping[] groupings = new Grouping[sTokens.length / 2];
212

    
213
         final int iGrouping = 0;
214
         for (int i = 0; i < sTokens.length; i++) {
215
            groupings[iGrouping] = new Grouping();
216
            groupings[iGrouping].field = Integer.parseInt(sTokens[i]);
217
            if ((groupings[iGrouping].field >= m_LayerIn.getFieldCount()) || (groupings[iGrouping].field < 0)) {
218
               throw new GeoAlgorithmExecutionException("Wrong groupings");
219
            }
220
            i++;
221
            groupings[iGrouping].function = Integer.parseInt(sTokens[i]);
222
            if ((groupings[iGrouping].function > 4) || (groupings[iGrouping].function < 0)) {
223
               throw new GeoAlgorithmExecutionException("Wrong groupings");
224
            }
225
         }
226
         return groupings;
227
      }
228
      catch (final Exception e) {
229
         throw new GeoAlgorithmExecutionException("Wrong groupings");
230
      }
231

    
232

    
233
   }
234

    
235

    
236
   @Override
237
   public void defineCharacteristics() {
238

    
239
      setName(Sextante.getText("Dissolve_multiple"));
240
      setGroup(Sextante.getText("Tools_for_vector_layers"));
241
      setUserCanDefineAnalysisExtent(true);
242

    
243
      try {
244
         m_Parameters.addInputVectorLayer(LAYER, Sextante.getText("Layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY, true);
245
         m_Parameters.addString(GROUPING_FIELDS, Sextante.getText("Fields"));
246
         m_Parameters.addString(GROUPING_FUNCTIONS, Sextante.getText("Summary_statistics"));
247
         addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_UNDEFINED, LAYER);
248
      }
249
      catch (final RepeatedParameterNameException e) {
250
         Sextante.addErrorToLog(e);
251
      }
252

    
253

    
254
   }
255

    
256
   private class Grouping {
257

    
258
      public int field;
259
      public int function;
260

    
261

    
262
      public Grouping() {
263
      }
264

    
265
   }
266

    
267
}