Statistics
| Revision:

svn-gvsig-desktop / tags / v1_1_Build_1003 / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / buffer / fmap / BufferGeoprocess.java @ 12271

History | View | Annotate | Download (20 KB)

1
/*
2
 * Created on 01-feb-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: BufferGeoprocess.java 6496 2006-07-21 11:04:50Z azabala $
47
 * $Log$
48
 * Revision 1.3  2006-07-21 11:04:50  azabala
49
 * Unified createTask and process() methods
50
 *
51
 * Revision 1.2  2006/06/29 07:33:57  fjp
52
 * Cambios ISchemaManager y IFieldManager por terminar
53
 *
54
 * Revision 1.1  2006/06/20 18:20:45  azabala
55
 * first version in cvs
56
 *
57
 * Revision 1.2  2006/06/02 18:20:58  azabala
58
 * cuando el buffer es con dissolve se crea indice espacial para optimizar
59
 *
60
 * Revision 1.1  2006/05/24 21:14:41  azabala
61
 * primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
62
 *
63
 * Revision 1.14  2006/05/01 19:18:09  azabala
64
 * revisi?n general del buffer (a?adidos anillos concentricos, buffers interiores y exteriores, etc)
65
 *
66
 * Revision 1.13  2006/03/23 21:02:58  azabala
67
 * *** empty log message ***
68
 *
69
 * Revision 1.12  2006/03/17 19:52:31  azabala
70
 * *** empty log message ***
71
 *
72
 * Revision 1.11  2006/03/14 19:35:13  azabala
73
 * *** empty log message ***
74
 *
75
 * Revision 1.10  2006/03/14 18:32:46  fjp
76
 * Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
77
 *
78
 * Revision 1.9  2006/03/07 21:01:33  azabala
79
 * *** empty log message ***
80
 *
81
 * Revision 1.8  2006/03/06 19:48:39  azabala
82
 * *** empty log message ***
83
 *
84
 * Revision 1.7  2006/03/05 19:56:40  azabala
85
 * *** empty log message ***
86
 *
87
 * Revision 1.6  2006/02/17 16:04:50  azabala
88
 * *** empty log message ***
89
 *
90
 * Revision 1.5  2006/02/13 21:13:49  azabala
91
 * *** empty log message ***
92
 *
93
 * Revision 1.4  2006/02/13 18:38:03  azabala
94
 * *** empty log message ***
95
 *
96
 * Revision 1.3  2006/02/13 17:52:45  azabala
97
 * *** empty log message ***
98
 *
99
 * Revision 1.2  2006/02/12 21:02:44  azabala
100
 * *** empty log message ***
101
 *
102
 * Revision 1.1  2006/02/02 19:47:12  azabala
103
 * many refactorings
104
 *
105
 * Revision 1.1  2006/02/01 19:42:04  azabala
106
 * First version in CVS
107
 *
108
 *
109
 */
110
package com.iver.cit.gvsig.geoprocess.impl.buffer.fmap;
111

    
112
import java.io.File;
113
import java.io.IOException;
114
import java.util.Map;
115

    
116
import org.cresques.cts.IProjection;
117

    
118
import com.iver.andami.PluginServices;
119
import com.iver.cit.gvsig.fmap.DriverException;
120
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
121
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
122
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
123
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
124
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
125
import com.iver.cit.gvsig.fmap.drivers.shp.IndexedShpDriver;
126
import com.iver.cit.gvsig.fmap.edition.EditionException;
127
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
128
import com.iver.cit.gvsig.fmap.layers.FBitSet;
129
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
130
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
131
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
132
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
133
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
134
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess;
135
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
136
import com.iver.cit.gvsig.geoprocess.core.fmap.GeometryPersisterProcessor;
137
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
138
import com.iver.cit.gvsig.geoprocess.core.fmap.IOneLayerGeoprocess;
139
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
140
import com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap.AdjacencyDissolveVisitor;
141
import com.iver.cit.gvsig.geoprocess.impl.dissolve.fmap.DissolveVisitor;
142
import com.iver.utiles.swing.threads.CancellableMonitorable;
143
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable;
144
import com.iver.utiles.swing.threads.IMonitorableTask;
145

    
146
/**
147
 * Geoprocess that computes a buffer area around each feature's geometry of the
148
 * input layer. <br>
149
 * All the points interior to this buffer area has to be at a distance inferior
150
 * to "buffer distance" to the original geometry. This buffer distance could be
151
 * constant, or it could be a function of the value of a feature attribute.<br>
152
 * 
153
 * @author azabala
154
 * 
155
 */
