Statistics
| Revision:

root / trunk / extensions / extGeoProcessing / src / com / iver / gvsig / geoprocessing / impl / difference / DifferenceGeoprocess.java @ 4447

History | View | Annotate | Download (11.8 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 4447 2006-03-15 18:35:56Z azabala $
47
 * $Log$
48
 * Revision 1.6  2006-03-15 18:31:50  azabala
49
 * *** empty log message ***
50
 *
51
 * Revision 1.5  2006/03/14 18:32:46  fjp
52
 * Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
53
 *
54
 * Revision 1.4  2006/03/07 21:01:33  azabala
55
 * *** empty log message ***
56
 *
57
 * Revision 1.3  2006/03/06 19:48:39  azabala
58
 * *** empty log message ***
59
 *
60
 * Revision 1.2  2006/03/05 19:57:58  azabala
61
 * *** empty log message ***
62
 *
63
 * Revision 1.1  2006/02/26 20:53:13  azabala
64
 * *** empty log message ***
65
 *
66
 *
67
 */
68
package com.iver.gvsig.geoprocessing.impl.difference;
69

    
70
import java.util.Map;
71

    
72
import com.hardcode.gdbms.engine.data.driver.DriverException;
73
import com.iver.cit.gvsig.fmap.core.IFeature;
74
import com.iver.cit.gvsig.fmap.core.IGeometry;
75
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
76
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
77
import com.iver.cit.gvsig.fmap.edition.EditionException;
78
import com.iver.cit.gvsig.fmap.layers.FBitSet;
79
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
80
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
81
import com.iver.cit.gvsig.fmap.operations.DefaultCancellableMonitorable;
82
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
83
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
84
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
85
import com.iver.gvsig.geoprocessing.impl.AbstractGeoprocess;
86
import com.iver.gvsig.geoprocessing.impl.jtsprocessors.FeaturePersisterProcessor2;
87
import com.iver.gvsig.geoprocessing.model.GeoprocessException;
88
import com.iver.gvsig.geoprocessing.model.IOverlayGeoprocess;
89
import com.iver.gvsig.geoprocessing.schemabuilder.DefinitionUtils;
90
import com.iver.gvsig.geoprocessing.schemabuilder.XTypes;
91
import com.iver.utiles.swing.threads.IMonitorableTask;
92

    
93
/**
94
 * This geoprocess computes diference geometries of two overlay polygon layers.
95
 * Difference of two geometries is the set of point of one geometry that the
96
 * other geometry doesnt have.
97
 * By analogy, this geoprocess computes difference geometries between vectorial
98
 * layers.
99
 * 
100
 * @author azabala
101
 * 
102
 */
103
public class DifferenceGeoprocess extends AbstractGeoprocess
104
                                        implements IOverlayGeoprocess {
105

    
106
        /**
107
         * overlay layer
108
         */
109
        private FLyrVect overlayLayer;
110

    
111
        /**
112
         * Schema of the result layer
113
         */
114
        private ILayerDefinition resultLayerDefinition;
115

    
116
        /**
117
         * flag to only clip selection of input layer
118
         */
119
        private boolean onlyFirstLayerSelection = false;
120

    
121
        /**
122
         * flag to only clip with selection of clipping layer
123
         */
124
        private boolean onlyClipLayerSelection = false;
125

    
126
        public DifferenceGeoprocess(FLyrVect inputLayer) {
127
                setFirstOperand(inputLayer);
128
        }
129

    
130
        public void setSecondOperand(FLyrVect overlayLayer) {
131
                this.overlayLayer = overlayLayer;
132

    
133
        }
134

    
135
        public void setFirstOperand(FLyrVect firstLayer) {
136
                this.firstLayer = firstLayer;
137
        }
138

    
139
        public void setParameters(Map params) throws GeoprocessException {
140
                Boolean firstLayerSelection = (Boolean) params
141
                                .get("firstlayerselection");
142
                if (firstLayerSelection != null)
143
                        this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
144

    
145
                Boolean secondLayerSelection = (Boolean) params
146
                                .get("secondlayerselection");
147
                if (secondLayerSelection != null)
148
                        this.onlyClipLayerSelection = secondLayerSelection.booleanValue();
149

    
150
        }
151

    
152
        public void checkPreconditions() throws GeoprocessException {
153
                if (firstLayer == null)
154
                        throw new GeoprocessException(
155
                                        "Interseccion: capa de entrada a null");
156
                if (overlayLayer == null)
157
                        throw new GeoprocessException("Interseccion: capa de union a null");
158
                if (this.writer == null || this.schemaManager == null) {
159
                        throw new GeoprocessException(
160
                                        "Operacion de interseccion sin especificar capa de resultados");
161
                }
162
                try {
163
                        if (firstLayer.getShapeType() != XTypes.POLYGON) {
164
                                throw new GeoprocessException(
165
                                                "Primera capa de interseccion no es de pol?gonos");
166
                        }
167
                        if (overlayLayer.getShapeType() != XTypes.POLYGON) {
168
                                throw new GeoprocessException(
169
                                                "Segunda capa de interseccion no es de pol?gonos");
170
                        }
171
                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
172
                        throw new GeoprocessException(
173
                                        "Error al tratar de chequear si las capas a intersectar son de pol?gonos");
174
                }
175

    
176
        }
177

    
178
        
179
        //FIXME La unica diferencia entre este geoproceso y el intersection
180
        //es que usa visitors distintos 
181
        //REDISE?AR TODOS LOS OVERLAYGEOPROCESS
182
        public void process() throws GeoprocessException {
183

    
184
                try {
185
                        //FIXME Sacar esto de aqu? y ponerlo fuera. Marcaremos como precondicion
186
                        //que el esquema del geoproceso haya sido creado
187
                        // Prepare the result
188
                        this.schemaManager.createOrAlterSchema(createLayerDefinition());
189
                        writer.preProcess();
190
                        Strategy strategy = 
191
                                StrategyManager.getStrategy(firstLayer);
192
                        FeaturePersisterProcessor2 featureProcessor = new FeaturePersisterProcessor2(
193
                                        writer);
194
                        Strategy overlayStrategy = 
195
                                StrategyManager.getStrategy(overlayLayer);
196
                        DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
197
                                        featureProcessor, overlayStrategy, onlyClipLayerSelection);
198
                        if (this.onlyFirstLayerSelection) {
199
                                strategy.process(visitor, this.firstLayer.getRecordset()
200
                                                .getSelection());
201
                        } else {
202
                                strategy.process(visitor);
203
                        }
204

    
205
                } catch (EditionException e) {
206
                        throw new GeoprocessException(
207
                                        "Error al crear el esquema/fichero de la nueva capa");
208
                } catch (DriverException e) {
209
                        throw new GeoprocessException(
210
                                        "Error de driver al calcular el geoproceso interseccion");
211
                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
212
                        throw new GeoprocessException(
213
                                        "Error de driver al calcular el geoproceso interseccion");
214
                } catch (VisitException e) {
215
                        throw new GeoprocessException(
216
                                        "Error al procesar el feature de una capa durante el geoproceso interseccion");
217
                }
218
        }
219

    
220
        public void cancel() {
221
                try {
222
                        schemaManager.drop();
223
                } catch (EditionException e) {
224
                        // FIXME (debe lanzar una excepcion cancel)
225
                        e.printStackTrace();
226
                }
227
        }
228

    
229
        public ILayerDefinition createLayerDefinition() {
230
                if (resultLayerDefinition == null) {
231
                        try {
232
                                resultLayerDefinition = DefinitionUtils.mergeLayerDefinitions(
233
                                                firstLayer, overlayLayer);
234
                        } catch (Exception e) {
235
                                // TODO Quizas createLayerDefinition deberia lanzar
236
                                // una excepcion
237
                                e.printStackTrace();
238
                        }
239
                }
240
                return resultLayerDefinition;
241
        }
242

    
243
        public FBitSet getOverlays(IGeometry firstLayerGeometry, int index) {
244
                // TODO Auto-generated method stub
245
                return null;
246
        }
247

    
248
        public IFeature[] computeIntersection(IGeometry firsLayerGeometry,
249
                        int firstLayerFeatureIndex, IGeometry secondLayerGeometry,
250
                        int secondLayerFeatureIndex) {
251
                // TODO Auto-generated method stub
252
                return null;
253
        }
254

    
255
        public IMonitorableTask createTask() {
256
                try {
257
                        return new DifferenceMonitorableTask();
258
                } catch (DriverIOException e) {
259
                        //FIXME Debe lanzar excepcion createTask ?
260
                        return null;
261
                }
262
        }
263
        
264
        /**
265
         * IMonitorableTask that allows to run diff geoprocess in background,
266
         * with cancelation requests.
267
         * 
268
         * @author azabala
269
         * 
270
         */
271
        class DifferenceMonitorableTask implements IMonitorableTask {
272
                private CancellableMonitorable cancelMonitor = null;
273

    
274
                // FIXME INTERNACIONALIZAR ESTO
275
                String DIFFERENCE_MESSAGE = "Computing differences: ";
276

    
277
                private boolean finished = false;
278

    
279
                DifferenceMonitorableTask() throws DriverIOException {
280
                        initialize();
281
                }
282
                void initialize() throws DriverIOException {
283
                        cancelMonitor = createCancelMonitor();
284
                }
285

    
286
                private CancellableMonitorable createCancelMonitor()
287
                                throws DriverIOException {
288
                        DefaultCancellableMonitorable monitor = new 
289
                                                        DefaultCancellableMonitorable();
290
                        monitor.setInitialStep(0);
291
                        //Really its undeterminated, but so we must to process all
292
                        //elements of first layer (or selection) we are going to 
293
                        //consideer determinated
294
                        monitor.setDeterminatedProcess(true);
295
                        int numSteps = 0;
296
                        if (onlyFirstLayerSelection) {
297
                                FBitSet selection = firstLayer.getRecordset().getSelection();
298
                                numSteps = selection.cardinality();
299
                        } else {
300
                                numSteps = firstLayer.getSource().getShapeCount();
301
                        }
302
                        monitor.setFinalStep(numSteps);
303
                        return monitor;
304
                }
305

    
306
                public int getInitialStep() {
307
                        return cancelMonitor.getInitialStep();
308
                }
309

    
310
                public int getFinishStep() {
311
                        return cancelMonitor.getFinalStep();
312
                }
313

    
314
                public int getCurrentStep() {
315
                        return cancelMonitor.getCurrentStep();
316
                }
317

    
318
                public String getStatusMessage() {
319
                        // FIXME Cambiar esto por un mecanismo de eventos,
320
                        // de forma que la tarea lo que tenga sea un escuchador
321
                        // que cambie el mensaje de estado segun los eventos
322
                        // de tareas que se est?n realizando
323
                        return "Difference Geoprocess...";
324
                }
325

    
326
                public String getNote() {
327
                        // FIXME Cambiar esto por un mecanismo de eventos,
328
                        // de forma que la tarea lo que tenga sea un escuchador
329
                        // que cambie el mensaje de estado segun los eventos
330
                        // de tareas que se est?n realizando
331
                        return DIFFERENCE_MESSAGE + getCurrentStep() + "of " + getFinishStep();
332
                }
333

    
334
                public void cancel() {
335
                        ((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
336
                }
337

    
338
                public void run() throws GeoprocessException {
339

    
340
                        try {
341
                                //FIXME Sacar esto de aqu? y ponerlo fuera. Marcaremos como precondicion
342
                                //que el esquema del geoproceso haya sido creado
343
                                // Prepare the result
344
                                schemaManager.createOrAlterSchema(createLayerDefinition());
345
                                writer.preProcess();
346
                                Strategy strategy = 
347
                                        StrategyManager.getStrategy(firstLayer);
348
                                FeaturePersisterProcessor2 featureProcessor =
349
                                        new FeaturePersisterProcessor2(writer);
350
                                Strategy overlayStrategy = 
351
                                        StrategyManager.getStrategy(overlayLayer);
352
                                DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
353
                                                featureProcessor, overlayStrategy, onlyClipLayerSelection);
354
                                if (onlyFirstLayerSelection) {
355
                                        strategy.process(visitor, firstLayer.getRecordset()
356
                                                        .getSelection(), cancelMonitor);
357
                                } else {
358
                                        strategy.process(visitor, cancelMonitor);
359
                                }
360

    
361
                        } catch (EditionException e) {
362
                                throw new GeoprocessException(
363
                                                "Error al crear el esquema/fichero de la nueva capa");
364
                        } catch (DriverException e) {
365
                                throw new GeoprocessException(
366
                                                "Error de driver al calcular el geoproceso interseccion");
367
                        } catch (com.iver.cit.gvsig.fmap.DriverException e) {
368
                                throw new GeoprocessException(
369
                                                "Error de driver al calcular el geoproceso interseccion");
370
                        } catch (VisitException e) {
371
                                throw new GeoprocessException(
372
                                                "Error al procesar el feature de una capa durante el geoproceso interseccion");
373
                        }finally{
374
                                finished = true;
375
                        }
376
                }
377

    
378
                public boolean isDefined() {
379
                        return cancelMonitor.isDeterminatedProcess();
380
                }
381

    
382
                public boolean isCanceled() {
383
                        return cancelMonitor.isCanceled();
384
                }
385

    
386
                public boolean isFinished() {
387
                        return finished;
388
                }
389
        }
390

    
391
}