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 |
} |