156
public class BufferGeoprocess extends AbstractGeoprocess implements
157
                IOneLayerGeoprocess {
158

    
159
        /**
160
         * flag that represents buffer computing with one only buffer distance.
161
         */
162
        public static final byte CONSTANT_DISTANCE_STRATEGY = 0;
163

    
164
        /**
165
         * buffer computing with variable buffer distance in function of feature
166
         * attribute value
167
         */
168
        public static final byte ATTRIBUTE_DISTANCE_STRATEGY = 1;
169

    
170
        
171
        /**
172
         * Schema of the result layer
173
         */
174
        private ILayerDefinition resultLayerDefinition;
175

    
176
        /**
177
         * the geoprocess will operate only with selected elements of layer, or with
178
         * all elements.<br>
179
         * By default, it work with all elements.
180
         */
181
        private boolean bufferOnlySelection = false;
182

    
183
        /**
184
         * this flag makes the process to dissolve or not geometries of the result
185
         * layer, to avoid intersections in a polygon layer. By default, is true.<br>
186
         */
187
        private boolean dissolveBuffers = false;
188
        
189
        /**
190
         * Iterates over input layer geometries to compute buffered geometries by
191
         * using a distance buffer function.
192
         */
193
        private BufferVisitor bufferVisitor;
194

    
195
        /**
196
         * Constructor
197
         * 
198
         * @param bufferLayer
199
         *            layer to buffer
200
         */
201
        public BufferGeoprocess(FLyrVect bufferLayer) {
202
                setFirstOperand(bufferLayer);
203
        }
204

    
205
        /**
206
         * Sets layer to buffer
207
         */
208
        public void setFirstOperand(FLyrVect bufferLayer) {
209
                this.firstLayer = bufferLayer;
210
        }
211

    
212
        /**
213
         * Sets user entry params to this geoprocess. This params represents user
214
         * preferences (FLayer are not optional params)
215
         */
216
        public void setParameters(Map params) throws GeoprocessException {
217
                Boolean onlySelection = (Boolean) params.get("layer_selection");
218
                if (onlySelection != null)
219
                        bufferOnlySelection = onlySelection.booleanValue();
220

    
221
                Boolean dissolve = (Boolean) params.get("dissolve_buffers");
222
                if (dissolve != null)
223
                        dissolveBuffers = dissolve.booleanValue();
224

    
225
                Byte strategy_flat = (Byte) params.get("strategy_flag");
226
                if (strategy_flat != null
227
                                && strategy_flat.byteValue() == ATTRIBUTE_DISTANCE_STRATEGY) {
228
                        // must check attribute name not null
229
                        String attributeName = (String) params.get("attr_name");
230
                        if (attributeName != null) {
231
                                bufferVisitor = new AttributeBufferVisitor(attributeName);
232
                        } else {
233
                                throw new GeoprocessException(
234
                                                "Buffer por atributo sin nombre de atributo");
235
                        }
236
                } else {
237
                        // default, constant strategy
238
                        // must check distance not null
239
                        Double dist = (Double) params.get("buffer_distance");
240
                        if (dist != null) {
241
                                double distance = dist.doubleValue();
242
                                bufferVisitor = new ConstantDistanceBufferVisitor(distance);
243
                        } else {
244
                                throw new GeoprocessException(
245
                                                "Buffer por dist constante sin distancia");
246
                        }
247
                }// else
248
                
249
                Byte capflag = (Byte) params.get("cap");
250
                if(capflag != null){
251
                        bufferVisitor.setTypeOfCap(capflag.byteValue());
252
                }
253
                
254
                Byte typePolFlag = (Byte) params.get("typePolBuffer");
255
                if(typePolFlag != null){
256
                        bufferVisitor.setTypeOfBuffer(typePolFlag.byteValue());
257
                }
258
                
259
                Integer numRingsFlag = (Integer) params.get("numRings");
260
                if(numRingsFlag != null){
261
                        bufferVisitor.setNumberOfRadialBuffers(numRingsFlag.intValue());
262
                }
263
        }
264
        
265

    
266
        /**
267
         * Checks preconditions to this geoprocess (input layer mustnt be null), etc
268
         */
269
        public void checkPreconditions() throws GeoprocessException {
270
                if (firstLayer == null)
271
                        throw new GeoprocessException("Buffer con capa de entrada a null");
272
                if (this.writer == null || this.schemaManager == null) {
273
                        throw new GeoprocessException(
274
                                        "Operacion de buffer sin especificar capa de resultados");
275
                }
276
        }
277

    
278
        /**
279
         * Computes buffer geoprocess, and saves results in solution layer.
280
         * 
281
         */
282
        public void process() throws GeoprocessException {
283
                try {
284
                        createTask().run();
285
                } catch (Exception e) {
286
                        throw new GeoprocessException("Error durante la ejecuci?n del buffer", e);
287
                }
288
        }
289

    
290
        /**
291
         * Creates a temp layer with the file referenced by writer.
292
         * It is useful when you want to dissolve buffers, to avoid working
293
         * with intermediate results in memory.
294
         * @return
295
         * @throws IOException
296
         * @throws DriverException
297
         */
298
        public FLyrVect createTempLayer() throws IOException, DriverException {
299
                FLyrVect solution = null;
300
                String fileName = ((ShpWriter) writer).getShpPath();
301
                File file = new File(fileName);
302
                IProjection proj = firstLayer.getProjection();
303
                IndexedShpDriver driver = new IndexedShpDriver();
304
                driver.open(file);
305
                driver.initialize();
306
                solution = (FLyrVect) LayerFactory.createLayer(fileName, driver, file,
307
                                proj);
308
                return solution;
309

    
310
        }
311

    
312
        private void computeAndDissolveBuffer(Strategy strategy,
313
                        CancellableMonitorable cancel) throws EditionException,
314
                        DriverException, VisitException, IOException {
315

    
316
                ShpWriter mainWriter = (ShpWriter) writer;
317
                writer = new ShpWriter();
318
                String temp = System.getProperty("java.io.tmpdir") + "/buffer"
319
                                + System.currentTimeMillis() + ".shp";
320
                File newFile = new File(temp);
321
                ((ShpWriter) writer).setFile(newFile);
322
                ((ShpWriter) writer)
323
                                .initialize((LayerDefinition) resultLayerDefinition);
324
                ((SHPLayerDefinition) resultLayerDefinition).setFile(newFile);
325
                schemaManager.createSchema(resultLayerDefinition);
326
                bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
327
                                resultLayerDefinition, schemaManager, writer));
