Statistics
| Revision:

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

History | View | Annotate | Download (12 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 13874 2007-09-19 16:12:18Z jaume $
47
 * $Log$
48
 * Revision 1.6  2007-09-19 16:05:53  jaume
49
 * ReadExpansionFileException removed from this context
50
 *
51
 * Revision 1.5  2007/08/07 15:42:19  azabala
52
 * centrilizing JTS in JTSFacade
53
 *
54
 * Revision 1.4  2007/05/15 07:24:19  cesar
55
 * Add the finished method for execution from Event Dispatch Thread
56
 *
57
 * Revision 1.3  2007/03/06 16:47:58  caballero
58
 * Exceptions
59
 *
60
 * Revision 1.2  2006/06/29 07:33:57  fjp
61
 * Cambios ISchemaManager y IFieldManager por terminar
62
 *
63
 * Revision 1.1  2006/06/20 18:20:45  azabala
64
 * first version in cvs
65
 *
66
 * Revision 1.2  2006/06/08 18:24:23  azabala
67
 * modificaciones para admitir capas de shapeType MULTI
68
 *
69
 * Revision 1.1  2006/05/24 21:11:38  azabala
70
 * primera version en cvs despues de refactoring orientado a crear un framework extensible de geoprocessing
71
 *
72
 * Revision 1.10  2006/05/01 19:15:37  azabala
73
 * 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)
74
 *
75
 * Revision 1.9  2006/03/26 20:02:25  azabala
76
 * *** empty log message ***
77
 *
78
 * Revision 1.8  2006/03/21 19:26:53  azabala
79
 * *** empty log message ***
80
 *
81
 * Revision 1.7  2006/03/17 19:53:05  azabala
82
 * *** empty log message ***
83
 *
84
 * Revision 1.6  2006/03/15 18:31:50  azabala
85
 * *** empty log message ***
86
 *
87
 * Revision 1.5  2006/03/14 18:32:46  fjp
88
 * Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
89
 *
90
 * Revision 1.4  2006/03/07 21:01:33  azabala
91
 * *** empty log message ***
92
 *
93
 * Revision 1.3  2006/03/06 19:48:39  azabala
94
 * *** empty log message ***
95
 *
96
 * Revision 1.2  2006/03/05 19:57:58  azabala
97
 * *** empty log message ***
98
 *
99
 * Revision 1.1  2006/02/26 20:53:13  azabala
100
 * *** empty log message ***
101
 *
102
 *
103
 */
104
package com.iver.cit.gvsig.geoprocess.impl.difference.fmap;
105

    
106
import java.util.Map;
107

    
108
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
109
import com.hardcode.gdbms.driver.exceptions.SchemaEditionException;
110
import com.iver.andami.PluginServices;
111
import com.iver.cit.gvsig.exceptions.expansionfile.ExpansionFileReadException;
112
import com.iver.cit.gvsig.exceptions.visitors.ProcessVisitorException;
113
import com.iver.cit.gvsig.exceptions.visitors.VisitorException;
114
import com.iver.cit.gvsig.fmap.core.FShape;
115
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
116
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
117
import com.iver.cit.gvsig.fmap.layers.FBitSet;
118
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
119
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
120
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
121
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess;
122
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils;
123
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
124
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
125
import com.iver.cit.gvsig.geoprocess.core.fmap.IOverlayGeoprocess;
126
import com.iver.utiles.swing.threads.CancellableMonitorable;
127
import com.iver.utiles.swing.threads.DefaultCancellableMonitorable;
128
import com.iver.utiles.swing.threads.IMonitorableTask;
129

    
130
/**
131
 * This geoprocess computes diference geometries of two overlay polygon layers.
132
 * Difference of two geometries is the set of point of one geometry that the
133
 * other geometry doesnt have.
134
 * By analogy, this geoprocess computes difference geometries between vectorial
135
 * layers.
136
 *
137
 * @author azabala
138
 *
139
 */
