Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGeoProcessing / src / com / iver / cit / gvsig / geoprocess / impl / difference / fmap / DifferenceGeoprocess.java @ 10626

History | View | Annotate | Download (12.9 KB)

1
/*
2
 * Created on 22-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: DifferenceGeoprocess.java 10626 2007-03-06 16:55:54Z caballero $
47
 * $Log$
48
 * Revision 1.3  2007-03-06 16:47:58  caballero
49
 * Exceptions
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/08 18:24:23  azabala
58
 * modificaciones para admitir capas de shapeType MULTI
59
 *
60
 * Revision 1.1  2006/05/24 21:11:38  azabala
61
 * primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
62
 *
63
 * Revision 1.10  2006/05/01 19:15:37  azabala
64
 * la cancelacion no solo para el ITask que ejecuta el geoproceso, adem?s llama al metodo cancel() del mismo (que se supone que deber?a hacer un drop() con los resultados del geoproceso inconcluso)
65
 *
66
 * Revision 1.9  2006/03/26 20:02:25  azabala
67
 * *** empty log message ***
68
 *
69
 * Revision 1.8  2006/03/21 19:26:53  azabala
70
 * *** empty log message ***
71
 *
72
 * Revision 1.7  2006/03/17 19:53:05  azabala
73
 * *** empty log message ***
74
 *
75
 * Revision 1.6  2006/03/15 18:31:50  azabala
76
 * *** empty log message ***
77
 *
78
 * Revision 1.5  2006/03/14 18:32:46  fjp
79
 * Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
80
 *
81
 * Revision 1.4  2006/03/07 21:01:33  azabala
82
 * *** empty log message ***
83
 *
84
 * Revision 1.3  2006/03/06 19:48:39  azabala
85
 * *** empty log message ***
86
 *
87
 * Revision 1.2  2006/03/05 19:57:58  azabala
88
 * *** empty log message ***
89
 *
90
 * Revision 1.1  2006/02/26 20:53:13  azabala
91
 * *** empty log message ***
92
 *
93
 *
94
 */
95
package com.iver.cit.gvsig.geoprocess.impl.difference.fmap;
96

    
97
import java.util.Map;
98

    
99
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
100
import com.hardcode.gdbms.driver.exceptions.SchemaEditionException;
101
import com.iver.andami.PluginServices;
102
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
103
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException;
104
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
105
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
106
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
107
import com.iver.cit.gvsig.fmap.layers.FBitSet;
108
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
109
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
110
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
111
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess;
112
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils;
113
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
114
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
115
import com.iver.cit.gvsig.geoprocess.core.fmap.IOverlayGeoprocess;
116
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
117
import com.iver.utiles.swing.threads.CancellableMonitorable;
118
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable;
119
import com.iver.utiles.swing.threads.IMonitorableTask;
120

    
121
/**
122
 * This geoprocess computes diference geometries of two overlay polygon layers.
123
 * Difference of two geometries is the set of point of one geometry that the
124
 * other geometry doesnt have.
125
 * By analogy, this geoprocess computes difference geometries between vectorial
126
 * layers.
127
 *
128
 * @author azabala
129
 *
130
 */
