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