328
                
329
                computeOnlyBuffers(strategy, cancel);
330
                FLyrVect tempLayer = createTempLayer();
331
                
332
                writer = mainWriter;
333
                FeaturePersisterProcessor2 processor = new FeaturePersisterProcessor2(
334
                                writer);
335
                AdjacencyDissolveVisitor dissolveVisitor = 
336
                        new AdjacencyDissolveVisitor(null, processor);
337
                Strategy secondPassStrategy = StrategyManager.getStrategy(tempLayer);
338
                dissolveVisitor.setStrategy(secondPassStrategy);
339
long t0 = System.currentTimeMillis();                
340
                secondPassStrategy.process(dissolveVisitor, cancel);
341
long t1 = System.currentTimeMillis();
342
System.out.println((t1-t0)+" en dissolver los buffers");
343
        }
344

    
345
        /**
346
         * Computes buffers of input layer, and saves them with the
347
         * actual writer.
348
         * @param strategy
349
         * @param cancel
350
         * @throws EditionException
351
         * @throws DriverException
352
         * @throws VisitException
353
         */
354
        private void computeOnlyBuffers(Strategy strategy,
355
                        CancellableMonitorable cancel) throws EditionException,
356
                        DriverException, VisitException {
357

    
358
                bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
359
                                this.resultLayerDefinition, this.schemaManager, this.writer));