131
public class DifferenceGeoprocess extends AbstractGeoprocess
132
                                        implements IOverlayGeoprocess {
133

    
134
        /**
135
         * overlay layer
136
         */
137
        private FLyrVect overlayLayer;
138

    
139
        /**
140
         * Schema of the result layer
141
         */
142
        private ILayerDefinition resultLayerDefinition;
143

    
144
        /**
145
         * flag to only clip selection of input layer
146
         */
147
        private boolean onlyFirstLayerSelection = false;
148

    
149
        /**
150
         * flag to only clip with selection of clipping layer
151
         */
152
        private boolean onlyClipLayerSelection = false;
153

    
154
        public DifferenceGeoprocess(FLyrVect inputLayer) {
155
                setFirstOperand(inputLayer);
156
        }
157

    
158
        public void setSecondOperand(FLyrVect overlayLayer) {
159
                this.overlayLayer = overlayLayer;
160

    
161
        }
162

    
163
        public void setFirstOperand(FLyrVect firstLayer) {
164
                this.firstLayer = firstLayer;
165
        }
166

    
167
        public void setParameters(Map params) throws GeoprocessException {
168
                Boolean firstLayerSelection = (Boolean) params
169
                                .get("firstlayerselection");
170
                if (firstLayerSelection != null)
171
                        this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
172

    
173
                Boolean secondLayerSelection = (Boolean) params
174
                                .get("secondlayerselection");
175
                if (secondLayerSelection != null)
176
                        this.onlyClipLayerSelection = secondLayerSelection.booleanValue();
177

    
178
        }
179

    
180
        public void checkPreconditions() throws GeoprocessException {
181
                if (firstLayer == null)
182
                        throw new GeoprocessException(
183
                                        "Interseccion: capa de entrada a null");
184
                if (overlayLayer == null)
185
                        throw new GeoprocessException("Interseccion: capa de union a null");
186
                if (this.writer == null || this.schemaManager == null) {
187
                        throw new GeoprocessException(
188
                                        "Operacion de interseccion sin especificar capa de resultados");
189
                }
190
                try {
191
                        if (firstLayer.getShapeType() != XTypes.POLYGON
192
                                        && firstLayer.getShapeType() != XTypes.MULTI) {
193
                                throw new GeoprocessException(
194
                                                "Primera capa de interseccion no es de pol?gonos");
195
                        }
196
                        if (overlayLayer.getShapeType() != XTypes.POLYGON
197
                                        && overlayLayer.getShapeType() != XTypes.MULTI) {
198
                                throw new GeoprocessException(
199
                                                "Segunda capa de interseccion no es de pol?gonos");
200
                        }
201
                } catch (ReadDriverException e) {
202
                        throw new GeoprocessException(
203
                        "Error al tratar de chequear si las capas a intersectar son de pol?gonos");
204
                }
205

    
206
        }
207

    
208

    
209
        //FIXME La unica diferencia entre este geoproceso y el intersection
210
        //es que usa visitors distintos
211
        //REDISE?AR TODOS LOS OVERLAYGEOPROCESS
212
        public void process() throws GeoprocessException {
213

    
214
                try {
215
                        //FIXME Sacar esto de aqu? y ponerlo fuera. Marcaremos como precondicion
216
                        //que el esquema del geoproceso haya sido creado
217
                        // Prepare the result
218
                        this.schemaManager.createSchema(createLayerDefinition());
219
                        writer.preProcess();
220
                        Strategy strategy =
221
                                StrategyManager.getStrategy(firstLayer);
222
                        FeaturePersisterProcessor2 featureProcessor = new FeaturePersisterProcessor2(
223
                                        writer);
224
                        Strategy overlayStrategy =
225
                                StrategyManager.getStrategy(overlayLayer);
226
                        DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
227
                                        featureProcessor, overlayStrategy, onlyClipLayerSelection);
228
                        visitor.setLayerDefinition(resultLayerDefinition);
229
                        if (this.onlyFirstLayerSelection) {
230
                                strategy.process(visitor, this.firstLayer.getRecordset()
231
                                                .getSelection());
232
                        } else {
233
                                strategy.process(visitor);
234
                        }
235

    
236
                } catch (ProcessVisitorException e) {
237
                        throw new GeoprocessException(
238
                                        "Error al procesar el feature de una capa durante el geoproceso interseccion");
239
                } catch (ReadDriverException e) {
240
                        throw new GeoprocessException(
241
                                "Error de driver al calcular el geoproceso interseccion");
242
                } catch (SchemaEditionException e) {
243
                        throw new GeoprocessException(
244
                                  "Error en el esquema de la nueva capa");
245
                } catch (ExpansionFileReadException e) {
246
                        throw new GeoprocessException(
247
                                "Error de driver al calcular el geoproceso interseccion");
248
                } catch (VisitorException e) {
249
                        throw new GeoprocessException(
250
                                 "Error de driver al calcular el geoproceso interseccion");
251
                }
252
        }
253

    
254
        public void cancel() {
255
                try {
256
                        schemaManager.removeSchema("");
257
                } catch (SchemaEditionException e) {
258
                        // TODO Auto-generated catch block
259
                        e.printStackTrace();
260
                }
261
        }
262

    
263
        public ILayerDefinition createLayerDefinition() {
264
                if (resultLayerDefinition == null) {
265
                        try {
266
//                                resultLayerDefinition = DefinitionUtils.mergeLayerDefinitions(
267
//                                                firstLayer, overlayLayer);
268
                                resultLayerDefinition = DefinitionUtils.createLayerDefinition(firstLayer);
269
                        } catch (Exception e) {
270
                                // TODO Quizas createLayerDefinition deberia lanzar
271
                                // una excepcion
272
                                e.printStackTrace();
273
                        }
274
                }
275
                return resultLayerDefinition;
276
        }
277

    
278
        public IMonitorableTask createTask() {
279
                try {
280
                        return new DifferenceMonitorableTask();
281
                } catch (DriverIOException e) {
282
                        //FIXME Debe lanzar excepcion createTask ?
283
                        return null;
284
                }
285
        }
286

    
287
        /**
288
         * IMonitorableTask that allows to run diff geoprocess in background,
289
         * with cancelation requests.
290
         *
291
         * @author azabala
292
         *
293
         */
