Statistics
| Revision:

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

History | View | Annotate | Download (8.3 KB)

1

    
2

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

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

    
9
import com.vividsolutions.jts.geom.Geometry;
10
import com.vividsolutions.jts.precision.EnhancedPrecisionOp;
11

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

    
27

    
28
public class DissolveAlgorithm
29
         extends
30
            GeoAlgorithm {
31

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

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

    
43
   private IVectorLayer       m_LayerIn;
44
   private int                m_iField;
45
   private Grouping[]         m_Groupings;
46

    
47

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

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

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

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

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

    
72
      final HashMap<String, Geometry> geoms = new HashMap<String, Geometry>();
73
      final HashMap[] stats = new HashMap[m_LayerIn.getFieldCount()];
74
      for (int i = 0; i < stats.length; i++) {
75
         stats[i] = new HashMap();
76
      }
77
      final IFeatureIterator iter = m_LayerIn.iterator();
78
      int i = 0;
79
      while (iter.hasNext() && setProgress(i, iShapesCount)) {
80
         final IFeature feature = iter.next();
81
         final String sClass = feature.getRecord().getValue(m_iField).toString();
82
         Geometry geom = geoms.get(sClass);
83
         if (geom == null) {
84
            geoms.put(sClass, feature.getGeometry());
85
            for (final HashMap element : stats) {
86
               element.put(sClass, new SimpleStats());
87
            }
88
         }
89
         else {
90
            try {
91
               geom = EnhancedPrecisionOp.union(geom, feature.getGeometry());
92
            }
93
            catch (final Exception e) {
94
               //try this if JTS complains
95
               geom = EnhancedPrecisionOp.union(geom.buffer(0), feature.getGeometry());
96
            }
97
            geoms.put(sClass, geom);
98
         }
99
         final IRecord record = feature.getRecord();
100
         for (int j = 0; j < stats.length; j++) {
101
            try {
102
               final double dValue = Double.parseDouble(record.getValue(j).toString());
103
               ((SimpleStats) stats[j].get(sClass)).addValue(dValue);
104
            }
105
            catch (final Exception e) {
106
            }
107
         }
108

    
109
         i++;
110
      }
111

    
112
      if (m_Task.isCanceled()) {
113
         return false;
114
      }
115

    
116
      final Set set = geoms.keySet();
117
      final Iterator keys = set.iterator();
118
      i = 0;
119
      while (keys.hasNext() && setProgress(i, geoms.size())) {
120
         final String sClass = (String) keys.next();
121
         final SimpleStats stat[] = new SimpleStats[m_LayerIn.getFieldCount()];
122
         for (int j = 0; j < stat.length; j++) {
123
            stat[j] = (SimpleStats) stats[j].get(sClass);
124
         }
125
         final Object[] values = calculateRecord(stat, sClass);
126
         output.addFeature(geoms.get(sClass), values);
127
         i++;
128
      }
129

    
130
      return !m_Task.isCanceled();
131

    
132
   }
133

    
134

    
135
   private Object[] calculateRecord(final SimpleStats[] stats,
136
                                    final String sClass) {
137

    
138
      double dValue;
139
      final Object[] values = new Object[m_Groupings.length + 1];
140
      values[0] = sClass;
141
      for (int i = 0; i < m_Groupings.length; i++) {
142
         final int iField = m_Groupings[i].field;
143
         final int iFunction = m_Groupings[i].function;
144
         switch (iFunction) {
145
            case MIN:
146
               dValue = stats[iField].getMin();
147
               break;
148
            case MAX:
149
               dValue = stats[iField].getMax();
150
               break;
151
            case SUM:
152
               dValue = stats[iField].getSum();
153
               break;
154
            case AVG:
155
            default:
156
               dValue = stats[iField].getMean();
157
               break;
158
         }
159
         if (stats[iField].getCount() > 0) {
160
            values[i + 1] = new Double(dValue);
161
         }
162
         else {
163
            values[i + 1] = null;
164
         }
165
      }
166

    
167
      return values;
168

    
169
   }
170

    
171

    
172
   private Grouping[] getGroupings(final String sGroupings) throws GeoAlgorithmExecutionException {
173

    
174
      if (sGroupings.trim().equals("")) {
175
         return new Grouping[0];
176
      }
177
      try {
178
         final String[] sTokens = sGroupings.split(",");
179
         if (sTokens.length % 2 != 0) {
180
            throw new GeoAlgorithmExecutionException("Wrong groupings");
181
         }
182
         final Grouping[] groupings = new Grouping[sTokens.length / 2];
183

    
184
         int iGrouping = 0;
185
         for (int i = 0; i < sTokens.length - 1; i++) {
186
            groupings[iGrouping] = new Grouping();
187
            groupings[iGrouping].field = Integer.parseInt(sTokens[i]);
188
            if ((groupings[iGrouping].field >= m_LayerIn.getFieldCount()) || (groupings[iGrouping].field < 0)) {
189
               throw new GeoAlgorithmExecutionException("Wrong groupings");
190
            }
191
            i++;
192
            groupings[iGrouping].function = Integer.parseInt(sTokens[i]);
193
            if ((groupings[iGrouping].function > 4) || (groupings[iGrouping].function < 0)) {
194
               throw new GeoAlgorithmExecutionException("Wrong groupings");
195
            }
196
            iGrouping++;
197
         }
198
         return groupings;
199
      }
200
      catch (final Exception e) {
201
         throw new GeoAlgorithmExecutionException("Wrong groupings");
202
      }
203

    
204

    
205
   }
206

    
207

    
208
   @Override
209
   public void defineCharacteristics() {
210

    
211
      setName(Sextante.getText("Dissolve"));
212
      setGroup(Sextante.getText("Tools_for_vector_layers"));
213
      setUserCanDefineAnalysisExtent(true);
214

    
215
      try {
216
         m_Parameters.addInputVectorLayer(LAYER, Sextante.getText("Layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY, true);
217
         m_Parameters.addTableField(GROUPING_FIELD, Sextante.getText("Field_with_class_name"), LAYER);
218
         m_Parameters.addString(GROUPING_FUNCTIONS, Sextante.getText("Summary_statistics"));
219
         addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_UNDEFINED, LAYER);
220
      }
221
      catch (final RepeatedParameterNameException e) {
222
         Sextante.addErrorToLog(e);
223
      }
224
      catch (final UndefinedParentParameterNameException e) {
225
         Sextante.addErrorToLog(e);
226
      }
227
      catch (final OptionalParentParameterException e) {
228
         Sextante.addErrorToLog(e);
229
      }
230

    
231
   }
232

    
233
   private class Grouping {
234

    
235
      public int field;
236
      public int function;
237

    
238

    
239
      public Grouping() {
240
      }
241

    
242
   }
243

    
244
}