360

    
361
                if (bufferOnlySelection) {
362
                        strategy.process(bufferVisitor, firstLayer.getRecordset()
363
                                        .getSelection(), cancel);
364
                } else {
365
                        strategy.process(bufferVisitor, cancel);
366
                }
367
        }
368

    
369
        /**
370
         * Creates a LayerDefinition in function of: 
371
         * a) input layer 
372
         * b) user selections 
373
         * c) buffer geoprocess itselt operation
374
         * 
375
         * Users of this geoprocess may construct a Writer from this LayerDefinition
376
         * (for example, to save to shp ShpWriter needs a File and a LayerDefinition
377
         * -to create this file with the proper schema-)
378
         * 
379
         * FIXME
380
         * We cant call this method before setParams(Map params). Launch a exception
381
         * 
382
         * ILayerDefinition wont be the same for dissolved buffers layers
383
         * 
384
         */
385
        public ILayerDefinition createLayerDefinition() {
386
                // In a buffer geoprocess we only well have a geometry
387
                // and a FID
388
                if (resultLayerDefinition == null) {
389
//                        if(dissolveBuffers){
390
//                                resultLayerDefinition = createDissolvedBuffersDefinition();
391
//                        }else{
392
                                if(bufferVisitor.getTypeOfBuffer() == BufferVisitor.BUFFER_INSIDE_OUTSIDE_POLY){
393
                                        resultLayerDefinition = createPositiveAndNegativeBufferDefinition();
394
                                }else{
395
                                        resultLayerDefinition = createPositiveOrNegativeBufferDefinition();
396
                                }
397
//                        }
398
                }
399
                return resultLayerDefinition;
400
        }
401
        
402
        /**
403
         * Auxilar method to create a layer definition for buffer's process which
404
         * needs to create only internal or external buffers.
405
         * @return
406
         */
407
        protected ILayerDefinition createPositiveOrNegativeBufferDefinition(){
408
                ILayerDefinition resultLayerDefinition = new SHPLayerDefinition();
409
                resultLayerDefinition.setShapeType(XTypes.POLYGON);
410
                FieldDescription[] fields = new FieldDescription[2];
411
                fields[0] = new FieldDescription();
412
                fields[0].setFieldLength(10);
413
                fields[0].setFieldName("FID");
414
                fields[0].setFieldType(XTypes.BIGINT);
415
                fields[1] = new FieldDescription();
416
                fields[1].setFieldLength(10);
417
                fields[1].setFieldDecimalCount(4);
418
                fields[1].setFieldName("DIST");
419
                fields[1].setFieldType(XTypes.DOUBLE);
420
                resultLayerDefinition.setFieldsDesc(fields);
421
                return resultLayerDefinition;
422
        }
423
        
424
        
425
        /**
426
         * Auxilar method to create a layer definition for buffer's process which
427
         * needs to create internal and external buffers.
428
         * @return
429
         */
430
        protected ILayerDefinition createPositiveAndNegativeBufferDefinition(){
431
                ILayerDefinition resultLayerDefinition = new SHPLayerDefinition();
432
                resultLayerDefinition.setShapeType(XTypes.POLYGON);
433
                FieldDescription[] fields = new FieldDescription[3];
434
                fields[0] = new FieldDescription();
435
                fields[0].setFieldLength(10);
436
                fields[0].setFieldName("FID");
437
                fields[0].setFieldType(XTypes.BIGINT);
438
                fields[1] = new FieldDescription();
439
                fields[1].setFieldLength(10);
440
                fields[1].setFieldDecimalCount(4);
441
                fields[1].setFieldName("FROM");
442
                fields[1].setFieldType(XTypes.DOUBLE);
443
                fields[2] = new FieldDescription();
444
                fields[2].setFieldLength(10);
445
                fields[2].setFieldDecimalCount(4);
446
                fields[2].setFieldName("TO");
447
                fields[2].setFieldType(XTypes.DOUBLE);
448
                
449
                resultLayerDefinition.setFieldsDesc(fields);
450
                return resultLayerDefinition;
451
        }