294
        class DifferenceMonitorableTask implements IMonitorableTask {
295
                private CancellableMonitorable cancelMonitor = null;
296
                String DIFFERENCE_MESSAGE = PluginServices.getText(this, "Mensaje_difference");
297
                String DIFFERENCE_NOTE = PluginServices.getText(this, "Mensaje_procesando_diferencia");
298
                String OF = PluginServices.getText(this, "De");
299
                private boolean finished = false;
300

    
301
                DifferenceMonitorableTask() throws DriverIOException {
302
                        initialize();
303
                }
304
                void initialize() throws DriverIOException {
305
                        cancelMonitor = createCancelMonitor();
306
                }
307

    
308
                private CancellableMonitorable createCancelMonitor() {
309
                        DefaultCancellableMonitorable monitor = new
310
                                                        DefaultCancellableMonitorable();
311
                        monitor.setInitialStep(0);
312
                        //Really its undeterminated, but so we must to process all
313
                        //elements of first layer (or selection) we are going to
314
                        //consideer determinated
315
                        monitor.setDeterminatedProcess(true);
316
                        int numSteps = 0;
317
                        if (onlyFirstLayerSelection) {
318
                                FBitSet selection = null;
319
                                try {
320
                                        selection = firstLayer.getRecordset().getSelection();
321
                                } catch (ReadDriverException e) {
322
                                        // TODO Auto-generated catch block
323
                                        e.printStackTrace();
324
                                }
325
                                numSteps = selection.cardinality();
326
                        } else {
327
                                try {
328
                                        numSteps = firstLayer.getSource().getShapeCount();
329
                                } catch (ReadDriverException e) {
330
                                        // TODO Auto-generated catch block
331
                                        e.printStackTrace();
332
                                }
333
                        }
334
                        monitor.setFinalStep(numSteps);
335
                        return monitor;
336
                }
337

    
338
                public int getInitialStep() {
339
                        return cancelMonitor.getInitialStep();
340
                }
341

    
342
                public int getFinishStep() {
343
                        return cancelMonitor.getFinalStep();
344
                }
345

    
346
                public int getCurrentStep() {
347
                        return cancelMonitor.getCurrentStep();
348
                }
349

    
350
                public String getStatusMessage() {
351
                        return DIFFERENCE_MESSAGE;
352
                }
353

    
354
                public String getNote() {
355
                        return DIFFERENCE_NOTE + " " +
356
                        getCurrentStep() + " "+
357
                        OF + " "+
358
                        getFinishStep();
359
                }
360

    
361
                public void cancel() {
362
                        ((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
363
                        DifferenceGeoprocess.this.cancel();
364
                }
365

    
366
                public void run() throws GeoprocessException {
367
                        try {
368
                                schemaManager.createSchema(createLayerDefinition());
369
                                writer.preProcess();
370
                                Strategy strategy =
371
                                        StrategyManager.getStrategy(firstLayer);
372
                                FeaturePersisterProcessor2 featureProcessor =
373
                                        new FeaturePersisterProcessor2(writer);
374
                                Strategy overlayStrategy =
375
                                        StrategyManager.getStrategy(overlayLayer);
376
                                DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
377
                                                featureProcessor, overlayStrategy, onlyClipLayerSelection);
378
                                visitor.setLayerDefinition(resultLayerDefinition);
379
                                if (onlyFirstLayerSelection) {
380
                                        strategy.process(visitor, firstLayer.getRecordset()
381
                                                        .getSelection(), cancelMonitor);
382
                                } else {
383
                                        strategy.process(visitor, cancelMonitor);
384
                                }
385

    
386
                        } catch (ProcessVisitorException e) {
387
                                throw new GeoprocessException(
388
                                                "Error al procesar el feature de una capa durante el geoproceso interseccion");
389
                        } catch (SchemaEditionException e) {
390
                                throw new GeoprocessException(
391
                                        "Error al crear el esquema/fichero de la nueva capa");
392
                        } catch (ReadDriverException e) {
393
                                throw new GeoprocessException(
394
                                        "Error de driver al calcular el geoproceso interseccion");
395
                        } catch (ExpansionFileReadException e) {
396
                                throw new GeoprocessException(
397
                                        "Error de driver al calcular el geoproceso interseccion");
398
                        } catch (VisitorException e) {
399
                                throw new GeoprocessException(
400
                                        "Error de driver al calcular el geoproceso interseccion");
401
                        }finally{
402
                                finished = true;
403
                        }
404
                }
405

    
406
                public boolean isDefined() {
407
                        return cancelMonitor.isDeterminatedProcess();
408
                }
409

    
410
                public boolean isCanceled() {
411
                        return cancelMonitor.isCanceled();
412
                }
413

    
414
                public boolean isFinished() {
415
                        return finished;
416
                }
417
        }
418

    
419
}