root / org.gvsig.toolbox / trunk / org.gvsig.toolbox / org.gvsig.toolbox.algorithm / src / main / java / es / unex / sextante / vectorTools / InPolygonSpatialJoin / InPolygonSpatialJoinAlgorithm.java @ 59
History | View | Annotate | Download (8.08 KB)
1 |
package es.unex.sextante.vectorTools.InPolygonSpatialJoin; |
---|---|
2 |
|
3 |
import com.vividsolutions.jts.geom.Geometry; |
4 |
|
5 |
import es.unex.sextante.additionalInfo.AdditionalInfoVectorLayer; |
6 |
import es.unex.sextante.core.GeoAlgorithm; |
7 |
import es.unex.sextante.core.Sextante; |
8 |
import es.unex.sextante.dataObjects.IFeature; |
9 |
import es.unex.sextante.dataObjects.IFeatureIterator; |
10 |
import es.unex.sextante.dataObjects.IVectorLayer; |
11 |
import es.unex.sextante.dataObjects.vectorFilters.BoundingBoxFilter; |
12 |
import es.unex.sextante.exceptions.GeoAlgorithmExecutionException; |
13 |
import es.unex.sextante.exceptions.RepeatedParameterNameException; |
14 |
import es.unex.sextante.math.simpleStats.SimpleStats; |
15 |
import es.unex.sextante.outputs.OutputVectorLayer; |
16 |
|
17 |
|
18 |
public class InPolygonSpatialJoinAlgorithm |
19 |
extends
|
20 |
GeoAlgorithm { |
21 |
|
22 |
public static final String RESULT = "RESULT"; |
23 |
public static final String POLYGONS = "POLYGONS"; |
24 |
public static final String POINTS = "POINTS"; |
25 |
public static final String GROUPING_FUNCTIONS = "GROUPING_FUNCTIONS"; |
26 |
|
27 |
public static final int SUM = 0; |
28 |
public static final int MIN = 1; |
29 |
public static final int MAX = 2; |
30 |
public static final int AVG = 3; |
31 |
public static final int COUNT = 4; |
32 |
public static final String FUNCTIONS[] = { "SUM", "MIN", "MAX", "AVG", "COUNT" }; |
33 |
|
34 |
|
35 |
private IVectorLayer m_MainLayer;
|
36 |
private IVectorLayer m_SecondaryLayer;
|
37 |
|
38 |
private IVectorLayer m_Output;
|
39 |
|
40 |
private NearestNeighbourFinder m_NNF;
|
41 |
private Grouping[] m_Groupings; |
42 |
|
43 |
|
44 |
@Override
|
45 |
public void defineCharacteristics() { |
46 |
|
47 |
setName(Sextante.getText("InPolygonSpatialJoin"));
|
48 |
setGroup(Sextante.getText("Tools_for_polygon_layers"));
|
49 |
setUserCanDefineAnalysisExtent(true);
|
50 |
|
51 |
try {
|
52 |
m_Parameters.addInputVectorLayer(POLYGONS, Sextante.getText("Polygons_layer"),
|
53 |
AdditionalInfoVectorLayer.SHAPE_TYPE_POLYGON, true);
|
54 |
m_Parameters.addInputVectorLayer(POINTS, Sextante.getText("Secondary_layer"), AdditionalInfoVectorLayer.SHAPE_TYPE_ANY,
|
55 |
true);
|
56 |
m_Parameters.addString(GROUPING_FUNCTIONS, Sextante.getText("Summary_statistics"));
|
57 |
addOutputVectorLayer(RESULT, Sextante.getText("Result"), OutputVectorLayer.SHAPE_TYPE_POLYGON, POLYGONS);
|
58 |
|
59 |
} |
60 |
catch (final RepeatedParameterNameException e) { |
61 |
|
62 |
} |
63 |
|
64 |
} |
65 |
|
66 |
|
67 |
@Override
|
68 |
public boolean processAlgorithm() throws GeoAlgorithmExecutionException { |
69 |
|
70 |
int i;
|
71 |
int iShapeCount;
|
72 |
|
73 |
m_MainLayer = m_Parameters.getParameterValueAsVectorLayer(POLYGONS); |
74 |
m_SecondaryLayer = m_Parameters.getParameterValueAsVectorLayer(POINTS); |
75 |
|
76 |
if (!m_bIsAutoExtent) {
|
77 |
m_MainLayer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
|
78 |
m_SecondaryLayer.addFilter(new BoundingBoxFilter(m_AnalysisExtent));
|
79 |
} |
80 |
|
81 |
final String sGroupings = m_Parameters.getParameterValueAsString(GROUPING_FUNCTIONS); |
82 |
m_Groupings = getGroupings(sGroupings); |
83 |
|
84 |
final String[] sFields = new String[m_MainLayer.getFieldCount() + m_Groupings.length]; |
85 |
final Class[] types = new Class[m_MainLayer.getFieldCount() + m_Groupings.length]; |
86 |
for (i = 0; i < m_MainLayer.getFieldCount(); i++) { |
87 |
sFields[i] = m_MainLayer.getFieldName(i); |
88 |
types[i] = m_MainLayer.getFieldType(i); |
89 |
} |
90 |
for (i = 0; i < m_Groupings.length; i++) { |
91 |
sFields[m_MainLayer.getFieldCount() + i] = m_SecondaryLayer.getFieldName(m_Groupings[i].field) + "_"
|
92 |
+ FUNCTIONS[m_Groupings[i].function]; |
93 |
types[m_MainLayer.getFieldCount() + i] = Double.class;
|
94 |
} |
95 |
|
96 |
m_Output = getNewVectorLayer(RESULT, m_MainLayer.getName(), m_MainLayer.getShapeType(), types, sFields); |
97 |
|
98 |
m_NNF = new NearestNeighbourFinder(m_SecondaryLayer, this.m_Task); |
99 |
|
100 |
iShapeCount = m_MainLayer.getShapesCount(); |
101 |
i = 0;
|
102 |
final IFeatureIterator iter = m_MainLayer.iterator();
|
103 |
while (iter.hasNext() && setProgress(i, iShapeCount)) {
|
104 |
final IFeature feature = iter.next();
|
105 |
performSpatialJoin(feature); |
106 |
i++; |
107 |
} |
108 |
iter.close(); |
109 |
|
110 |
return !m_Task.isCanceled();
|
111 |
|
112 |
} |
113 |
|
114 |
|
115 |
private void performSpatialJoin(final IFeature feature) { |
116 |
|
117 |
final Geometry polygon = feature.getGeometry();
|
118 |
final IFeature[] pts = m_NNF.getClosestPoints(polygon); |
119 |
|
120 |
final SimpleStats[] stats = new SimpleStats[m_SecondaryLayer.getFieldCount()]; |
121 |
for (int i = 0; i < stats.length; i++) { |
122 |
stats[i] = new SimpleStats();
|
123 |
} |
124 |
|
125 |
for (final IFeature element : pts) { |
126 |
if (polygon.contains(element.getGeometry())) {
|
127 |
for (int j = 0; j < stats.length; j++) { |
128 |
final String sValue = element.getRecord().getValue(j).toString(); |
129 |
try {
|
130 |
final double dValue = Double.parseDouble(sValue); |
131 |
stats[j].addValue(dValue); |
132 |
} |
133 |
catch (final Exception e) { |
134 |
e.printStackTrace(); |
135 |
} |
136 |
} |
137 |
} |
138 |
} |
139 |
|
140 |
m_Output.addFeature(polygon, calculateRecord(stats, feature.getRecord().getValues())); |
141 |
|
142 |
} |
143 |
|
144 |
|
145 |
private Object[] calculateRecord(final SimpleStats[] stats, |
146 |
final Object[] record) { |
147 |
|
148 |
double dValue;
|
149 |
final Object[] values = new Object[m_Groupings.length + record.length]; |
150 |
System.arraycopy(record, 0, values, 0, record.length); |
151 |
for (int i = 0; i < m_Groupings.length; i++) { |
152 |
final int iField = m_Groupings[i].field; |
153 |
final int iFunction = m_Groupings[i].function; |
154 |
switch (iFunction) {
|
155 |
case COUNT:
|
156 |
dValue = stats[iField].getCount(); |
157 |
break;
|
158 |
case MIN:
|
159 |
dValue = stats[iField].getMin(); |
160 |
break;
|
161 |
case MAX:
|
162 |
dValue = stats[iField].getMax(); |
163 |
break;
|
164 |
case SUM:
|
165 |
dValue = stats[iField].getSum(); |
166 |
break;
|
167 |
case AVG:
|
168 |
default:
|
169 |
dValue = stats[iField].getMean(); |
170 |
break;
|
171 |
} |
172 |
if (stats[iField].getCount() > 0) { |
173 |
values[i + record.length] = new Double(dValue); |
174 |
} |
175 |
else {
|
176 |
values[i + record.length] = null;
|
177 |
} |
178 |
} |
179 |
|
180 |
return values;
|
181 |
|
182 |
} |
183 |
|
184 |
|
185 |
private Grouping[] getGroupings(final String sGroupings) throws GeoAlgorithmExecutionException { |
186 |
|
187 |
if (sGroupings.trim().equals("")) { |
188 |
return new Grouping[0]; |
189 |
} |
190 |
try {
|
191 |
final String[] sTokens = sGroupings.split(","); |
192 |
if (sTokens.length % 2 != 0) { |
193 |
throw new GeoAlgorithmExecutionException("Wrong groupings"); |
194 |
} |
195 |
final Grouping[] groupings = new Grouping[sTokens.length / 2]; |
196 |
|
197 |
int iGrouping = 0; |
198 |
for (int i = 0; i < sTokens.length; i++) { |
199 |
String sToken = sTokens[i];
|
200 |
groupings[iGrouping] = new Grouping();
|
201 |
groupings[iGrouping].field = Integer.parseInt(sToken);
|
202 |
if ((groupings[iGrouping].field >= m_SecondaryLayer.getFieldCount()) || (groupings[iGrouping].field < 0)) { |
203 |
throw new GeoAlgorithmExecutionException("Wrong groupings"); |
204 |
} |
205 |
i++; |
206 |
sToken = sTokens[i]; |
207 |
groupings[iGrouping].function = Integer.parseInt(sToken);
|
208 |
if ((groupings[iGrouping].function > 4) || (groupings[iGrouping].function < 0)) { |
209 |
throw new GeoAlgorithmExecutionException("Wrong groupings"); |
210 |
} |
211 |
iGrouping++; |
212 |
} |
213 |
return groupings;
|
214 |
} |
215 |
catch (final Exception e) { |
216 |
throw new GeoAlgorithmExecutionException("Wrong groupings"); |
217 |
} |
218 |
|
219 |
|
220 |
} |
221 |
|
222 |
|
223 |
private class Grouping { |
224 |
|
225 |
public int field; |
226 |
public int function; |
227 |
|
228 |
|
229 |
public Grouping() {}
|
230 |
|
231 |
} |
232 |
|
233 |
|
234 |
} |