452

    
453
        /**
454
         * Creates a CancelableMonitorable instance to monitor and cancels
455
         * ITask's buffer creation.
456
         * @return
457
         */
458
        private DefaultCancellableMonitorable createCancelMonitor() {
459
                DefaultCancellableMonitorable monitor = new DefaultCancellableMonitorable();
460
                monitor.setInitialStep(0);
461
                if (this.bufferOnlySelection) {
462
                        FBitSet selection = null;
463
                        try {
464
                                selection = firstLayer.getRecordset().getSelection();
465
                        } catch (DriverException e) {
466
                                // TODO Auto-generated catch block
467
                                e.printStackTrace();
468
                        }
469
                        int numSelected = selection.cardinality();
470
                        monitor.setFinalStep(numSelected);
471
                } else {
472
                        try {
473
                                monitor.setFinalStep(firstLayer.getSource().getShapeCount());
474
                        } catch (DriverIOException e) {
475
                                e.printStackTrace();
476
                        }
477
                }
478
                if (!dissolveBuffers) {
479
                        // if we dont look for adjacents, is a determinated
480
                        // task (we know how many steps we are going to do
481
                        monitor.setDeterminatedProcess(true);
482

    
483
                } else {
484
                        monitor.setDeterminatedProcess(false);
485
                }// if dissolvebuffer
486
                return monitor;
487
        }
