Revision 2039
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/DissolveOperationFast.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or modify it under |
|
7 |
* the terms of the GNU General Public License as published by the Free Software |
|
8 |
* Foundation; either version 2 of the License, or (at your option) any later |
|
9 |
* version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 |
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|
14 |
* details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License along with |
|
17 |
* this program; if not, write to the Free Software Foundation, Inc., 51 |
|
18 |
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 |
* |
|
20 |
* For any additional information, do not hesitate to contact us at info AT |
|
21 |
* gvsig.com, or visit our website www.gvsig.com. |
|
22 |
*/ |
|
23 |
/* |
|
24 |
|
|
25 |
* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana |
|
26 |
* |
|
27 |
* Copyright (C) 2010 Generalitat Valenciana. |
|
28 |
* |
|
29 |
* This program is free software; you can redistribute it and/or |
|
30 |
* modify it under the terms of the GNU General Public License |
|
31 |
* as published by the Free Software Foundation; either version 2 |
|
32 |
* of the License, or (at your option) any later version. |
|
33 |
* |
|
34 |
* This program is distributed in the hope that it will be useful, |
|
35 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
36 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
37 |
* GNU General Public License for more details. |
|
38 |
* |
|
39 |
* You should have received a copy of the GNU General Public License |
|
40 |
* along with this program; if not, write to the Free Software |
|
41 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA. |
|
42 |
*/ |
|
43 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
44 |
|
|
45 |
import java.util.ArrayList; |
|
46 |
import java.util.List; |
|
47 |
|
|
48 |
import org.gvsig.fmap.dal.exception.DataException; |
|
49 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
|
50 |
import org.gvsig.fmap.dal.feature.Feature; |
|
51 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
|
52 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
|
53 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
|
54 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
|
55 |
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation; |
|
56 |
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil; |
|
57 |
import org.gvsig.geoprocess.algorithm.base.util.JTSFacade; |
|
58 |
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess; |
|
59 |
import org.slf4j.Logger; |
|
60 |
import org.slf4j.LoggerFactory; |
|
61 |
|
|
62 |
import com.vividsolutions.jts.geom.Geometry; |
|
63 |
import java.util.Iterator; |
|
64 |
|
|
65 |
/** |
|
66 |
* Dissolve operation |
|
67 |
* |
|
68 |
* @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a> |
|
69 |
*/ |
|
70 |
public class DissolveOperationFast extends GeometryOperation { |
|
71 |
|
|
72 |
private static Logger logger = LoggerFactory.getLogger(DissolveOperationFast.class.getName()); |
|
73 |
private EditableFeature lastEditFeature = null; |
|
74 |
private ArrayList<Element> featureList = null; |
|
75 |
private IDissolveRule rule = null; |
|
76 |
private Summary summary = null; |
|
77 |
|
|
78 |
class Element { |
|
79 |
|
|
80 |
public int id = -1; |
|
81 |
public Feature feat = null; |
|
82 |
public List<Element> overlapList = new ArrayList<Element>(); |
|
83 |
public boolean insertedToJoin = false; |
|
84 |
public Geometry jtsGeom = null; |
|
85 |
} |
|
86 |
|
|
87 |
class NodeTree { |
|
88 |
|
|
89 |
public Element element = null; |
|
90 |
public int pos = 0; |
|
91 |
public NodeTree parent = null; |
|
92 |
|
|
93 |
public NodeTree(Element node, NodeTree parent) { |
|
94 |
this.element = node; |
|
95 |
this.parent = parent; |
|
96 |
} |
|
97 |
|
|
98 |
public Element getNext() { |
|
99 |
if (pos < element.overlapList.size()) { |
|
100 |
return element.overlapList.get(pos++); |
|
101 |
} |
|
102 |
return null; |
|
103 |
} |
|
104 |
} |
|
105 |
|
|
106 |
public DissolveOperationFast(IDissolveRule rule, AbstractSextanteGeoProcess p) { |
|
107 |
super(p); |
|
108 |
this.rule = rule; |
|
109 |
featureList = new ArrayList<Element>(); |
|
110 |
} |
|
111 |
|
|
112 |
/* |
|
113 |
* (non-Javadoc) |
|
114 |
* @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature) |
|
115 |
*/ |
|
116 |
public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) { |
|
117 |
return null; |
|
118 |
} |
|
119 |
|
|
120 |
/* |
|
121 |
* (non-Javadoc) |
|
122 |
* @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature) |
|
123 |
*/ |
|
124 |
public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) { |
|
125 |
if (g == null) { |
|
126 |
return; |
|
127 |
} |
|
128 |
} |
|
129 |
|
|
130 |
/* |
|
131 |
* (non-Javadoc) |
|
132 |
* @see org.gvsig.geoprocess.algorithm.base.core.IOperation#getResult() |
|
133 |
*/ |
|
134 |
public Object getResult() { |
|
135 |
return lastEditFeature; |
|
136 |
} |
|
137 |
|
|
138 |
/** |
|
139 |
* Computes a complete operation over the input FeatureStore. The result of |
|
140 |
* this operation is stored in the output FeatureStore. |
|
141 |
* |
|
142 |
* @param inFeatStore Input FeatureStore |
|
143 |
* @param outFeatStore Output FeatureStore |
|
144 |
* @param attrNames List of attributes to build the output feature store |
|
145 |
* @param selectedGeom If it is true only the selected geometries will be |
|
146 |
* processed |
|
147 |
* @throws DataException |
|
148 |
*/ |
|
149 |
@SuppressWarnings({"deprecation"}) |
|
150 |
public void computesGeometryOperation(FeatureStore inFeatStore, |
|
151 |
FeatureStore outFeatStore, |
|
152 |
String[] attrNames, |
|
153 |
boolean selectedGeomInput, |
|
154 |
boolean selectedGeomOutput, |
|
155 |
boolean closeOutStore) throws DataException { |
|
156 |
this.inFeatureStore = inFeatStore; |
|
157 |
FeatureSet featuresSet = null; |
|
158 |
featuresSet = inFeatStore.getFeatureSet(); |
|
159 |
|
|
160 |
setFeatureStore(outFeatStore, attrNames); |
|
161 |
Iterator it = null; |
|
162 |
|
|
163 |
if (selectedGeomInput) { |
|
164 |
FeatureSelection ds = inFeatStore.getFeatureSelection(); |
|
165 |
it = ds.iterator(); |
|
166 |
numberOfFeatures = (int) ds.getSelectedCount(); |
|
167 |
} else { |
|
168 |
it = featuresSet.iterator(); |
|
169 |
numberOfFeatures = (int) featuresSet.getSize(); |
|
170 |
} |
|
171 |
|
|
172 |
if (status != null && process != null) { |
|
173 |
status.setRangeOfValues(0, numberOfFeatures); |
|
174 |
process.setProgress(0, numberOfFeatures); |
|
175 |
} |
|
176 |
|
|
177 |
//Crear lista de elementos |
|
178 |
int iCount = 0; |
|
179 |
while (it.hasNext() && !process.getTaskMonitor().isCanceled()) { |
|
180 |
Feature feat = (Feature) it.next(); |
|
181 |
Element el = new Element(); |
|
182 |
el.feat = feat.getCopy(); |
|
183 |
el.id = iCount; |
|
184 |
featureList.add(el); |
|
185 |
if (status != null && process != null) { |
|
186 |
status.setCurValue(iCount); |
|
187 |
process.setProgress(iCount, numberOfFeatures); |
|
188 |
} |
|
189 |
iCount++; |
|
190 |
} |
|
191 |
//it.dispose(); |
|
192 |
|
|
193 |
//Crear listas de solapes para cada feature |
|
194 |
iCount = 0; |
|
195 |
while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) { |
|
196 |
Element elem1 = featureList.get(iCount); |
|
197 |
org.gvsig.fmap.geom.Geometry geom1 = elem1.feat.getDefaultGeometry(); |
|
198 |
elem1.jtsGeom = GeometryUtil.geomToJTS(geom1); |
|
199 |
|
|
200 |
if (status != null) { |
|
201 |
status.setCurValue(iCount); |
|
202 |
} |
|
203 |
if (process != null) { |
|
204 |
process.setProgress(iCount, numberOfFeatures); |
|
205 |
} |
|
206 |
|
|
207 |
for (int i = iCount + 1; i < featureList.size(); i++) { |
|
208 |
Element elem2 = featureList.get(i); |
|
209 |
org.gvsig.fmap.geom.Geometry geom2 = elem2.feat.getDefaultGeometry(); |
|
210 |
elem2.jtsGeom = GeometryUtil.geomToJTS(geom2); |
|
211 |
if (rule.verifyIfDissolve(elem1.jtsGeom, elem2.jtsGeom, elem1.feat, elem2.feat)) { |
|
212 |
elem1.overlapList.add(elem2); |
|
213 |
elem2.overlapList.add(elem1); |
|
214 |
} |
|
215 |
} |
|
216 |
iCount++; |
|
217 |
} |
|
218 |
|
|
219 |
//Se calculan las listas de geometrias a unir |
|
220 |
//Para cada feature se obtiene su lista de elementos que solapan y para |
|
221 |
//cada elemento que solapa se obtiene su lista. Finalmente todas se unen y |
|
222 |
//y se hace un insert de una feature nueva |
|
223 |
List<Geometry> listResult = new ArrayList<Geometry>(); |
|
224 |
iCount = 0; |
|
225 |
int iFeat = 0; |
|
226 |
summary = new Summary(rule, outFeatStore.getDefaultFeatureType()); |
|
227 |
while (iCount < featureList.size() && !process.getTaskMonitor().isCanceled()) { |
|
228 |
Element elem1 = featureList.get(iCount); |
|
229 |
summary.loadDefaultSummarizes(elem1.feat); |
|
230 |
if (status != null) { |
|
231 |
status.setCurValue(iCount); |
|
232 |
} |
|
233 |
if (process != null) { |
|
234 |
process.setProgress(iCount, numberOfFeatures); |
|
235 |
} |
|
236 |
|
|
237 |
if (!elem1.insertedToJoin) { |
|
238 |
buildListToJoin(elem1, iFeat); |
|
239 |
iFeat++; |
|
240 |
} |
|
241 |
|
|
242 |
/*if(!elem1.insertedToJoin) { |
|
243 |
elem1.insertedToJoin = true; |
|
244 |
listResult.clear(); |
|
245 |
//org.gvsig.fmap.geom.Geometry dalGeom = elem1.feat.getDefaultGeometry(); |
|
246 |
//Geometry jtsGeom = GeometryUtil.geomToJTS(dalGeom); |
|
247 |
listResult.add(elem1.jtsGeom); |
|
248 |
|
|
249 |
buildListToJoin(listResult, elem1.overlapList); |
|
250 |
Geometry newGeom = computesUnion(listResult, elem1);//GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType()); |
|
251 |
try { |
|
252 |
addFeatureToOutput(newGeom, elem1.feat, iFeat); |
|
253 |
} catch (CreateGeometryException e) { |
|
254 |
logger.info("Error a?adiendo geometr?a", e); |
|
255 |
} catch (DataException e) { |
|
256 |
logger.info("Error a?adiendo geometr?a", e); |
|
257 |
} |
|
258 |
iFeat ++; |
|
259 |
}*/ |
|
260 |
iCount++; |
|
261 |
} |
|
262 |
|
|
263 |
if (closeOutStore && persister != null) { |
|
264 |
persister.end(); |
|
265 |
} |
|
266 |
} |
|
267 |
|
|
268 |
/** |
|
269 |
* Computes the union of the list of geometries |
|
270 |
* |
|
271 |
* @param listResult |
|
272 |
* @param elem1 |
|
273 |
* @return |
|
274 |
*/ |
|
275 |
private Geometry computesUnion(List<Geometry> listResult, Element elem1) { |
|
276 |
int splitValue = 500; |
|
277 |
Geometry newGeom = null; |
|
278 |
if (listResult.size() > splitValue) { |
|
279 |
List<List<Geometry>> list = splitList(listResult, splitValue); |
|
280 |
List<Geometry> result = new ArrayList<Geometry>(); |
|
281 |
for (int i = 0; i < list.size(); i++) { |
|
282 |
Geometry aux = GeometryUtil.geometryUnion(list.get(i), elem1.feat.getDefaultGeometry().getGeometryType().getType()); |
|
283 |
result.add(aux); |
|
284 |
} |
|
285 |
for (int i = 0; i < result.size(); i++) { |
|
286 |
newGeom = GeometryUtil.geometryUnion(result, elem1.feat.getDefaultGeometry().getGeometryType().getType()); |
|
287 |
} |
|
288 |
} else { |
|
289 |
newGeom = GeometryUtil.geometryUnion(listResult, elem1.feat.getDefaultGeometry().getGeometryType().getType()); |
|
290 |
} |
|
291 |
return newGeom; |
|
292 |
} |
|
293 |
|
|
294 |
private Geometry computesUnion3(List<Geometry> listResult) { |
|
295 |
Geometry newGeom = null; |
|
296 |
int iCount = 0; |
|
297 |
int max = listResult.size(); |
|
298 |
if (process != null) { |
|
299 |
process.setName("Generating union"); |
|
300 |
} |
|
301 |
while (listResult.size() > 1) { |
|
302 |
List<Geometry> list = new ArrayList<Geometry>(); |
|
303 |
if (status != null) { |
|
304 |
status.setCurValue(iCount); |
|
305 |
} |
|
306 |
if (process != null) { |
|
307 |
process.setProgress(iCount, max); |
|
308 |
} |
|
309 |
for (int i = 0; i < listResult.size(); i = i + 2) { |
|
310 |
if (i == (listResult.size() - 1)) { |
|
311 |
list.add(listResult.get(i)); |
|
312 |
} else { |
|
313 |
newGeom = JTSFacade.union(listResult.get(i), listResult.get(i + 1)); |
|
314 |
list.add(newGeom); |
|
315 |
} |
|
316 |
} |
|
317 |
listResult = list; |
|
318 |
} |
|
319 |
return newGeom; |
|
320 |
} |
|
321 |
|
|
322 |
/** |
|
323 |
* Splits the array of geometries to compute its union because JTS cannot |
|
324 |
* support a lot of geometries |
|
325 |
* |
|
326 |
* @param list |
|
327 |
* @param n |
|
328 |
* @return |
|
329 |
*/ |
|
330 |
private List<List<Geometry>> splitList(List<Geometry> list, int n) { |
|
331 |
int elements = (int) (list.size() / n); |
|
332 |
List<List<Geometry>> l = new ArrayList<List<Geometry>>(); |
|
333 |
for (int i = 0; i < elements; i++) { |
|
334 |
l.add(list.subList((i * n), (i * n) + n)); |
|
335 |
} |
|
336 |
if (elements * n < list.size()) { |
|
337 |
l.add(list.subList((elements * n), list.size())); |
|
338 |
} |
|
339 |
return l; |
|
340 |
} |
|
341 |
|
|
342 |
/** |
|
343 |
* Adds a feature to the output |
|
344 |
* |
|
345 |
* @param newGeom |
|
346 |
* @param feat |
|
347 |
* @param newFeatID |
|
348 |
* @throws DataException |
|
349 |
* @throws CreateGeometryException |
|
350 |
*/ |
|
351 |
private void addFeatureToOutput(Geometry newGeom, Feature feat, int newFeatID) throws DataException, CreateGeometryException { |
|
352 |
EditableFeature result = persister.getOutputFeatureStore().createNewFeature(); |
|
353 |
result.setDouble(0, newFeatID); |
|
354 |
result.set(1, feat.get(rule.getFieldName())); |
|
355 |
result.setGeometry("GEOMETRY", GeometryUtil.jtsToGeom(newGeom)); |
|
356 |
summary.loadEditableFeature(result); |
|
357 |
lastEditFeature = persister.addFeature(result, result.getDefaultGeometry()); |
|
358 |
} |
|
359 |
|
|
360 |
/** |
|
361 |
* Builds the union of all lists |
|
362 |
* |
|
363 |
* @param listResult |
|
364 |
* @param listToJoin |
|
365 |
*/ |
|
366 |
private void buildListToJoin(List<Geometry> listResult, List<Element> listToJoin) { |
|
367 |
for (int i = 0; i < listToJoin.size(); i++) { |
|
368 |
Element elem = listToJoin.get(i); |
|
369 |
if (!elem.insertedToJoin) { |
|
370 |
elem.insertedToJoin = true; |
|
371 |
buildListToJoin(listResult, elem.overlapList); |
|
372 |
summary.updateValues(elem.feat); |
|
373 |
//org.gvsig.fmap.geom.Geometry dalGeom = elem.feat.getDefaultGeometry(); |
|
374 |
//Geometry jtsGeom = GeometryUtil.geomToJTS(dalGeom); |
|
375 |
listResult.add(elem.jtsGeom); |
|
376 |
} |
|
377 |
} |
|
378 |
} |
|
379 |
|
|
380 |
/** |
|
381 |
* Builds the union of all lists |
|
382 |
* |
|
383 |
* @param listResult |
|
384 |
* @param listToJoin |
|
385 |
*/ |
|
386 |
private void buildListToJoin(Element elem, int iFeat) { |
|
387 |
Geometry newGeom = null; |
|
388 |
|
|
389 |
if (elem.overlapList.size() == 0) { |
|
390 |
if (!elem.insertedToJoin) { |
|
391 |
elem.insertedToJoin = true; |
|
392 |
} |
|
393 |
try { |
|
394 |
summary.updateValues(elem.feat); |
|
395 |
addFeatureToOutput(elem.jtsGeom, elem.feat, iFeat); |
|
396 |
} catch (CreateGeometryException e) { |
|
397 |
logger.info("Error a?adiendo geometr?a", e); |
|
398 |
} catch (DataException e) { |
|
399 |
logger.info("Error a?adiendo geometr?a", e); |
|
400 |
} |
|
401 |
} else { |
|
402 |
List<Geometry> listResult = new ArrayList<Geometry>(); |
|
403 |
NodeTree subtree = new NodeTree(elem, null); |
|
404 |
//Hacemos un recorrido en profundidad del ?rbol para a?adir |
|
405 |
//todos los elementos a la lista de geometrias a unir sin |
|
406 |
//repetir ninguna. |
|
407 |
while (subtree != null) { |
|
408 |
if (!subtree.element.insertedToJoin) { |
|
409 |
listResult.add(subtree.element.jtsGeom); |
|
410 |
summary.updateValues(subtree.element.feat); |
|
411 |
subtree.element.insertedToJoin = true; |
|
412 |
} |
|
413 |
|
|
414 |
boolean back = false; |
|
415 |
|
|
416 |
Element l = subtree.getNext(); |
|
417 |
if (l == null) { |
|
418 |
back = true; |
|
419 |
} |
|
420 |
|
|
421 |
while (!back && l.insertedToJoin) { |
|
422 |
l = subtree.getNext(); |
|
423 |
if (l == null) { |
|
424 |
back = true; |
|
425 |
} |
|
426 |
} |
|
427 |
|
|
428 |
if (back) { |
|
429 |
subtree = subtree.parent; |
|
430 |
continue; |
|
431 |
} |
|
432 |
subtree = new NodeTree(l, subtree); |
|
433 |
} |
|
434 |
newGeom = computesUnion3(listResult); |
|
435 |
|
|
436 |
try { |
|
437 |
addFeatureToOutput(newGeom, elem.feat, iFeat); |
|
438 |
} catch (DataException e) { |
|
439 |
logger.info("Imposible insertar en la tabla", e); |
|
440 |
} catch (CreateGeometryException e) { |
|
441 |
logger.info("Error a?adiendo geometr?a", e); |
|
442 |
} |
|
443 |
} |
|
444 |
|
|
445 |
} |
|
446 |
|
|
447 |
} |
|
0 | 448 |
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/DissolveOperation.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or modify it under |
|
7 |
* the terms of the GNU General Public License as published by the Free Software |
|
8 |
* Foundation; either version 2 of the License, or (at your option) any later |
|
9 |
* version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, but WITHOUT |
|
12 |
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
|
13 |
* FOR A PARTICULAR PURPOSE. See the GNU General Public License for more |
|
14 |
* details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License along with |
|
17 |
* this program; if not, write to the Free Software Foundation, Inc., 51 |
|
18 |
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
19 |
* |
|
20 |
* For any additional information, do not hesitate to contact us at info AT |
|
21 |
* gvsig.com, or visit our website www.gvsig.com. |
|
22 |
*/ |
|
23 |
/* |
|
24 |
|
|
25 |
* gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana |
|
26 |
* |
|
27 |
* Copyright (C) 2010 Generalitat Valenciana. |
|
28 |
* |
|
29 |
* This program is free software; you can redistribute it and/or |
|
30 |
* modify it under the terms of the GNU General Public License |
|
31 |
* as published by the Free Software Foundation; either version 2 |
|
32 |
* of the License, or (at your option) any later version. |
|
33 |
* |
|
34 |
* This program is distributed in the hope that it will be useful, |
|
35 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
36 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
37 |
* GNU General Public License for more details. |
|
38 |
* |
|
39 |
* You should have received a copy of the GNU General Public License |
|
40 |
* along with this program; if not, write to the Free Software |
|
41 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA. |
|
42 |
*/ |
|
43 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
44 |
|
|
45 |
import java.util.ArrayList; |
|
46 |
|
|
47 |
import org.gvsig.fmap.dal.exception.DataException; |
|
48 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
|
49 |
import org.gvsig.fmap.dal.feature.Feature; |
|
50 |
import org.gvsig.fmap.dal.feature.FeatureSelection; |
|
51 |
import org.gvsig.fmap.dal.feature.FeatureSet; |
|
52 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
|
53 |
import org.gvsig.fmap.geom.exception.CreateGeometryException; |
|
54 |
import org.gvsig.fmap.geom.primitive.NullGeometry; |
|
55 |
import org.gvsig.geoprocess.algorithm.base.core.GeometryOperation; |
|
56 |
import org.gvsig.geoprocess.algorithm.base.util.GeometryUtil; |
|
57 |
import org.gvsig.geoprocess.lib.sextante.AbstractSextanteGeoProcess; |
|
58 |
|
|
59 |
import com.vividsolutions.jts.geom.Geometry; |
|
60 |
|
|
61 |
import es.unex.sextante.core.Sextante; |
|
62 |
import java.util.Iterator; |
|
63 |
|
|
64 |
/** |
|
65 |
* Dissolve operation |
|
66 |
* |
|
67 |
* @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a> |
|
68 |
*/ |
|
69 |
public class DissolveOperation extends GeometryOperation { |
|
70 |
|
|
71 |
private EditableFeature lastEditFeature = null; |
|
72 |
private ArrayList<Geometry> geometries = new ArrayList<Geometry>(); |
|
73 |
private IDissolveRule criteria = null; |
|
74 |
private AtomicDissolveOperation atomicOperation = null; |
|
75 |
|
|
76 |
/** |
|
77 |
* Cada elemento representa una feature del vectorial de entrada. Cuando se |
|
78 |
* hace un dissolve de esa feature con otra su posici?n en el array se pone |
|
79 |
* a false para no volver a procesarla. |
|
80 |
*/ |
|
81 |
//private boolean[] analizedFeats = null; |
|
82 |
public DissolveOperation(IDissolveRule criteria, AbstractSextanteGeoProcess p) { |
|
83 |
super(p); |
|
84 |
this.criteria = criteria; |
|
85 |
} |
|
86 |
|
|
87 |
public AtomicDissolveOperation getAtomicDissolveOperation() { |
|
88 |
if (atomicOperation == null) { |
|
89 |
atomicOperation = new AtomicDissolveOperation(process); |
|
90 |
} |
|
91 |
return atomicOperation; |
|
92 |
} |
|
93 |
|
|
94 |
/* |
|
95 |
* (non-Javadoc) |
|
96 |
* @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.Feature) |
|
97 |
*/ |
|
98 |
public EditableFeature invoke(org.gvsig.fmap.geom.Geometry g, Feature feature) { |
|
99 |
if (g == null) { |
|
100 |
return lastEditFeature; |
|
101 |
} |
|
102 |
getAtomicDissolveOperation().setFeature(feature); |
|
103 |
try { |
|
104 |
getAtomicDissolveOperation().computesOperation(selectedGeomInput); |
|
105 |
EditableFeature res = (EditableFeature) getAtomicDissolveOperation().getResult(); |
|
106 |
lastEditFeature = persister.addFeature(res, res.getDefaultGeometry()); |
|
107 |
} catch (DataException e) { |
|
108 |
Sextante.addErrorToLog(e); |
|
109 |
} catch (CreateGeometryException e) { |
|
110 |
Sextante.addErrorToLog(e); |
|
111 |
} |
|
112 |
|
|
113 |
return lastEditFeature; |
|
114 |
} |
|
115 |
|
|
116 |
/* |
|
117 |
* (non-Javadoc) |
|
118 |
* @see org.gvsig.geoprocess.algorithm.base.core.GeometryOperation#invoke(org.gvsig.fmap.geom.Geometry, org.gvsig.fmap.dal.feature.EditableFeature) |
|
119 |
*/ |
|
120 |
public void invoke(org.gvsig.fmap.geom.Geometry g, EditableFeature feature) { |
|
121 |
if (g == null) { |
|
122 |
return; |
|
123 |
} |
|
124 |
} |
|
125 |
|
|
126 |
/* |
|
127 |
* (non-Javadoc) |
|
128 |
* @see org.gvsig.geoprocess.algorithm.base.core.IOperation#getResult() |
|
129 |
*/ |
|
130 |
public Object getResult() { |
|
131 |
return lastEditFeature; |
|
132 |
} |
|
133 |
|
|
134 |
/** |
|
135 |
* Computes a complete operation over the input FeatureStore. The result of |
|
136 |
* this operation is stored in the output FeatureStore. |
|
137 |
* |
|
138 |
* @param inFeatStore Input FeatureStore |
|
139 |
* @param outFeatStore Output FeatureStore |
|
140 |
* @param attrNames List of attributes to build the output feature store |
|
141 |
* @param selectedGeom If it is true only the selected geometries will be |
|
142 |
* processed |
|
143 |
* @throws DataException |
|
144 |
*/ |
|
145 |
@SuppressWarnings({"deprecation"}) |
|
146 |
public void computesGeometryOperation(FeatureStore inFeatStore, |
|
147 |
FeatureStore outFeatStore, |
|
148 |
String[] attrNames, |
|
149 |
boolean selectedGeomInput, |
|
150 |
boolean selectedGeomOutput, |
|
151 |
boolean closeOutStore) throws DataException { |
|
152 |
this.inFeatureStore = inFeatStore; |
|
153 |
this.selectedGeomInput = selectedGeomInput; |
|
154 |
this.selectedGeomOverlay = selectedGeomOutput; |
|
155 |
FeatureSet featuresSet = null; |
|
156 |
featuresSet = inFeatStore.getFeatureSet(); |
|
157 |
|
|
158 |
setFeatureStore(outFeatStore, attrNames); |
|
159 |
Iterator it = null; |
|
160 |
|
|
161 |
if (selectedGeomInput) { |
|
162 |
FeatureSelection ds = inFeatStore.getFeatureSelection(); |
|
163 |
it = ds.iterator(); |
|
164 |
numberOfFeatures = (int) ds.getSelectedCount(); |
|
165 |
} else { |
|
166 |
it = featuresSet.iterator(); |
|
167 |
numberOfFeatures = (int) featuresSet.getSize(); |
|
168 |
} |
|
169 |
|
|
170 |
if (status != null && process != null) { |
|
171 |
status.setRangeOfValues(0, numberOfFeatures); |
|
172 |
process.setProgress(0, numberOfFeatures); |
|
173 |
} |
|
174 |
|
|
175 |
ArrayList<Feature> featList = new ArrayList<Feature>(); |
|
176 |
|
|
177 |
int iCount = 0; |
|
178 |
while (it.hasNext() && !process.getTaskMonitor().isCanceled()) { |
|
179 |
featList.add((Feature) it.next()); |
|
180 |
if (status != null && process != null) { |
|
181 |
status.setCurValue(iCount); |
|
182 |
process.setProgress(iCount, numberOfFeatures); |
|
183 |
} |
|
184 |
iCount++; |
|
185 |
} |
|
186 |
|
|
187 |
getAtomicDissolveOperation().setTaskStatus(status); |
|
188 |
getAtomicDissolveOperation().setGeoProcess(process, numberOfFeatures); |
|
189 |
getAtomicDissolveOperation().setCriteria(criteria); |
|
190 |
getAtomicDissolveOperation().setGeometryList(geometries); |
|
191 |
getAtomicDissolveOperation().setFeatureStore(persister.getOutputFeatureStore(), null); |
|
192 |
getAtomicDissolveOperation().setFeatureList(featList); |
|
193 |
|
|
194 |
iCount = 0; |
|
195 |
while (featList.size() > 0 && !process.getTaskMonitor().isCanceled()) { |
|
196 |
Feature feature = featList.remove(0); |
|
197 |
|
|
198 |
geometries.clear(); |
|
199 |
|
|
200 |
if (status != null && process != null) { |
|
201 |
status.setCurValue(numberOfFeatures - featList.size()); |
|
202 |
process.setProgress(numberOfFeatures - featList.size(), numberOfFeatures); |
|
203 |
} |
|
204 |
|
|
205 |
org.gvsig.fmap.geom.Geometry geom = feature.getDefaultGeometry(); |
|
206 |
if (!(geom instanceof NullGeometry)) { |
|
207 |
geometries.add(GeometryUtil.geomToJTS(geom)); |
|
208 |
invoke(geom, feature); |
|
209 |
} |
|
210 |
continue; |
|
211 |
|
|
212 |
} |
|
213 |
|
|
214 |
if (closeOutStore && persister != null) { |
|
215 |
persister.end(); |
|
216 |
} |
|
217 |
} |
|
218 |
|
|
219 |
/** |
|
220 |
* Computes a complete operation over the input FeatureStore. The result of |
|
221 |
* this operation is stored in the output FeatureStore. |
|
222 |
* |
|
223 |
* @param inFeatStore Input FeatureStore |
|
224 |
* @param outFeatStore Output FeatureStore |
|
225 |
* @param attrNames List of attributes to build the output feature store |
|
226 |
* @param selectedGeom If it is true only the selected geometries will be |
|
227 |
* processed |
|
228 |
* @throws DataException |
|
229 |
*/ |
|
230 |
// public void computesGeometryOperation(FeatureStore inFeatStore, |
|
231 |
// FeatureStore outFeatStore, |
|
232 |
// String[] attrNames, |
|
233 |
// boolean selectedGeom, |
|
234 |
// boolean closeOutStore) throws DataException { |
|
235 |
// this.inFeatureStore = inFeatStore; |
|
236 |
// this.selectedGeom = selectedGeom; |
|
237 |
// FeatureSet featuresSet = null; |
|
238 |
// featuresSet = inFeatStore.getFeatureSet(); |
|
239 |
// |
|
240 |
// setFeatureStore(outFeatStore, attrNames); |
|
241 |
// DisposableIterator it = null; |
|
242 |
// |
|
243 |
// if(selectedGeom) { |
|
244 |
// FeatureSelection ds = inFeatStore.getFeatureSelection(); |
|
245 |
// it = ds.iterator(); |
|
246 |
// numberOfFeatures = (int) ds.getSelectedCount(); |
|
247 |
// } else { |
|
248 |
// it = featuresSet.iterator(); |
|
249 |
// numberOfFeatures = (int)featuresSet.getSize(); |
|
250 |
// } |
|
251 |
// |
|
252 |
// if (status != null && process != null) { |
|
253 |
// status.setRangeOfValues(0, numberOfFeatures); |
|
254 |
// process.setProgress(0, numberOfFeatures); |
|
255 |
// } |
|
256 |
// analizedFeats = new boolean[numberOfFeatures]; |
|
257 |
// |
|
258 |
// getAtomicDissolveOperation().setCriteria(criteria); |
|
259 |
// getAtomicDissolveOperation().setGeometryList(geometries); |
|
260 |
// getAtomicDissolveOperation().setFeatureStore(persister.getOutputFeatureStore(), null); |
|
261 |
// getAtomicDissolveOperation().setAnalizedFeatureList(analizedFeats); |
|
262 |
// getAtomicDissolveOperation().setFeatureStore(inFeatureStore); |
|
263 |
// |
|
264 |
// int iCount = 0; |
|
265 |
// int featAnalized = 0; |
|
266 |
// while( it.hasNext() && !process.getTaskMonitor().isCanceled()) { |
|
267 |
// Feature feature = (Feature)it.next(); |
|
268 |
// |
|
269 |
// if(analizedFeats[featAnalized]) { |
|
270 |
// featAnalized ++; |
|
271 |
// continue; |
|
272 |
// } |
|
273 |
// |
|
274 |
// analizedFeats[featAnalized] = true; |
|
275 |
// List geomList = feature.getGeometries(); |
|
276 |
// geometries.clear(); |
|
277 |
// |
|
278 |
// if (status != null && process != null) { |
|
279 |
// status.setCurValue(iCount); |
|
280 |
// process.setProgress(iCount, numberOfFeatures); |
|
281 |
// } |
|
282 |
// iCount ++; |
|
283 |
// |
|
284 |
// if(geomList == null) { |
|
285 |
// org.gvsig.fmap.geom.Geometry geom = feature.getDefaultGeometry(); |
|
286 |
// geometries.add(GeometryUtil.geomToJTS(geom)); |
|
287 |
// invoke(geom, feature); |
|
288 |
// featAnalized ++; |
|
289 |
// continue; |
|
290 |
// } |
|
291 |
// |
|
292 |
// Iterator<org.gvsig.fmap.geom.Geometry> itGeom = geomList.iterator(); |
|
293 |
// while(itGeom.hasNext() && !process.getTaskMonitor().isCanceled()) { |
|
294 |
// org.gvsig.fmap.geom.Geometry g = itGeom.next(); |
|
295 |
// geometries.add(GeometryUtil.geomToJTS(g)); |
|
296 |
// invoke(g, feature); |
|
297 |
// } |
|
298 |
// |
|
299 |
// featAnalized ++; |
|
300 |
// } |
|
301 |
// |
|
302 |
// if(closeOutStore && persister != null) |
|
303 |
// persister.end(); |
|
304 |
// } |
|
305 |
} |
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/IDissolveRule.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or |
|
7 |
* modify it under the terms of the GNU General Public License |
|
8 |
* as published by the Free Software Foundation; either version 2 |
|
9 |
* of the License, or (at your option) any later version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, |
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
* GNU General Public License for more details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License |
|
17 |
* along with this program; if not, write to the Free Software |
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
20 |
* |
|
21 |
* For any additional information, do not hesitate to contact us |
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com. |
|
23 |
*/ |
|
24 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
25 |
|
|
26 |
import com.vividsolutions.jts.geom.Geometry; |
|
27 |
|
|
28 |
import org.gvsig.fmap.dal.feature.Feature; |
|
29 |
|
|
30 |
|
|
31 |
/** |
|
32 |
* Forces to IDissolveCriteria to fetch geometries from |
|
33 |
* ReadableVectorial (for performance reasons, once a criteria |
|
34 |
* has verified a spatial conditions, it caches IGeometry, to |
|
35 |
* avoid reading them many times) |
|
36 |
* @author azabala |
|
37 |
* |
|
38 |
*/ |
|
39 |
public interface IDissolveRule { |
|
40 |
/** |
|
41 |
* Verifies if the given geometries will be dissolved |
|
42 |
* @param g1 |
|
43 |
* @param g2 |
|
44 |
* @param f |
|
45 |
* @return true if the given geometries will be dissolved or false |
|
46 |
* if not. |
|
47 |
*/ |
|
48 |
public boolean verifyIfDissolve(Geometry g1, Geometry g2, Feature f1, Feature f2); |
|
49 |
|
|
50 |
/** |
|
51 |
* Returns true if the selected function is included in the summary |
|
52 |
* @param func |
|
53 |
* @return |
|
54 |
*/ |
|
55 |
public boolean isFunctionIncluded(String func); |
|
56 |
|
|
57 |
/** |
|
58 |
* Returns the name of the field for the selected function |
|
59 |
* @return |
|
60 |
*/ |
|
61 |
public String getFieldName(String func); |
|
62 |
|
|
63 |
/** |
|
64 |
* Gets the index of the field to apply the dissolve rule |
|
65 |
* @return |
|
66 |
*/ |
|
67 |
public String getFieldName(); |
|
68 |
} |
|
69 |
|
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/DissolveParametersPanel.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or |
|
7 |
* modify it under the terms of the GNU General Public License |
|
8 |
* as published by the Free Software Foundation; either version 2 |
|
9 |
* of the License, or (at your option) any later version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, |
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
* GNU General Public License for more details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License |
|
17 |
* along with this program; if not, write to the Free Software |
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
20 |
* |
|
21 |
* For any additional information, do not hesitate to contact us |
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com. |
|
23 |
*/ |
|
24 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
25 |
|
|
26 |
import java.awt.BorderLayout; |
|
27 |
import java.awt.Dimension; |
|
28 |
import java.awt.GridBagConstraints; |
|
29 |
import java.awt.GridBagLayout; |
|
30 |
import java.awt.Insets; |
|
31 |
import java.awt.event.ActionEvent; |
|
32 |
import java.awt.event.ActionListener; |
|
33 |
import java.util.ArrayList; |
|
34 |
import java.util.List; |
|
35 |
|
|
36 |
import javax.swing.ComboBoxModel; |
|
37 |
import javax.swing.DefaultComboBoxModel; |
|
38 |
import javax.swing.JCheckBox; |
|
39 |
import javax.swing.JComboBox; |
|
40 |
import javax.swing.JLabel; |
|
41 |
import javax.swing.JPanel; |
|
42 |
|
|
43 |
import org.gvsig.fmap.dal.exception.DataException; |
|
44 |
import org.gvsig.fmap.dal.feature.FeatureStore; |
|
45 |
import org.gvsig.geoprocess.lib.api.GeoProcessLocator; |
|
46 |
import org.gvsig.geoprocess.lib.sextante.dataObjects.FlyrVectIVectorLayer; |
|
47 |
import org.gvsig.geoprocess.sextante.gui.algorithm.AlgorithmOutputPanel; |
|
48 |
import org.gvsig.gui.beans.table.TableContainer; |
|
49 |
import org.gvsig.gui.beans.table.exceptions.NotInitializeException; |
|
50 |
|
|
51 |
import es.unex.sextante.core.GeoAlgorithm; |
|
52 |
import es.unex.sextante.core.ObjectAndDescription; |
|
53 |
import es.unex.sextante.core.OutputObjectsSet; |
|
54 |
import es.unex.sextante.core.ParametersSet; |
|
55 |
import es.unex.sextante.core.Sextante; |
|
56 |
import es.unex.sextante.dataObjects.IVectorLayer; |
|
57 |
import es.unex.sextante.gui.algorithm.GeoAlgorithmParametersPanel; |
|
58 |
import es.unex.sextante.gui.algorithm.OutputChannelSelectionPanel; |
|
59 |
import es.unex.sextante.gui.core.SextanteGUI; |
|
60 |
import es.unex.sextante.outputs.Output; |
|
61 |
import java.util.Arrays; |
|
62 |
|
|
63 |
/** |
|
64 |
* Panel for dissolve algorithm |
|
65 |
* @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a> |
|
66 |
*/ |
|
67 |
public class DissolveParametersPanel extends GeoAlgorithmParametersPanel implements ActionListener { |
|
68 |
private static final long serialVersionUID = 1L; |
|
69 |
private GeoAlgorithm m_Algorithm = null; |
|
70 |
private JComboBox layersCombo = null; |
|
71 |
private JComboBox fieldsCombo = null; |
|
72 |
private JCheckBox selectionOnly = null; |
|
73 |
private JCheckBox adjacentOnly = null; |
|
74 |
//private AlgorithmOutputPanel output = null; |
|
75 |
private final String[] columnNames = { "Min", "Max", "Sum", "Avg", "Field ID" }; |
|
76 |
private final int[] columnWidths = { 35, 35, 35, 35, 334 }; |
|
77 |
private TableContainer table = null; |
|
78 |
private AlgorithmOutputPanel algorithmOutputPanel = null; |
|
79 |
private OutputChannelSelectionPanel outputChannelSelectionPanel; |
|
80 |
private JPanel outputPanel; |
|
81 |
|
|
82 |
public DissolveParametersPanel() { |
|
83 |
super(); |
|
84 |
} |
|
85 |
|
|
86 |
public void init(GeoAlgorithm algorithm) { |
|
87 |
m_Algorithm = algorithm; |
|
88 |
initGUI(); |
|
89 |
} |
|
90 |
|
|
91 |
private void initGUI() { |
|
92 |
GridBagLayout gbl = new GridBagLayout(); |
|
93 |
this.setLayout(gbl); |
|
94 |
|
|
95 |
GridBagConstraints gbc = new GridBagConstraints(); |
|
96 |
gbc.fill = GridBagConstraints.HORIZONTAL; |
|
97 |
gbc.weightx = 1.0; |
|
98 |
gbc.gridx = 0; |
|
99 |
gbc.gridy = 0; |
|
100 |
gbc.insets = new Insets(0, 0, 8, 0); |
|
101 |
this.add(getComboPanel(GeoProcessLocator.getGeoProcessManager().getTranslation("Input_layer"), getLayersCombo()), gbc); |
|
102 |
|
|
103 |
gbc.gridy = 1; |
|
104 |
this.add(getComboPanel(GeoProcessLocator.getGeoProcessManager().getTranslation("Field"), getFieldsCombo()), gbc); |
|
105 |
|
|
106 |
gbc.gridy = 2; |
|
107 |
this.add(getSelectionCheck(), gbc); |
|
108 |
|
|
109 |
gbc.gridy = 3; |
|
110 |
this.add(getAdjacentCheck(), gbc); |
|
111 |
|
|
112 |
gbc.gridy = 4; |
|
113 |
this.add(new JLabel(GeoProcessLocator.getGeoProcessManager().getTranslation("summary_function")), gbc); |
|
114 |
|
|
115 |
gbc.gridy = 5; |
|
116 |
gbc.fill = GridBagConstraints.BOTH; |
|
117 |
gbc.insets = new Insets(0, 0, 12, 0); |
|
118 |
gbc.weighty = 1.0; |
|
119 |
this.add(getRadioButtonTable(), gbc); |
|
120 |
|
|
121 |
gbc.gridy = 6; |
|
122 |
gbc.fill = GridBagConstraints.HORIZONTAL; |
|
123 |
gbc.weighty = 0.0; |
|
124 |
this.add(getOutputChannelSelectionPanel(), gbc); |
|
125 |
|
|
126 |
initTable(); |
|
127 |
} |
|
128 |
|
|
129 |
/** |
|
130 |
* Gets the output panel (SEXTANTE) |
|
131 |
* @return |
|
132 |
*/ |
|
133 |
private JPanel getOutputChannelSelectionPanel() { |
|
134 |
if(outputPanel == null) { |
|
135 |
try { |
|
136 |
outputPanel = new JPanel(); |
|
137 |
outputPanel.setLayout(new BorderLayout()); |
|
138 |
final OutputObjectsSet ooSet = m_Algorithm.getOutputObjects(); |
|
139 |
final Output out = ooSet.getOutput(DissolveAlgorithm.RESULT); |
|
140 |
outputChannelSelectionPanel = new OutputChannelSelectionPanel(out, m_Algorithm.getParameters()); |
|
141 |
outputPanel.add(new JLabel(" " + GeoProcessLocator.getGeoProcessManager().getTranslation("Dissolve") + |
|
142 |
" [" + GeoProcessLocator.getGeoProcessManager().getTranslation("Vectorial") + |
|
143 |
"] "), BorderLayout.WEST); |
|
144 |
outputPanel.add(outputChannelSelectionPanel, BorderLayout.CENTER); |
|
145 |
} catch (final Exception e) { |
|
146 |
Sextante.addErrorToLog(e); |
|
147 |
} |
|
148 |
} |
|
149 |
return outputPanel; |
|
150 |
} |
|
151 |
|
|
152 |
/** |
|
153 |
* Gets the output panel |
|
154 |
* @return |
|
155 |
*/ |
|
156 |
@SuppressWarnings("unused") |
|
157 |
private AlgorithmOutputPanel getAlgorithmOutputPanel() { |
|
158 |
if(algorithmOutputPanel == null) |
|
159 |
algorithmOutputPanel = new AlgorithmOutputPanel(); |
|
160 |
return algorithmOutputPanel; |
|
161 |
} |
|
162 |
|
|
163 |
/** |
|
164 |
* Gets a new JPanel with the text and JComboBox |
|
165 |
* @param text |
|
166 |
* @param combo |
|
167 |
* @return |
|
168 |
*/ |
|
169 |
public JPanel getComboPanel(String text, JComboBox combo) { |
|
170 |
JPanel panel = new JPanel(); |
|
171 |
GridBagLayout gbl = new GridBagLayout(); |
|
172 |
panel.setLayout(gbl); |
|
173 |
|
|
174 |
GridBagConstraints gbc = new GridBagConstraints(); |
|
175 |
gbc.fill = GridBagConstraints.NONE; |
|
176 |
gbc.weightx = 0; |
|
177 |
gbc.gridx = 0; |
|
178 |
gbc.insets = new Insets(0, 2, 0, 5); |
|
179 |
JLabel label = new JLabel(text); |
|
180 |
label.setPreferredSize(new Dimension(180, 18)); |
|
181 |
panel.add(label, gbc); |
|
182 |
|
|
183 |
gbc.fill = GridBagConstraints.HORIZONTAL; |
|
184 |
gbc.weightx = 1.0; |
|
185 |
gbc.gridx = 1; |
|
186 |
gbc.anchor = GridBagConstraints.EAST; |
|
187 |
gbc.insets = new Insets(0, 2, 0, 0); |
|
188 |
panel.add(combo, gbc); |
|
189 |
return panel; |
|
190 |
} |
|
191 |
|
|
192 |
/** |
|
193 |
* Gets a ComboBox |
|
194 |
* @return |
|
195 |
*/ |
|
196 |
public JComboBox getLayersCombo() { |
|
197 |
if(layersCombo == null) { |
|
198 |
layersCombo = new JComboBox(); |
|
199 |
layersCombo.setPreferredSize(new Dimension(0, 18)); |
|
200 |
ComboBoxModel comboModel = new DefaultComboBoxModel(getLayerList()); |
|
201 |
layersCombo.setModel(comboModel); |
|
202 |
layersCombo.addActionListener(this); |
|
203 |
} |
|
204 |
return layersCombo; |
|
205 |
} |
|
206 |
|
|
207 |
/** |
|
208 |
* Gets a ComboBox |
|
209 |
* @return |
|
210 |
*/ |
|
211 |
public JComboBox getFieldsCombo() { |
|
212 |
if(fieldsCombo == null) { |
|
213 |
fieldsCombo = new JComboBox(); |
|
214 |
fieldsCombo.setPreferredSize(new Dimension(0, 18)); |
|
215 |
List<String> fieldList = getFieldList(); |
|
216 |
fieldsCombo.removeAllItems(); |
|
217 |
for (int i = 0; i < fieldList.size(); i++) |
|
218 |
fieldsCombo.addItem(fieldList.get(i)); |
|
219 |
} |
|
220 |
return fieldsCombo; |
|
221 |
} |
|
222 |
|
|
223 |
/** |
|
224 |
* Gets a CheckBox |
|
225 |
* @return |
|
226 |
*/ |
|
227 |
public JCheckBox getSelectionCheck() { |
|
228 |
if(selectionOnly == null) { |
|
229 |
selectionOnly = new JCheckBox(GeoProcessLocator.getGeoProcessManager().getTranslation("Selected_geometries")); |
|
230 |
} |
|
231 |
return selectionOnly; |
|
232 |
} |
|
233 |
|
|
234 |
/** |
|
235 |
* Gets a CheckBox |
|
236 |
* @return |
|
237 |
*/ |
|
238 |
public JCheckBox getAdjacentCheck() { |
|
239 |
if(adjacentOnly == null) { |
|
240 |
adjacentOnly = new JCheckBox(GeoProcessLocator.getGeoProcessManager().getTranslation("adjacent_geometries_only")); |
|
241 |
} |
|
242 |
return adjacentOnly; |
|
243 |
} |
|
244 |
|
|
245 |
/** |
|
246 |
* Gets the summary table |
|
247 |
* @return TableContainer |
|
248 |
*/ |
|
249 |
public TableContainer getRadioButtonTable() { |
|
250 |
if (table == null) { |
|
251 |
table = new TableContainer(columnNames, columnWidths, null); |
|
252 |
table.setModel("ARGBBandSelectorModel"); |
|
253 |
table.setControlVisible(false); |
|
254 |
table.initialize(); |
|
255 |
} |
|
256 |
return table; |
|
257 |
} |
|
258 |
|
|
259 |
//------------------------------------------------------------ |
|
260 |
|
|
261 |
/* |
|
262 |
* (non-Javadoc) |
|
263 |
* @see java.awt.event.ActionListener#actionPerformed(java.awt.event.ActionEvent) |
|
264 |
*/ |
|
265 |
public void actionPerformed(ActionEvent e) { |
|
266 |
if(e.getSource() == getLayersCombo()) { |
|
267 |
//Recarga el combo de campos |
|
268 |
List<String> fieldList = getFieldList(); |
|
269 |
getFieldsCombo().removeAllItems(); |
|
270 |
for (int i = 0; i < fieldList.size(); i++) |
|
271 |
getFieldsCombo().addItem(fieldList.get(i)); |
|
272 |
|
|
273 |
initTable(); |
|
274 |
} |
|
275 |
} |
|
276 |
|
|
277 |
/** |
|
278 |
* Adds to the table one entry for each field |
|
279 |
*/ |
|
280 |
private void initTable() { |
|
281 |
try { |
|
282 |
getRadioButtonTable().removeAllRows(); |
|
283 |
for (int i = 0; i < getSelectedVectorLayer().getFieldCount(); i++) { |
|
284 |
if(Number.class.isAssignableFrom(getSelectedVectorLayer().getFieldType(i))) |
|
285 |
addTableRow(getSelectedVectorLayer().getFieldName(i)); |
|
286 |
} |
|
287 |
} catch (NotInitializeException e) { |
|
288 |
Sextante.addErrorToLog(e); |
|
289 |
} |
|
290 |
} |
|
291 |
|
|
292 |
/** |
|
293 |
* A�ade una banda a la tabla bandas de la imagen asignandole un nombre y |
|
294 |
* valor a los checkbox |
|
295 |
* @param bandName Nombre de la banda |
|
296 |
* @throws NotInitializeException |
|
297 |
*/ |
|
298 |
private void addTableRow(String fieldName) throws NotInitializeException { |
|
299 |
Object[] row = { new Boolean(false), |
|
300 |
new Boolean(false), |
|
301 |
new Boolean(false), |
|
302 |
new Boolean(false), |
|
303 |
fieldName }; |
|
304 |
getRadioButtonTable().addRow(row); |
|
305 |
} |
|
306 |
|
|
307 |
@Override |
|
308 |
public void assignParameters() { |
|
309 |
try { |
|
310 |
ParametersSet params = m_Algorithm.getParameters(); |
|
311 |
params.getParameter(DissolveAlgorithm.LAYER).setParameterValue(getSelectedVectorLayer()); |
|
312 |
params.getParameter(DissolveAlgorithm.FIELD).setParameterValue(fieldsCombo.getSelectedIndex()); |
|
313 |
params.getParameter(DissolveAlgorithm.SELECTED_GEOM).setParameterValue(getSelectionCheck().isSelected()); |
|
314 |
params.getParameter(DissolveAlgorithm.DISSOLV_ADJ).setParameterValue(getAdjacentCheck().isSelected()); |
|
315 |
|
|
316 |
params.getParameter(DissolveAlgorithm.FUNCTION_LIST).setParameterValue(getValues()); |
|
317 |
|
|
318 |
OutputObjectsSet ooSet = m_Algorithm.getOutputObjects(); |
|
319 |
Output out = ooSet.getOutput(DissolveAlgorithm.RESULT); |
|
320 |
|
|
321 |
//Reponer estas l?neas para cambiar el panel de salida y comentar la siguiente |
|
322 |
//AlgorithmOutputPanel fsp = getAlgorithmOutputPanel(); |
|
323 |
//out.setOutputChannel(new CompositeSourceOutputChannel(fsp.getOutputParameters())); |
|
324 |
out.setOutputChannel(outputChannelSelectionPanel.getOutputChannel()); |
|
325 |
} catch (Exception e) { |
|
326 |
Sextante.addErrorToLog(e); |
|
327 |
} |
|
328 |
} |
|
329 |
|
|
330 |
/** |
|
331 |
* Formats the content of the table |
|
332 |
* @return |
|
333 |
*/ |
|
334 |
private String getValues() { |
|
335 |
String str = ""; |
|
336 |
try { |
|
337 |
for (int i = 0; i < getRadioButtonTable().getRowCount(); i++) { |
|
338 |
str = str + (String)getRadioButtonTable().getModel().getValueAt(i, 4) + ","; |
|
339 |
for (int j = 0; j < getRadioButtonTable().getModel().getColumnCount() - 1; j++) |
|
340 |
if(((Boolean)getRadioButtonTable().getModel().getValueAt(i, j)).booleanValue()) |
|
341 |
str = str + DissolveAlgorithm.Summary[j] + ","; |
|
342 |
str = str.substring(0, str.length() - 1) + ";"; |
|
343 |
} |
|
344 |
} catch (NotInitializeException e) { |
|
345 |
Sextante.addErrorToLog(e); |
|
346 |
} |
|
347 |
return (str.equals("")) ? str : str.substring(0, str.length() - 1); |
|
348 |
} |
|
349 |
|
|
350 |
@Override |
|
351 |
public void setOutputValue(String arg0, String arg1) { |
|
352 |
|
|
353 |
} |
|
354 |
|
|
355 |
@Override |
|
356 |
public void setParameterValue(String arg0, String arg1) { |
|
357 |
|
|
358 |
} |
|
359 |
|
|
360 |
/** |
|
361 |
* Gets the input layer list |
|
362 |
* @return |
|
363 |
*/ |
|
364 |
private ObjectAndDescription[] getLayerList() { |
|
365 |
IVectorLayer[] layers = SextanteGUI.getInputFactory() |
|
366 |
.getVectorLayers(IVectorLayer.SHAPE_TYPE_WRONG); |
|
367 |
ObjectAndDescription[] oad = new ObjectAndDescription[layers.length]; |
|
368 |
for (int i = 0; i < layers.length; i++) |
|
369 |
oad[i] = new ObjectAndDescription(layers[i].getName(), layers[i]); |
|
370 |
return oad; |
|
371 |
} |
|
372 |
|
|
373 |
/** |
|
374 |
* Gets the selected vector layer in the JComboBox |
|
375 |
* @return |
|
376 |
*/ |
|
377 |
private IVectorLayer getSelectedVectorLayer() { |
|
378 |
if(layersCombo.getSelectedItem() != null) |
|
379 |
return (IVectorLayer)((ObjectAndDescription)layersCombo.getSelectedItem()).getObject(); |
|
380 |
return null; |
|
381 |
} |
|
382 |
|
|
383 |
/** |
|
384 |
* Gets the field list of the selected layer |
|
385 |
* @return |
|
386 |
*/ |
|
387 |
public List<String> getFieldList() { |
|
388 |
IVectorLayer layer = getSelectedVectorLayer(); |
|
389 |
return Arrays.asList(layer.getFieldNames()); |
|
390 |
} |
|
391 |
} |
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/DissolveLibrary.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or |
|
7 |
* modify it under the terms of the GNU General Public License |
|
8 |
* as published by the Free Software Foundation; either version 2 |
|
9 |
* of the License, or (at your option) any later version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, |
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
* GNU General Public License for more details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License |
|
17 |
* along with this program; if not, write to the Free Software |
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
20 |
* |
|
21 |
* For any additional information, do not hesitate to contact us |
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com. |
|
23 |
*/ |
|
24 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
25 |
|
|
26 |
import org.gvsig.geoprocess.algorithm.base.core.AlgorithmAbstractLibrary; |
|
27 |
import org.gvsig.i18n.Messages; |
|
28 |
import org.gvsig.tools.library.LibraryException; |
|
29 |
|
|
30 |
/** |
|
31 |
* Initialization of DissolveLibrary library. |
|
32 |
* |
|
33 |
* @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a> |
|
34 |
*/ |
|
35 |
public class DissolveLibrary extends AlgorithmAbstractLibrary { |
|
36 |
|
|
37 |
@Override |
|
38 |
protected void doInitialize() throws LibraryException { |
|
39 |
|
|
40 |
} |
|
41 |
|
|
42 |
@Override |
|
43 |
protected void doPostInitialize() throws LibraryException { |
|
44 |
Messages.addResourceFamily( |
|
45 |
"org.gvsig.geoprocess.algorithm.dissolve.dissolve", |
|
46 |
DissolveLibrary.class.getClassLoader(), DissolveLibrary.class |
|
47 |
.getClass().getName()); |
|
48 |
|
|
49 |
registerGeoProcess(new DissolveAlgorithm()); |
|
50 |
} |
|
51 |
|
|
52 |
} |
org.gvsig.geoprocess/tags/org.gvsig.geoprocess-2.2.275/org.gvsig.geoprocess.algorithm/org.gvsig.geoprocess.algorithm.dissolve/src/main/java/org/gvsig/geoprocess/algorithm/dissolve/Summary.java | ||
---|---|---|
1 |
/** |
|
2 |
* gvSIG. Desktop Geographic Information System. |
|
3 |
* |
|
4 |
* Copyright (C) 2007-2012 gvSIG Association. |
|
5 |
* |
|
6 |
* This program is free software; you can redistribute it and/or |
|
7 |
* modify it under the terms of the GNU General Public License |
|
8 |
* as published by the Free Software Foundation; either version 2 |
|
9 |
* of the License, or (at your option) any later version. |
|
10 |
* |
|
11 |
* This program is distributed in the hope that it will be useful, |
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
14 |
* GNU General Public License for more details. |
|
15 |
* |
|
16 |
* You should have received a copy of the GNU General Public License |
|
17 |
* along with this program; if not, write to the Free Software |
|
18 |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, |
|
19 |
* MA 02110-1301, USA. |
|
20 |
* |
|
21 |
* For any additional information, do not hesitate to contact us |
|
22 |
* at info AT gvsig.com, or visit our website www.gvsig.com. |
|
23 |
*/ |
|
24 |
package org.gvsig.geoprocess.algorithm.dissolve; |
|
25 |
|
|
26 |
import es.unex.sextante.core.Sextante; |
|
27 |
|
|
28 |
import org.gvsig.fmap.dal.feature.EditableFeature; |
|
29 |
import org.gvsig.fmap.dal.feature.Feature; |
|
30 |
import org.gvsig.fmap.dal.feature.FeatureAttributeDescriptor; |
|
31 |
import org.gvsig.fmap.dal.feature.FeatureType; |
|
32 |
|
|
33 |
/** |
|
34 |
* <p> |
|
35 |
* Computes summary functions. There are four summary functions, maximum, minimum, |
|
36 |
* average and sum. |
|
37 |
* </p> |
|
38 |
* <p> |
|
39 |
* At the beginning you have to call loadDefaultSummarizes with the |
|
40 |
* first analyzed feature. Next, the function updateValues will update the statistics |
|
41 |
* values and in the end you have to load the statistics value in the output feature |
|
42 |
* calling the function loadEditableFeature. |
|
43 |
* </p> |
|
44 |
* |
|
45 |
* @author <a href="mailto:nachobrodin@gmail.com">Nacho Brodin</a> |
|
46 |
*/ |
|
47 |
public class Summary { |
|
48 |
private IDissolveRule rule = null; |
|
49 |
private double max = Double.NEGATIVE_INFINITY; |
|
50 |
private double min = Double.POSITIVE_INFINITY; |
|
51 |
private double avg = 0; |
|
52 |
private double sum = 0; |
|
53 |
private double sumAvg = 0; |
|
54 |
private double nfeat = 0; |
|
55 |
private FeatureType featType = null; |
|
56 |
|
|
57 |
public Summary(IDissolveRule criteria, FeatureType featType) { |
|
58 |
this.rule = criteria; |
|
59 |
this.featType = featType; |
|
60 |
} |
|
61 |
|
|
62 |
/** |
|
63 |
* This function updates statistics values reading the field |
|
64 |
* values of the selected feature . |
|
65 |
* @param feature |
|
66 |
*/ |
|
67 |
public void updateValues(Feature feature) { |
|
68 |
try { |
|
69 |
FeatureAttributeDescriptor[] desc = featType.getAttributeDescriptors(); |
|
70 |
Object obj = null; |
|
71 |
String fName = null; |
|
72 |
|
|
73 |
for (int i = 0; i < desc.length; i++) { |
|
74 |
String fieldName = desc[i].getName(); |
|
75 |
|
|
76 |
if(fieldName.endsWith("_Max")) { |
|
77 |
fName = rule.getFieldName("Max"); |
|
78 |
if(fName != null) { |
|
79 |
obj = feature.get(fName); |
|
80 |
max = Math.max(max, ((Number)obj).doubleValue()); |
|
81 |
} |
|
82 |
} |
|
83 |
|
|
84 |
if(fieldName.endsWith("_Min")) { |
|
85 |
fName = rule.getFieldName("Min"); |
|
86 |
if(fName != null) { |
|
87 |
obj = feature.get(fName); |
|
88 |
min = Math.min(min, ((Number)obj).doubleValue()); |
|
89 |
} |
|
90 |
} |
|
91 |
|
|
92 |
if(fieldName.endsWith("_Sum")) { |
|
93 |
fName = rule.getFieldName("Sum"); |
|
94 |
if(fName != null) { |
|
95 |
obj = feature.get(fName); |
|
96 |
sum = sum + ((Number)obj).doubleValue(); |
|
97 |
} |
|
98 |
} |
|
99 |
|
|
100 |
if(fieldName.endsWith("_Avg")) { |
|
101 |
fName = rule.getFieldName("Avg"); |
|
102 |
if(fName != null) { |
|
103 |
obj = feature.get(fName); |
|
104 |
sumAvg = sumAvg + ((Number)obj).doubleValue(); |
|
105 |
nfeat ++; |
|
106 |
avg = sumAvg / nfeat; |
|
107 |
} |
|
108 |
} |
|
109 |
fName = null; |
|
110 |
} |
|
111 |
|
|
112 |
} catch (NumberFormatException e) { |
|
113 |
Sextante.addErrorToLog(e); |
|
114 |
} |
|
115 |
} |
|
116 |
|
|
117 |
/** |
|
118 |
* Loads an EditableFeature with the statistics |
|
119 |
* @param feat |
|
120 |
*/ |
|
121 |
public void loadEditableFeature(EditableFeature feat) { |
|
122 |
FeatureAttributeDescriptor[] desc = featType.getAttributeDescriptors(); |
|
123 |
for (int i = 0; i < desc.length; i++) { |
|
124 |
String fieldName = desc[i].getName(); |
|
125 |
if(fieldName.endsWith("_Max")) { |
|
126 |
if(feat.getType().getAttributeDescriptor(fieldName) != null) |
|
127 |
feat.setDouble(fieldName, getMax()); |
|
128 |
} |
|
129 |
|
|
130 |
if(fieldName.endsWith("_Min")) { |
|
131 |
if(feat.getType().getAttributeDescriptor(fieldName) != null) |
|
132 |
feat.setDouble(fieldName, getMin()); |
|
133 |
} |
|
134 |
|
|
135 |
if(fieldName.endsWith("_Sum")) { |
|
136 |
if(feat.getType().getAttributeDescriptor(fieldName) != null) |
|
137 |
feat.setDouble(fieldName, getSum()); |
|
138 |
} |
|
139 |
|
|
140 |
if(fieldName.endsWith("_Avg")) { |
|
141 |
if(feat.getType().getAttributeDescriptor(fieldName) != null) |
|
142 |
feat.setDouble(fieldName, getAvg()); |
|
143 |
} |
|
144 |
} |
|
145 |
} |
|
146 |
|
|
147 |
/** |
|
148 |
* Loads the default statistics values. |
|
149 |
* @param feature |
|
150 |
*/ |
|
151 |
public void loadDefaultSummarizes(Feature feature) { |
|
152 |
try { |
|
153 |
FeatureAttributeDescriptor[] desc = featType.getAttributeDescriptors(); |
|
154 |
Object obj = null; |
|
155 |
String fName = null; |
|
156 |
sum = avg = sumAvg = nfeat = 0; |
|
157 |
|
|
158 |
for (int i = 0; i < desc.length; i++) { |
|
159 |
String fieldName = desc[i].getName(); |
|
160 |
if(fieldName.endsWith("_Max")) { |
|
161 |
fName = rule.getFieldName("Max"); |
|
162 |
if(fName != null) { |
|
163 |
obj = feature.get(fName); |
|
164 |
max = ((Number)obj).doubleValue(); |
|
165 |
} |
|
166 |
} |
|
167 |
|
|
168 |
if(fieldName.endsWith("_Min")) { |
|
169 |
fName = rule.getFieldName("Min"); |
|
170 |
if(fName != null) { |
|
171 |
obj = feature.get(fName); |
|
172 |
min = ((Number)obj).doubleValue(); |
|
173 |
} |
|
174 |
} |
|
175 |
|
|
176 |
fName = null; |
|
177 |
} |
|
178 |
|
|
179 |
} catch (NumberFormatException e) { |
|
180 |
Sextante.addErrorToLog(e); |
|
181 |
} |
|
182 |
} |
|
183 |
|
|
184 |
public double getMax() { |
|
185 |
return max; |
|
186 |
} |
|
187 |
|
|
188 |
public void setMax(double max) { |
|
189 |
this.max = max; |
|
190 |
} |
|
191 |
|
|
192 |
public double getMin() { |
|
193 |
return min; |
|
194 |
} |
|
195 |
|
|
196 |
public void setMin(double min) { |
|
197 |
this.min = min; |
|
198 |
} |
|
199 |
|
|
200 |
public double getAvg() { |
|
201 |
return avg; |
Also available in: Unified diff