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