488

    
489
        public IMonitorableTask createTask() {
490
                /*
491
                 * Allows to monitor and cancel the task
492
                 */
493
                final CancellableMonitorable cancelMonitor = createCancelMonitor();
494
                /*
495
                 * Main Message for reporting buffer geoprocess
496
                 */
497
                final String message = PluginServices.getText(this, "Mensaje_buffer");
498
                /*
499
                 * Message for report individual step of buffer computation
500
                 */
501
                final String note = PluginServices.getText(this,
502
                                "Mensaje_procesando_buffer");
503
                /*
504
                 * Message for report individual step of dissolving of buffers
505
                 */
506
                final String note2 = PluginServices.getText(this,
507
                "Mensaje_procesando_buffer2");
508
                /*
509
                 * Concatenation string
510
                 */
511
                final String of = PluginServices.getText(this, "De");
512
                
513
                return new IMonitorableTask() {
514
                        private boolean finished = false;
515
                        String currentNote = note;
516

    
517
                        public int getInitialStep() {
518
                                return cancelMonitor.getInitialStep();
519
                        }
520

    
521
                        public int getFinishStep() {
522
                                return cancelMonitor.getFinalStep();
523
                        }
524

    
525
                        public int getCurrentStep() {
526
                                return cancelMonitor.getCurrentStep();
527
                        }
528

    
529
                        public String getStatusMessage() {
530
                                return message;
531
                        }
532

    
533
                        public String getNote() {
534
                                return currentNote + ": " + getCurrentStep() + " " + of + " "
535
                                                + getFinishStep();
536
                        }
537

    
538
                        public void cancel() {
539
                                ((DefaultCancellableMonitorable) cancelMonitor)
540
                                                .setCanceled(true);
541
                                BufferGeoprocess.this.cancel();
542
                        }
543

    
544
                        public void run() {
545

    
546
                                Strategy strategy = StrategyManager.getStrategy(firstLayer);
547
                                resultLayerDefinition = createLayerDefinition();
548
                                try {
549
                                        if (dissolveBuffers) {
550
                                                //computeAndDissolveBuffer(strategy, cancelMonitor);
551
                                                ShpWriter mainWriter = (ShpWriter) writer;
552
                                                writer = new ShpWriter();
553
                                                String temp = System.getProperty("java.io.tmpdir") + 
554
                                                                "/buffer" + 
555
                                                                System.currentTimeMillis() +
556
                                                                ".shp";
557
                                                File newFile = new File(temp);
558
                                                ((ShpWriter) writer).setFile(newFile);
559
                                                ((ShpWriter) writer).initialize(
560
                                                                (LayerDefinition) resultLayerDefinition);
561
                                                ((SHPLayerDefinition) resultLayerDefinition).setFile(newFile);
562
                                                schemaManager.createSchema(resultLayerDefinition);
563
                                                bufferVisitor.setBufferProcessor(new GeometryPersisterProcessor(
564
                                                                resultLayerDefinition, schemaManager, writer));
565
                                                computeOnlyBuffers(strategy, cancelMonitor);
566
                                                //dissolving buffers
567
                                                currentNote = note2;
568
                                                cancelMonitor.setCurrentStep(0);
569
                                                FLyrVect tempLayer = createTempLayer();
570
                                                tempLayer.createSpatialIndex();
571
                                                cancelMonitor.setFinalStep(tempLayer.getSource().getShapeCount());
572
                                                writer = mainWriter;
573
                                                FeaturePersisterProcessor2 processor = new FeaturePersisterProcessor2(
574
                                                                writer);
575
//                                                AdjacencyDissolveVisitor dissolveVisitor = 
576
//                                                        new AdjacencyDissolveVisitor(null, processor);
577
                                                DissolveVisitor dissolveVisitor =
578
                                                        createDissolveVisitor(processor);
579
                                                Strategy secondPassStrategy = StrategyManager.getStrategy(tempLayer);
580
                                                dissolveVisitor.setStrategy(secondPassStrategy);
581
                                long t0 = System.currentTimeMillis();                
582
                                                secondPassStrategy.process(dissolveVisitor, cancelMonitor);
583
                                long t1 = System.currentTimeMillis();
584
                                System.out.println((t1-t0)+" en dissolver los buffers");
585
                                        } else {
586
                                                computeOnlyBuffers(strategy, cancelMonitor);
587
                                        }
588
                                        finished = true;
589
                                } catch (Exception e) {
590
                                        e.printStackTrace();
591
                                        finished = true;
592
                                } 
593
                        }
594

    
595
                        /**
596
                         * Creates a DissolveVisitor to dissolve computed buffers.
597
                         * If we only computed a ring buffer, dissolve
598
                         * criteria will be adjacency.
599
                         * If we computed many buffers, dissolve criteria will be
600
                         * adjacency and alphanumeric (value of FROM-TO or DISTANCE fields of the
601
                         * buffer geometry) 
602
                         * @return
603
                         */
604
                        private DissolveVisitor createDissolveVisitor(FeaturePersisterProcessor2 processor) {
605
                                //int numBuffers = bufferVisitor.getNumberOfRadialBuffers();
606
                                //if(numBuffers == 1){
607
                                        return new AdjacencyDissolveVisitor(null,processor);
608
                                //}
609
                                /*DOCUMENTAR ESTE CASO
610
                                else{
611
                                        //Esto no funciona bien. Para dissolver buffers
612
                                        //con varios rings, da errores topol?gicos.
613
                                        
614
                                        //La ?nica soluci?n es calcular 1? la uni?n, luego
615
                                        //y luego los multirings
616
                                        
617
                                        if(bufferVisitor.getTypeOfBuffer() == BufferVisitor.BUFFER_INSIDE_OUTSIDE_POLY){
618
                                                return new DissolveVisitor("FROM", processor);
619
                                        }else{
620
                                                return new DissolveVisitor("DIST", processor);
621
                                        }
622
                                }
623
                                */
624
                        }
625

    
626
                        public boolean isDefined() {
627
                                return cancelMonitor.isDeterminatedProcess();
628
                        }
629

    
630
                        public boolean isCanceled() {
631
                                return cancelMonitor.isCanceled();
632
                        }
633

    
634
                        public boolean isFinished() {
635
                                return finished;
636
                        }
637
                };
638
        }
639
}