root / trunk / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / dissolve / fmap / FeatureDissolver.java @ 13874
History | View | Annotate | Download (19.8 KB)
1 | 5918 | azabala | /*
|
---|---|---|---|
2 | * Created on 12-may-2006
|
||
3 | *
|
||
4 | * gvSIG. Sistema de Informaci?n Geogr?fica de la Generalitat Valenciana
|
||
5 | *
|
||
6 | * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
|
||
7 | *
|
||
8 | * This program is free software; you can redistribute it and/or
|
||
9 | * modify it under the terms of the GNU General Public License
|
||
10 | * as published by the Free Software Foundation; either version 2
|
||
11 | * of the License, or (at your option) any later version.
|
||
12 | *
|
||
13 | * This program is distributed in the hope that it will be useful,
|
||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
16 | * GNU General Public License for more details.
|
||
17 | *
|
||
18 | * You should have received a copy of the GNU General Public License
|
||
19 | * along with this program; if not, write to the Free Software
|
||
20 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,USA.
|
||
21 | *
|
||
22 | * For more information, contact:
|
||
23 | *
|
||
24 | * Generalitat Valenciana
|
||
25 | * Conselleria d'Infraestructures i Transport
|
||
26 | * Av. Blasco Ib??ez, 50
|
||
27 | * 46010 VALENCIA
|
||
28 | * SPAIN
|
||
29 | *
|
||
30 | * +34 963862235
|
||
31 | * gvsig@gva.es
|
||
32 | * www.gvsig.gva.es
|
||
33 | *
|
||
34 | * or
|
||
35 | *
|
||
36 | * IVER T.I. S.A
|
||
37 | * Salamanca 50
|
||
38 | * 46005 Valencia
|
||
39 | * Spain
|
||
40 | *
|
||
41 | * +34 963163400
|
||
42 | * dac@iver.es
|
||
43 | */
|
||
44 | /* CVS MESSAGES:
|
||
45 | *
|
||
46 | * $Id$
|
||
47 | * $Log$
|
||
48 | 13874 | jaume | * Revision 1.6 2007-09-19 16:06:27 jaume
|
49 | * ReadExpansionFileException removed from this context
|
||
50 | *
|
||
51 | * Revision 1.5 2007/08/07 15:44:09 azabala
|
||
52 | 12951 | azabala | * centrilizing JTS in JTSFacade and allowing all geometry types (not only Polygon)
|
53 | *
|
||
54 | * Revision 1.4 2007/03/06 16:47:58 caballero
|
||
55 | 10626 | caballero | * Exceptions
|
56 | *
|
||
57 | * Revision 1.3 2006/08/11 16:27:46 azabala
|
||
58 | 6551 | azabala | * *** empty log message ***
|
59 | *
|
||
60 | 6749 | azabala | * Revision 1.2 2006/07/27 17:21:06 azabala
|
61 | * *** empty log message ***
|
||
62 | *
|
||
63 | 6551 | azabala | * Revision 1.1 2006/06/20 18:20:45 azabala
|
64 | 5918 | azabala | * first version in cvs
|
65 | *
|
||
66 | * Revision 1.2 2006/06/02 18:21:28 azabala
|
||
67 | * *** empty log message ***
|
||
68 | *
|
||
69 | * Revision 1.1 2006/05/24 21:11:14 azabala
|
||
70 | * primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
|
||
71 | *
|
||
72 | *
|
||
73 | */
|
||
74 | package com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap; |
||
75 | |||
76 | import java.awt.geom.Rectangle2D; |
||
77 | import java.io.IOException; |
||
78 | import java.util.ArrayList; |
||
79 | import java.util.Enumeration; |
||
80 | import java.util.List; |
||
81 | import java.util.Map; |
||
82 | import java.util.Stack; |
||
83 | |||
84 | import org.cresques.cts.ICoordTrans; |
||
85 | |||
86 | 10626 | caballero | import com.hardcode.gdbms.driver.exceptions.ReadDriverException; |
87 | import com.hardcode.gdbms.engine.data.driver.DriverException; |
||
88 | import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException; |
||
89 | import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException; |
||
90 | import com.iver.cit.gvsig.exceptions.visitors.StartVisitorException; |
||
91 | import com.iver.cit.gvsig.exceptions.visitors.StopVisitorException; |
||
92 | import com.iver.cit.gvsig.exceptions.visitors.VisitorException; |
||
93 | 5918 | azabala | import com.iver.cit.gvsig.fmap.core.IFeature; |
94 | import com.iver.cit.gvsig.fmap.core.IGeometry; |
||
95 | import com.iver.cit.gvsig.fmap.core.v02.FConverter; |
||
96 | import com.iver.cit.gvsig.fmap.drivers.DriverIOException; |
||
97 | import com.iver.cit.gvsig.fmap.layers.FBitSet; |
||
98 | import com.iver.cit.gvsig.fmap.layers.FLayer; |
||
99 | import com.iver.cit.gvsig.fmap.layers.FLyrVect; |
||
100 | import com.iver.cit.gvsig.fmap.layers.ReadableVectorial; |
||
101 | import com.iver.cit.gvsig.fmap.layers.SelectableDataSource; |
||
102 | import com.iver.cit.gvsig.fmap.layers.layerOperations.AlphanumericData; |
||
103 | import com.iver.cit.gvsig.fmap.layers.layerOperations.VectorialData; |
||
104 | import com.iver.cit.gvsig.fmap.operations.strategies.FeatureVisitor; |
||
105 | import com.iver.cit.gvsig.fmap.operations.strategies.Strategy; |
||
106 | import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager; |
||
107 | import com.iver.cit.gvsig.geoprocess.core.fmap.FeatureProcessor; |
||
108 | import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException; |
||
109 | 12951 | azabala | import com.iver.cit.gvsig.geoprocess.core.util.JTSFacade; |
110 | 5918 | azabala | import com.iver.utiles.swing.threads.Cancellable; |
111 | import com.iver.utiles.swing.threads.CancellableMonitorable; |
||
112 | import com.vividsolutions.jts.geom.Geometry; |
||
113 | |||
114 | /**
|
||
115 | * <p>
|
||
116 | * Dissolve features in base of a given dissolve criteria.
|
||
117 | * </p>
|
||
118 | * By 'dissolving' we understand the union of the geometry of many features
|
||
119 | 10626 | caballero | *
|
120 | 5918 | azabala | * @author azabala
|
121 | 10626 | caballero | *
|
122 | 5918 | azabala | */
|
123 | public class FeatureDissolver { |
||
124 | |||
125 | public static final int ALPHANUMERIC_DISSOLVE = 0; |
||
126 | |||
127 | public static final int SPATIAL_DISSOLVE = 1; |
||
128 | |||
129 | private int dissolveType = ALPHANUMERIC_DISSOLVE; |
||
130 | |||
131 | /**
|
||
132 | * Fetches attributes of disolved layer features
|
||
133 | */
|
||
134 | protected SelectableDataSource recordset;
|
||
135 | 10626 | caballero | |
136 | 5918 | azabala | protected ICoordTrans ct;
|
137 | |||
138 | /**
|
||
139 | * Is used to do spatial querys (looking for adjacent polygons to visited
|
||
140 | * feature geometry
|
||
141 | */
|
||
142 | protected FLyrVect dissolvedLayer;
|
||
143 | 12951 | azabala | |
144 | protected int geometryType; |
||
145 | 5918 | azabala | |
146 | /**
|
||
147 | * It marks all features that have already been dissolved (to avoid process
|
||
148 | * them in subsecuent steps)
|
||
149 | 10626 | caballero | *
|
150 | 5918 | azabala | */
|
151 | protected FBitSet dissolvedGeometries;
|
||
152 | |||
153 | /**
|
||
154 | * Relates a numerical field name with its sumarization functions
|
||
155 | */
|
||
156 | protected Map numericField_sumarizeFunction; |
||
157 | |||
158 | /**
|
||
159 | * Processes results of dissolve operations (save them in a file, or cache
|
||
160 | * them in memory, etc)
|
||
161 | */
|
||
162 | protected FeatureProcessor featureProcessor;
|
||
163 | |||
164 | /**
|
||
165 | * Index of the result
|
||
166 | */
|
||
167 | protected int fid = 0; |
||
168 | |||
169 | /**
|
||
170 | * It decides if two features must be dissolved, and builds the feature
|
||
171 | * resulting of the dissolution
|
||
172 | */
|
||
173 | protected IDissolveCriteria dissolveCriteria;
|
||
174 | |||
175 | /**
|
||
176 | 10626 | caballero | *
|
177 | 5918 | azabala | * @param processor
|
178 | * @param layer
|
||
179 | * @throws GeoprocessException
|
||
180 | */
|
||
181 | public FeatureDissolver(FeatureProcessor processor, FLyrVect layer,
|
||
182 | Map numericField_sumFunction, IDissolveCriteria criteria, int dissolveType) |
||
183 | throws GeoprocessException {
|
||
184 | |||
185 | this.featureProcessor = processor;
|
||
186 | this.numericField_sumarizeFunction = numericField_sumFunction;
|
||
187 | this.dissolveCriteria = criteria;
|
||
188 | this.dissolveType = dissolveType;
|
||
189 | dissolvedGeometries = new FBitSet();
|
||
190 | |||
191 | if (layer instanceof AlphanumericData && layer instanceof VectorialData) { |
||
192 | try {
|
||
193 | dissolvedLayer = (FLyrVect) layer; |
||
194 | 12951 | azabala | geometryType = dissolvedLayer.getShapeType(); |
195 | 5918 | azabala | recordset = ((AlphanumericData) layer).getRecordset(); |
196 | ct = dissolvedLayer.getCoordTrans(); |
||
197 | featureProcessor.start(); |
||
198 | 10626 | caballero | } catch (ReadDriverException e) {
|
199 | 5918 | azabala | throw new GeoprocessException( |
200 | "Error al acceder al recordset de la capa "
|
||
201 | + layer.getName(), e); |
||
202 | 10626 | caballero | } catch (StartVisitorException e) {
|
203 | 5918 | azabala | throw new GeoprocessException( |
204 | "Error al preparar donde se van a escribir los resultados del dissolve de la capa "
|
||
205 | + layer.getName(), e); |
||
206 | } |
||
207 | } else {
|
||
208 | throw new GeoprocessException( |
||
209 | "La capa a dissolver debe ser VectorialData y AlphanumericData");
|
||
210 | } |
||
211 | } |
||
212 | |||
213 | public void setDissolveCriteria(IDissolveCriteria criteria) { |
||
214 | this.dissolveCriteria = criteria;
|
||
215 | } |
||
216 | |||
217 | public void setDissolvedAttributesInfo(Map numericField_sumFunction) { |
||
218 | this.numericField_sumarizeFunction = numericField_sumFunction;
|
||
219 | } |
||
220 | |||
221 | public int getNumProcessedGeometries() { |
||
222 | return dissolvedGeometries.cardinality();
|
||
223 | } |
||
224 | |||
225 | public void dissolve(CancellableMonitorable cancel) throws GeoprocessException { |
||
226 | try {
|
||
227 | ReadableVectorial va = dissolvedLayer.getSource(); |
||
228 | va.start(); |
||
229 | for (int i = 0; i < va.getShapeCount(); i++) {// for each geometry |
||
230 | if (verifyCancelation(cancel, va)) {
|
||
231 | this.featureProcessor.finish();
|
||
232 | return;
|
||
233 | } |
||
234 | 10626 | caballero | |
235 | 5918 | azabala | //Ver si podemos optimizar esto de forma que solo
|
236 | //se procesasen los elementos no marcados en el bitset
|
||
237 | //(bitset de acceso aleatorio)
|
||
238 | 10626 | caballero | |
239 | 5918 | azabala | if (!dissolvedGeometries.get(i)) {
|
240 | // if we havent processed this element yet
|
||
241 | try {
|
||
242 | if(dissolveType == SPATIAL_DISSOLVE)
|
||
243 | process( i, va, cancel); |
||
244 | else if(dissolveType == ALPHANUMERIC_DISSOLVE) |
||
245 | processAlphanumeric(i, va, cancel); |
||
246 | 10626 | caballero | } catch (ReadDriverException e) {
|
247 | 5918 | azabala | throw new GeoprocessException( |
248 | "Error accediendo a datos durante dissolve", e);
|
||
249 | 10626 | caballero | } catch (ProcessVisitorException e) {
|
250 | 5918 | azabala | throw new GeoprocessException( |
251 | "Error procesando datos durante dissolve", e);
|
||
252 | 10626 | caballero | } catch (VisitorException e) {
|
253 | throw new GeoprocessException( |
||
254 | "Error accediendo a datos durante dissolve", e);
|
||
255 | 5918 | azabala | } |
256 | }// if
|
||
257 | }// for
|
||
258 | va.stop(); |
||
259 | this.featureProcessor.finish();
|
||
260 | 10626 | caballero | } catch (ReadDriverException e) {
|
261 | // TODO Auto-generated catch block
|
||
262 | 5918 | azabala | e.printStackTrace(); |
263 | 10626 | caballero | } catch (StopVisitorException e) {
|
264 | // TODO Auto-generated catch block
|
||
265 | e.printStackTrace(); |
||
266 | 5918 | azabala | } |
267 | } |
||
268 | |||
269 | /**
|
||
270 | * Verifies cancelation events, and return a boolean flag if processes must
|
||
271 | * be stopped for this cancelations events.
|
||
272 | 10626 | caballero | *
|
273 | 5918 | azabala | * @param cancel
|
274 | * @param va
|
||
275 | * @param visitor
|
||
276 | * @return
|
||
277 | * @throws DriverIOException
|
||
278 | */
|
||
279 | protected boolean verifyCancelation(Cancellable cancel, ReadableVectorial va) { |
||
280 | if (cancel != null) { |
||
281 | if (cancel.isCanceled()) {
|
||
282 | try {
|
||
283 | va.stop(); |
||
284 | } finally {
|
||
285 | return true; |
||
286 | } |
||
287 | } |
||
288 | } |
||
289 | return false; |
||
290 | } |
||
291 | |||
292 | class DissolveVisitor implements FeatureVisitor { |
||
293 | 10626 | caballero | |
294 | 5918 | azabala | IDissolveCriteria criteria; |
295 | int index1;
|
||
296 | Stack stack;
|
||
297 | List geometries;
|
||
298 | ReadableVectorial va; |
||
299 | FunctionSummarizer sumarizer; |
||
300 | CancellableMonitorable cancel; |
||
301 | |||
302 | DissolveVisitor(IDissolveCriteria criteria, int index1, Stack stack, |
||
303 | List geometries, ReadableVectorial va,
|
||
304 | FunctionSummarizer sumarizer, CancellableMonitorable cancel) { |
||
305 | this.criteria = criteria;
|
||
306 | this.index1 = index1;
|
||
307 | this.stack = stack;
|
||
308 | this.geometries = geometries;
|
||
309 | this.va = va;
|
||
310 | this.sumarizer = sumarizer;
|
||
311 | this.cancel = cancel;
|
||
312 | } |
||
313 | |||
314 | 10626 | caballero | public void visit(IGeometry g, int index2) throws VisitorException, ProcessVisitorException { |
315 | 5918 | azabala | if(g == null) |
316 | return;
|
||
317 | if (verifyCancelation(cancel, va)) {
|
||
318 | // TODO Revisar si hay problemas por llamar a finish
|
||
319 | // varias veces
|
||
320 | featureProcessor.finish(); |
||
321 | return;
|
||
322 | } |
||
323 | 10626 | caballero | |
324 | 5918 | azabala | if(index1 == index2){
|
325 | //we dont want dissolve a feature with itself
|
||
326 | return;
|
||
327 | } |
||
328 | |||
329 | if (dissolvedGeometries.get(index2)) {
|
||
330 | // Esta geometria ya ha sido procesada
|
||
331 | return;
|
||
332 | } |
||
333 | |||
334 | if (criteria.verifyIfDissolve(index1, index2)) {
|
||
335 | //Redise?ar esto (es para que valga tanto para dissolves
|
||
336 | //espaciales como alfanum?ricos
|
||
337 | if(stack != null) |
||
338 | stack.push(new Integer(index2)); |
||
339 | try {
|
||
340 | if(criteria instanceof ISpatialDissolveCriteria){ |
||
341 | 10626 | caballero | //Para ver el criterio de disolucion ya se ha
|
342 | 5918 | azabala | //leido la geometria
|
343 | geometries.add( |
||
344 | ((ISpatialDissolveCriteria)criteria). |
||
345 | getSecondGeometry().toJTSGeometry()); |
||
346 | }else{
|
||
347 | IGeometry g2 = va.getShape(index2); |
||
348 | if(ct != null) |
||
349 | g2.reProject(ct); |
||
350 | geometries.add(g2.toJTSGeometry()); |
||
351 | } |
||
352 | sumarizer.applySumarizeFunction(index2); |
||
353 | 10626 | caballero | } catch (ReadDriverException e) {
|
354 | throw new ProcessVisitorException(recordset.getName(),e, |
||
355 | "Error durante lectura de geometria en dissolve");
|
||
356 | 13874 | jaume | } |
357 | 5918 | azabala | //Esto se debe hacer externamente
|
358 | if(stack == null) |
||
359 | dissolvedGeometries.set(index2); |
||
360 | } |
||
361 | }// visit
|
||
362 | |||
363 | public String getProcessDescription() { |
||
364 | return ""; |
||
365 | } |
||
366 | |||
367 | 10626 | caballero | public void stop(FLayer layer) throws VisitorException { |
368 | 5918 | azabala | } |
369 | |||
370 | 10626 | caballero | public boolean start(FLayer layer) throws StartVisitorException { |
371 | 5918 | azabala | return true; |
372 | } |
||
373 | } |
||
374 | 10626 | caballero | |
375 | 5918 | azabala | /**
|
376 | * @param index1
|
||
377 | * @param va
|
||
378 | * @param cancel
|
||
379 | * @throws DriverException
|
||
380 | 10626 | caballero | * @throws ExpansionFileReadException
|
381 | * @throws ReadDriverException
|
||
382 | * @throws VisitorException
|
||
383 | * @throws ProcessWriterException
|
||
384 | 5918 | azabala | * @throws IOException
|
385 | * @throws DriverIOException
|
||
386 | */
|
||
387 | public void processAlphanumeric(int index1, |
||
388 | 10626 | caballero | ReadableVectorial va, |
389 | 5918 | azabala | CancellableMonitorable cancel) |
390 | 10626 | caballero | throws ReadDriverException, ExpansionFileReadException, VisitorException{
|
391 | |||
392 | 5918 | azabala | dissolvedGeometries.set(index1); |
393 | Strategy strategy = StrategyManager.getStrategy(dissolvedLayer); |
||
394 | ArrayList geometries = new ArrayList(); |
||
395 | //we add the 'seed' feature geometry
|
||
396 | IGeometry g1 = va.getShape(index1); |
||
397 | if(g1 == null) |
||
398 | return;
|
||
399 | if(ct != null) |
||
400 | g1.reProject(ct); |
||
401 | geometries.add(g1.toJTSGeometry()); |
||
402 | if(dissolveCriteria instanceof ISpatialDissolveCriteria){ |
||
403 | ((ISpatialDissolveCriteria)dissolveCriteria).setCoordTrans(ct); |
||
404 | ((ISpatialDissolveCriteria)dissolveCriteria).setFirstGeometry(g1); |
||
405 | } |
||
406 | FunctionSummarizer sumarizer = new FunctionSummarizer(
|
||
407 | numericField_sumarizeFunction, recordset); |
||
408 | DissolveVisitor visitor = new DissolveVisitor(dissolveCriteria, index1, null, |
||
409 | geometries, va, sumarizer, cancel); |
||
410 | strategy.process(visitor); |
||
411 | IGeometry newGeometry = FConverter.jts_to_igeometry(union2(geometries)); |
||
412 | List sumarizedValues = sumarizer.getValues();
|
||
413 | IFeature dissolvedFeature = null;
|
||
414 | if(sumarizedValues != null || sumarizedValues.size() != 0){ |
||
415 | dissolvedFeature = dissolveCriteria. |
||
416 | getFeatureBuilder(). |
||
417 | 10626 | caballero | createFeature(newGeometry, |
418 | sumarizedValues, |
||
419 | fid, |
||
420 | 5918 | azabala | index1); |
421 | }else{
|
||
422 | dissolvedFeature = dissolveCriteria. |
||
423 | getFeatureBuilder(). |
||
424 | createFeature(newGeometry, |
||
425 | 10626 | caballero | index1, |
426 | 5918 | azabala | fid); |
427 | } |
||
428 | 12951 | azabala | if(dissolvedFeature.getGeometry() != null){ |
429 | fid++; |
||
430 | featureProcessor.processFeature(dissolvedFeature); |
||
431 | } |
||
432 | 5918 | azabala | dissolveCriteria.clear(); |
433 | } |
||
434 | 10626 | caballero | |
435 | |||
436 | 5918 | azabala | class SpatialDissolveVisitor implements FeatureVisitor { |
437 | 10626 | caballero | |
438 | 5918 | azabala | IDissolveCriteria criteria; |
439 | Geometry geom1; |
||
440 | StackEntry entry1; |
||
441 | Stack stack;
|
||
442 | List geometries;
|
||
443 | ReadableVectorial va; |
||
444 | FunctionSummarizer sumarizer; |
||
445 | CancellableMonitorable cancel; |
||
446 | |||
447 | 10626 | caballero | SpatialDissolveVisitor(IDissolveCriteria criteria, Geometry geo1, StackEntry entry1, |
448 | 5918 | azabala | Stack stack,
|
449 | List geometries, ReadableVectorial va,
|
||
450 | FunctionSummarizer sumarizer, CancellableMonitorable cancel) { |
||
451 | this.criteria = criteria;
|
||
452 | this.geom1 = geo1;
|
||
453 | this.entry1 = entry1;
|
||
454 | this.stack = stack;
|
||
455 | this.geometries = geometries;
|
||
456 | this.va = va;
|
||
457 | this.sumarizer = sumarizer;
|
||
458 | this.cancel = cancel;
|
||
459 | } |
||
460 | 10626 | caballero | |
461 | 5918 | azabala | void setSeed(StackEntry entry, Geometry jtsGeo){
|
462 | this.entry1 = entry;
|
||
463 | this.geom1 = jtsGeo;
|
||
464 | } |
||
465 | |||
466 | 10626 | caballero | |
467 | |||
468 | public void visit(IGeometry g, int index2) throws VisitorException, ProcessVisitorException { |
||
469 | 5918 | azabala | if(g == null) |
470 | return;
|
||
471 | if (verifyCancelation(cancel, va)) {
|
||
472 | // TODO Revisar si hay problemas por llamar a finish
|
||
473 | // varias veces
|
||
474 | featureProcessor.finish(); |
||
475 | return;
|
||
476 | } |
||
477 | 10626 | caballero | |
478 | 5918 | azabala | if(entry1.index == index2){
|
479 | //we dont want dissolve a feature with itself
|
||
480 | return;
|
||
481 | } |
||
482 | |||
483 | if (dissolvedGeometries.get(index2)) {
|
||
484 | // Esta geometria ya ha sido procesada
|
||
485 | return;
|
||
486 | } |
||
487 | if(criteria instanceof ISpatialDissolveCriteria){ |
||
488 | ((ISpatialDissolveCriteria)criteria).setSecondGeometry(g); |
||
489 | } |
||
490 | if (criteria.verifyIfDissolve(entry1.index, index2)) {
|
||
491 | StackEntry entry2 = new StackEntry();
|
||
492 | entry2.g = g; |
||
493 | entry2.index = index2; |
||
494 | stack.push(entry2); |
||
495 | System.out.println("Anado "+index2+ " al stack"); |
||
496 | dumpStack(stack); |
||
497 | if(criteria instanceof ISpatialDissolveCriteria) |
||
498 | { |
||
499 | ISpatialDissolveCriteria c = (ISpatialDissolveCriteria)criteria; |
||
500 | geometries.add(c.getSecondJts()); |
||
501 | }else
|
||
502 | geometries.add(g.toJTSGeometry()); |
||
503 | try {
|
||
504 | sumarizer.applySumarizeFunction(index2); |
||
505 | 10626 | caballero | } catch (ReadDriverException e) {
|
506 | throw new ProcessVisitorException(recordset.getName(),e,"Error al aplicar la funcion de sumarizacion en dissolve"); |
||
507 | 5918 | azabala | } |
508 | dissolvedGeometries.set(index2); |
||
509 | } |
||
510 | }// visit
|
||
511 | |||
512 | public String getProcessDescription() { |
||
513 | return ""; |
||
514 | } |
||
515 | |||
516 | 10626 | caballero | public void stop(FLayer layer) throws VisitorException { |
517 | 5918 | azabala | } |
518 | |||
519 | 10626 | caballero | public boolean start(FLayer layer) throws StartVisitorException { |
520 | 5918 | azabala | return true; |
521 | } |
||
522 | } |
||
523 | 10626 | caballero | |
524 | 5918 | azabala | class StackEntry{ |
525 | public IGeometry g;
|
||
526 | public int index; |
||
527 | } |
||
528 | /**
|
||
529 | * Processes the given feature looking for features to dissolve with. The
|
||
530 | * criteria to decide if dissolve two features is given by
|
||
531 | * IDissolveCriteria.
|
||
532 | 10626 | caballero | *
|
533 | 5918 | azabala | * @param criteria
|
534 | * decides if dissolve two features
|
||
535 | * @param index1
|
||
536 | * index of feature we are processing
|
||
537 | * @param va
|
||
538 | * it reads geometry of features
|
||
539 | * @param cancel
|
||
540 | * listen cancelations
|
||
541 | 10626 | caballero | * @throws ExpansionFileReadException
|
542 | * @throws ReadDriverException
|
||
543 | * @throws VisitorException
|
||
544 | * @throws ProcessWriterException
|
||
545 | 5918 | azabala | * @throws DriverException
|
546 | * @throws IOException
|
||
547 | * @throws DriverIOException
|
||
548 | */
|
||
549 | public void process(int index1, |
||
550 | 10626 | caballero | ReadableVectorial va, |
551 | 5918 | azabala | CancellableMonitorable cancel) |
552 | 10626 | caballero | throws ReadDriverException, ExpansionFileReadException, VisitorException {
|
553 | |||
554 | 5918 | azabala | if(dissolvedGeometries.get(index1))
|
555 | return;
|
||
556 | 10626 | caballero | Strategy strategy = StrategyManager.getStrategy(dissolvedLayer); |
557 | 5918 | azabala | IGeometry g1 = va.getShape(index1); |
558 | if(g1 == null) |
||
559 | return;
|
||
560 | if(ct != null) |
||
561 | g1.reProject(ct); |
||
562 | StackEntry entry = new StackEntry();
|
||
563 | entry.g = g1; |
||
564 | entry.index = index1; |
||
565 | Stack stack = new Stack();//it saves FMap geometries |
||
566 | stack.push(entry); |
||
567 | ArrayList geometries = new ArrayList(); |
||
568 | 10626 | caballero | |
569 | 5918 | azabala | Geometry jtsGeo = g1.toJTSGeometry(); |
570 | geometries.add(jtsGeo);//it saves jts geometries
|
||
571 | 10626 | caballero | |
572 | 5918 | azabala | if(dissolveCriteria instanceof ISpatialDissolveCriteria){ |
573 | ((ISpatialDissolveCriteria)dissolveCriteria).setCoordTrans(ct); |
||
574 | ((ISpatialDissolveCriteria)dissolveCriteria).setFirstGeometry(g1); |
||
575 | } |
||
576 | FunctionSummarizer sumarizer = new FunctionSummarizer(
|
||
577 | numericField_sumarizeFunction, recordset); |
||
578 | 10626 | caballero | SpatialDissolveVisitor visitor = new SpatialDissolveVisitor(dissolveCriteria,
|
579 | jtsGeo, |
||
580 | entry, |
||
581 | 5918 | azabala | stack, |
582 | 10626 | caballero | geometries, |
583 | va, |
||
584 | sumarizer, |
||
585 | 5918 | azabala | cancel); |
586 | 10626 | caballero | |
587 | 5918 | azabala | while (stack.size() != 0) { |
588 | dumpStack(stack); |
||
589 | StackEntry sEntry = (StackEntry) stack.pop(); |
||
590 | dissolvedGeometries.set(sEntry.index); |
||
591 | 10626 | caballero | |
592 | 5918 | azabala | /*//TODO
|
593 | * Revisar si no deberiamos hacer
|
||
594 | * ct.getInverted().convert(rect);
|
||
595 | 10626 | caballero | *
|
596 | 5918 | azabala | * */
|
597 | Rectangle2D rect = sEntry.g.getBounds2D();
|
||
598 | if(ct != null) |
||
599 | rect = ct.convert(rect); |
||
600 | double xmin = rect.getMinX();
|
||
601 | double ymin = rect.getMinY();
|
||
602 | double xmax = rect.getMaxX();
|
||
603 | double ymax = rect.getMaxY();
|
||
604 | double magnify = 15d; |
||
605 | Rectangle2D query = new Rectangle2D.Double(xmin - magnify, ymin |
||
606 | - magnify, (xmax - xmin) + magnify, (ymax - ymin) + magnify); |
||
607 | Geometry jts = sEntry.g.toJTSGeometry(); |
||
608 | visitor.setSeed(sEntry, jts); |
||
609 | strategy.process(visitor, query); |
||
610 | }// while
|
||
611 | 10626 | caballero | |
612 | |||
613 | 5918 | azabala | IGeometry newGeometry = FConverter.jts_to_igeometry(union2(geometries)); |
614 | List sumarizedValues = sumarizer.getValues();
|
||
615 | IFeature dissolvedFeature = null;
|
||
616 | if(sumarizedValues != null || sumarizedValues.size() != 0){ |
||
617 | dissolvedFeature = dissolveCriteria. |
||
618 | getFeatureBuilder(). |
||
619 | 10626 | caballero | createFeature(newGeometry, |
620 | sumarizedValues, |
||
621 | fid, |
||
622 | 5918 | azabala | index1); |
623 | }else{
|
||
624 | dissolvedFeature = dissolveCriteria. |
||
625 | getFeatureBuilder(). |
||
626 | createFeature(newGeometry, |
||
627 | 10626 | caballero | index1, |
628 | 5918 | azabala | fid); |
629 | } |
||
630 | fid++; |
||
631 | featureProcessor.processFeature(dissolvedFeature); |
||
632 | dissolveCriteria.clear(); |
||
633 | } |
||
634 | |||
635 | private void dumpStack(Stack stack) { |
||
636 | Enumeration e = stack.elements();
|
||
637 | System.out.println("#####Elementos por procesar"); |
||
638 | while(e.hasMoreElements()){
|
||
639 | System.out.println("#######- "+((StackEntry)e.nextElement()).index); |
||
640 | } |
||
641 | } |
||
642 | |||
643 | /**
|
||
644 | * Returns the union of all geometries of the list
|
||
645 | 10626 | caballero | *
|
646 | 5918 | azabala | * @param geometries
|
647 | * @return
|
||
648 | */
|
||
649 | 12951 | azabala | /*
|
650 | 10626 | caballero | protected Geometry union(List geometries) {
|
651 | 5918 | azabala | Geometry union = null;
|
652 | 12951 | azabala | // GeometryFactory fact = ((Geometry)geometries.
|
653 | // get(0)).getFactory();
|
||
654 | 5918 | azabala | Iterator geomIt = geometries.iterator();
|
655 | while(geomIt.hasNext()){
|
||
656 | Geometry g = (Geometry) geomIt.next();
|
||
657 | if(union == null)
|
||
658 | union = g;
|
||
659 | else{
|
||
660 | Geometry[] geomArray = {union, g};
|
||
661 | 12951 | azabala | // GeometryCollection gCol =
|
662 | // fact.
|
||
663 | // createGeometryCollection(geomArray);
|
||
664 | // union = gCol.buffer(0d);
|
||
665 | union = JTSFacade.union(geomArray);
|
||
666 | 10626 | caballero | }
|
667 | 5918 | azabala | }
|
668 | return union;
|
||
669 | }
|
||
670 | 12951 | azabala | */
|
671 | 10626 | caballero | |
672 | 12951 | azabala | /*
|
673 | 5918 | azabala | protected Geometry union3(List geometries) {
|
674 | 10626 | caballero | long t0 = System.currentTimeMillis();
|
675 | 12951 | azabala | Geometry union = null;
|
676 | Iterator geomIt = geometries.iterator();
|
||
677 | while(geomIt.hasNext()){
|
||
678 | Geometry g = (Geometry) geomIt.next();
|
||
679 | if(union == null)
|
||
680 | union = g;
|
||
681 | else{
|
||
682 | // union = union.union(g);
|
||
683 | union = JTSFacade.union(union, g);
|
||
684 | }
|
||
685 | }
|
||
686 | 5918 | azabala | long t1 = System.currentTimeMillis();
|
687 | System.out.println((t1-t0)+ " en procesar union 3");
|
||
688 | 12951 | azabala | return union;
|
689 | }
|
||
690 | */
|
||
691 | 10626 | caballero | |
692 | protected Geometry union2(List geometries){ |
||
693 | 5918 | azabala | Geometry union = null;
|
694 | Geometry[] geom = new Geometry[geometries.size()]; |
||
695 | geometries.toArray(geom); |
||
696 | 12951 | azabala | union = JTSFacade.union(geom, geometryType); |
697 | 5918 | azabala | return union;
|
698 | 10626 | caballero | |
699 | 5918 | azabala | } |
700 | } |