Statistics
| Revision:

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
}