140
public class DifferenceGeoprocess extends AbstractGeoprocess
141
                                        implements IOverlayGeoprocess {
142

    
143
        /**
144
         * overlay layer
145
         */
146
        private FLyrVect overlayLayer;
147

    
148
        /**
149
         * Schema of the result layer
150
         */
151
        private ILayerDefinition resultLayerDefinition;
152

    
153
        /**
154
         * flag to only clip selection of input layer
155
         */
156
        private boolean onlyFirstLayerSelection = false;
157

    
158
        /**
159
         * flag to only clip with selection of clipping layer
160
         */
161
        private boolean onlyClipLayerSelection = false;
162

    
163
        public DifferenceGeoprocess(FLyrVect inputLayer) {
164
                setFirstOperand(inputLayer);
165
        }
166

    
167
        public void setSecondOperand(FLyrVect overlayLayer) {
168
                this.overlayLayer = overlayLayer;
169

    
170
        }
171

    
172
        public void setFirstOperand(FLyrVect firstLayer) {
173
                this.firstLayer = firstLayer;
174
        }
175

    
176
        public void setParameters(Map params) throws GeoprocessException {
177
                Boolean firstLayerSelection = (Boolean) params
178
                                .get("firstlayerselection");
179
                if (firstLayerSelection != null)
180
                        this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
181

    
182
                Boolean secondLayerSelection = (Boolean) params
183
                                .get("secondlayerselection");
184
                if (secondLayerSelection != null)
185
                        this.onlyClipLayerSelection = secondLayerSelection.booleanValue();
186

    
187
        }
188

    
189
        public void checkPreconditions() throws GeoprocessException {
190
                if (firstLayer == null)
191
                        throw new GeoprocessException(
192
                                        "Interseccion: capa de entrada a null");
193
                if (overlayLayer == null)
194
                        throw new GeoprocessException("Interseccion: capa de union a null");
195
                if (this.writer == null || this.schemaManager == null) {
196
                        throw new GeoprocessException(
197
                                        "Operacion de interseccion sin especificar capa de resultados");
198
                }
199
                /*AZABALA: PERMITIMOS CAPAS DE PUNTOS, LINEAS Y DE POLIGONOS
200
                try {
201
                        if (firstLayer.getShapeType() != XTypes.POLYGON
202
                                        && firstLayer.getShapeType() != XTypes.MULTI) {
203
                                throw new GeoprocessException(
204
                                                "Primera capa de interseccion no es de pol?gonos");
205
                        }
206
                        if (overlayLayer.getShapeType() != XTypes.POLYGON
207
                                        && overlayLayer.getShapeType() != XTypes.MULTI) {
208
                                throw new GeoprocessException(
209
                                                "Segunda capa de interseccion no es de pol?gonos");
210
                        }
211
                } catch (ReadDriverException e) {
212
                        throw new GeoprocessException(
213
                        "Error al tratar de chequear si las capas a intersectar son de pol?gonos");
214
                }
215
                */
216

    
217
        }
218

    
219

    
220
        //FIXME La unica diferencia entre este geoproceso y el intersection
221
        //es que usa visitors distintos
222
        //REDISE?AR TODOS LOS OVERLAYGEOPROCESS
223
        public void process() throws GeoprocessException {
224
                try {
225
                        new DifferenceMonitorableTask().run();
226
                }catch (DriverIOException e) {
227
                        throw new GeoprocessException("Error de lectura de driver durante geoproceso diferencia");
228
                }
229
        }
230

    
231
        public void cancel() {
232
                try {
233
                        schemaManager.removeSchema("");
234
                } catch (SchemaEditionException e) {
235
                        // TODO Auto-generated catch block
236
                        e.printStackTrace();
237
                }
238
        }
239

    
240
        public ILayerDefinition createLayerDefinition() {
241
                if (resultLayerDefinition == null) {
242
                        try {
243
                                resultLayerDefinition = DefinitionUtils.createLayerDefinition(firstLayer);
244
                                //All overlay geoprocesses could generate various kind of geometry types
245
                                resultLayerDefinition.setShapeType(FShape.MULTI);
246
                        } catch (Exception e) {
247
                                // TODO Quizas createLayerDefinition deberia lanzar
248
                                // una excepcion
249
                                e.printStackTrace();
250
                        }
251
                }
252
                return resultLayerDefinition;
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
                String DIFFERENCE_MESSAGE = PluginServices.getText(this, "Mensaje_difference");
274
                String DIFFERENCE_NOTE = PluginServices.getText(this, "Mensaje_procesando_diferencia");
275
                String OF = PluginServices.getText(this, "De");
276
                private boolean finished = false;
277

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

    
285
                private CancellableMonitorable createCancelMonitor() {
286
                        DefaultCancellableMonitorable monitor = new
287
                                                        DefaultCancellableMonitorable();
288
                        monitor.setInitialStep(0);
289
                        //Really its undeterminated, but so we must to process all
290
                        //elements of first layer (or selection) we are going to
291
                        //consideer determinated
292
                        monitor.setDeterminatedProcess(true);
293
                        int numSteps = 0;
294
                        if (onlyFirstLayerSelection) {
295
                                FBitSet selection = null;
296
                                try {
297
                                        selection = firstLayer.getRecordset().getSelection();
298
                                } catch (ReadDriverException e) {
299
                                        // TODO Auto-generated catch block
300
                                        e.printStackTrace();
301
                                }
302
                                numSteps = selection.cardinality();
303
                        } else {
304
                                try {
305
                                        numSteps = firstLayer.getSource().getShapeCount();
306
                                } catch (ReadDriverException e) {
307
                                        // TODO Auto-generated catch block
308
                                        e.printStackTrace();
309
                                }
310
                        }
311
                        monitor.setFinalStep(numSteps);
312
                        return monitor;
313
                }
314

    
315
                public int getInitialStep() {
316
                        return cancelMonitor.getInitialStep();
317
                }
318

    
319
                public int getFinishStep() {
320
                        return cancelMonitor.getFinalStep();
321
                }
322

    
323
                public int getCurrentStep() {
324
                        return cancelMonitor.getCurrentStep();
325
                }
326

    
327
                public String getStatusMessage() {
328
                        return DIFFERENCE_MESSAGE;
329
                }
330

    
331
                public String getNote() {
332
                        return DIFFERENCE_NOTE + " " +
333
                        getCurrentStep() + " "+
334
                        OF + " "+
335
                        getFinishStep();
336
                }
337

    
338
                public void cancel() {
339
                        ((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
340
                        DifferenceGeoprocess.this.cancel();
341
                }
342

    
343
                public void run() throws GeoprocessException {
344
                        try {
345
                                schemaManager.createSchema(createLayerDefinition());
346
                                writer.preProcess();
347
                                Strategy strategy =
348
                                        StrategyManager.getStrategy(firstLayer);
349
                                FeaturePersisterProcessor2 featureProcessor =
350
                                        new FeaturePersisterProcessor2(writer);
351
                                Strategy overlayStrategy =
352
                                        StrategyManager.getStrategy(overlayLayer);
353
                                DifferenceVisitor visitor = new DifferenceVisitor(overlayLayer,
354
                                                featureProcessor, overlayStrategy, onlyClipLayerSelection);
355
                                visitor.setLayerDefinition(resultLayerDefinition);
356
                                if (onlyFirstLayerSelection) {
357
                                        strategy.process(visitor, firstLayer.getRecordset()
358
                                                        .getSelection(), cancelMonitor);
359
                                } else {
360
                                        strategy.process(visitor, cancelMonitor);
361
                                }
362

    
363
                        } catch (ProcessVisitorException e) {
364
                                throw new GeoprocessException(
365
                                                "Error al procesar el feature de una capa durante el geoproceso interseccion");
366
                        } catch (SchemaEditionException e) {
367
                                throw new GeoprocessException(
368
                                        "Error al crear el esquema/fichero de la nueva capa");
369
                        } catch (ReadDriverException e) {
370
                                throw new GeoprocessException(
371
                                        "Error de driver al calcular el geoproceso interseccion");
372
                        } catch (VisitorException e) {
373
                                throw new GeoprocessException(
374
                                        "Error de driver al calcular el geoproceso interseccion");
375
                        } finally {
376
                                finished = true;
377
                        }
378
                }
379

    
380
                public boolean isDefined() {
381
                        return cancelMonitor.isDeterminatedProcess();
382
                }
383

    
384
                public boolean isCanceled() {
385
                        return cancelMonitor.isCanceled();
386
                }
387

    
388
                public boolean isFinished() {
389
                        return finished;
390
                }
391
                /* (non-Javadoc)
392
                 * @see com.iver.utiles.swing.threads.IMonitorableTask#finished()
393
                 */
394
                public void finished() {
395
                        // TODO Auto-generated method stub
396
                        
397
                }
398
        }
399

    
400
}