Statistics
| Revision:

root / trunk / extensions / extGeoProcessing / src / com / iver / gvsig / geoprocessing / impl / clip / ClipGeoprocess.java @ 4447

History | View | Annotate | Download (11.2 KB)

1
/*
2
 * Created on 14-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
*
45
* $Id: ClipGeoprocess.java 4447 2006-03-15 18:35:56Z azabala $
46
* $Log$
47
* Revision 1.8  2006-03-15 18:30:39  azabala
48
* *** empty log message ***
49
*
50
* Revision 1.7  2006/03/14 18:32:46  fjp
51
* Cambio con LayerDefinition para que sea compatible con la definici?n de tablas tambi?n.
52
*
53
* Revision 1.6  2006/03/07 21:01:33  azabala
54
* *** empty log message ***
55
*
56
* Revision 1.5  2006/03/06 19:48:39  azabala
57
* *** empty log message ***
58
*
59
* Revision 1.4  2006/03/05 19:57:14  azabala
60
* *** empty log message ***
61
*
62
* Revision 1.3  2006/02/19 20:56:32  azabala
63
* *** empty log message ***
64
*
65
* Revision 1.2  2006/02/17 19:25:28  azabala
66
* *** empty log message ***
67
*
68
* Revision 1.1  2006/02/17 16:31:58  azabala
69
* *** empty log message ***
70
*
71
*
72
*/
73
package com.iver.gvsig.geoprocessing.impl.clip;
74

    
75
import java.util.Map;
76

    
77
import com.iver.cit.gvsig.fmap.core.IFeature;
78
import com.iver.cit.gvsig.fmap.core.IGeometry;
79
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
80
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
81
import com.iver.cit.gvsig.fmap.drivers.ITableDefinition;
82
import com.iver.cit.gvsig.fmap.edition.ISchemaManager;
83
import com.iver.cit.gvsig.fmap.edition.IWriter;
84
import com.iver.cit.gvsig.fmap.layers.FBitSet;
85
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
86
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
87
import com.iver.cit.gvsig.fmap.operations.DefaultCancellableMonitorable;
88
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
89
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
90
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
91
import com.iver.gvsig.geoprocessing.impl.AbstractGeoprocess;
92
import com.iver.gvsig.geoprocessing.impl.convexhull.ScalableUnionVisitor;
93
import com.iver.gvsig.geoprocessing.model.GeoprocessException;
94
import com.iver.gvsig.geoprocessing.model.IOverlayGeoprocess;
95
import com.iver.gvsig.geoprocessing.schemabuilder.DefinitionUtils;
96
import com.iver.gvsig.geoprocessing.schemabuilder.XTypes;
97
import com.iver.utiles.swing.threads.IMonitorableTask;
98
import com.vividsolutions.jts.geom.Geometry;
99

    
100
/**
101
 * A clip between two layers is the intersection of the first layer with the
102
 * convex hull of the second layer.
103
 * 
104
 * It is an individual case of OverlayGeoprocess. When we would have piped
105
 * geoprocesses, we could model it like a pipe of a ConvexHull geoprocess and an
106
 * intersection geoprocess.
107
 * 
108
 * @author azabala
109
 * 
110
 */
111
public class ClipGeoprocess extends AbstractGeoprocess implements
112
                IOverlayGeoprocess {
113

    
114
        /**
115
         * overlay layer
116
         */
117
        private FLyrVect overlayLayer;
118

    
119
        /**
120
         * Schema of the result layer
121
         */
122

    
123
        private ILayerDefinition resultLayerDefinition;
124

    
125
        /**
126
         * flag to only clip selection of input layer
127
         */
128
        private boolean onlyFirstLayerSelection = false;
129

    
130
        /**
131
         * flag to only clip with selection of clipping layer
132
         */
133
        private boolean onlyClipLayerSelection = false;
134

    
135
        /**
136
         * processes input layer's features to clip its geometries with clipping
137
         * layer bounding box
138
         */
139
        private ClipVisitor visitor;
140

    
141
        /**
142
         * Constructor
143
         * 
144
         */
145
        public ClipGeoprocess(FLyrVect inputLayer) {
146
                setFirstOperand(inputLayer);
147
        }
148

    
149
        public void setSecondOperand(FLyrVect secondLayer) {
150
                this.overlayLayer = secondLayer;
151

    
152
        }
153

    
154
        public void setFirstOperand(FLyrVect firstLayer) {
155
                this.firstLayer = firstLayer;
156
        }
157

    
158
        public void setParameters(Map params) throws GeoprocessException {
159
                Boolean firstLayerSelection = (Boolean) params
160
                                .get("firstlayerselection");
161
                if (firstLayerSelection != null)
162
                        this.onlyFirstLayerSelection = firstLayerSelection.booleanValue();
163

    
164
                Boolean secondLayerSelection = (Boolean) params
165
                                .get("secondlayerselection");
166
                if (secondLayerSelection != null)
167
                        this.onlyClipLayerSelection = secondLayerSelection.booleanValue();
168
        }
169

    
170
        public void checkPreconditions() throws GeoprocessException {
171
                if (firstLayer == null)
172
                        throw new GeoprocessException("Clip: capa de entrada a null");
173
                if (overlayLayer == null)
174
                        throw new GeoprocessException("Clip: capa de clip a null");
175
                if (this.writer == null || this.schemaManager == null) {
176
                        throw new GeoprocessException(
177
                                        "Operacion de clip sin especificar capa de resultados");
178
                }
179

    
180
                try {
181
                        if (overlayLayer.getShapeType() != XTypes.POLYGON) {
182
                                throw new GeoprocessException(
183
                                                "La capa de recorte no es de pol?gonos");
184
                        }
185
                } catch (com.iver.cit.gvsig.fmap.DriverException e) {
186
                        throw new GeoprocessException(
187
                                        "Error al tratar de chequear si la capa de recorte es de pol?gonos");
188
                }
189
        }
190

    
191
        public void process() throws GeoprocessException {
192
                Geometry clippingGeometry = null;
193
                try {
194
                        clippingGeometry = computeJtsClippingPoly(null);
195
                } catch (Exception e) {
196
                        throw new GeoprocessException(
197
                                        "Error calculando el convex hull de la clipping layer");
198
                }
199
                visitor = new ClipVisitor(clippingGeometry, resultLayerDefinition,
200
                                schemaManager, writer);
201
                Strategy strategy = StrategyManager.getStrategy(firstLayer);
202
                try {
203
                        if (onlyFirstLayerSelection) {
204
                                strategy.process(visitor, firstLayer.getRecordset()
205
                                                .getSelection());
206
                        } else {
207
                                strategy.process(visitor);
208
                        }
209
                } catch (Exception e) {
210
                        throw new GeoprocessException(
211
                                        "Problemas al leer los datos de la capa a clipear");
212
                }
213
        }
214

    
215
        public void cancel() {
216
                // TODO Auto-generated method stub
217

    
218
        }
219

    
220
        public void setResultLayerProperties(IWriter writer,
221
                        ISchemaManager schemaManager) {
222
                this.writer = writer;
223
                this.schemaManager = schemaManager;
224

    
225
        }
226

    
227

    
228
        public ILayerDefinition createLayerDefinition() {
229
                //result layer definition will be the same that
230
                //input layer
231
                if(resultLayerDefinition == null){
232
                        try {
233
                                resultLayerDefinition = DefinitionUtils
234
                                                .createLayerDefinition(firstLayer);
235
                        } catch (Exception e) {
236
                                // TODO Quizas createLayerDefinition deberia lanzar
237
                                // una excepcion
238
                                e.printStackTrace();
239
                        }
240
                }
241
                return resultLayerDefinition;
242
        }
243

    
244
        /**
245
         * Computes union of all geometries of the clipping layer
246
         * 
247
         * @param cancel
248
         *            monitors cancellations and progress of clipping polygon
249
         *            computation.
250
         * @return
251
         * @throws com.iver.cit.gvsig.fmap.DriverException
252
         * @throws VisitException
253
         */
254
        private Geometry computeJtsClippingPoly(CancellableMonitorable cancel)
255
                        throws com.iver.cit.gvsig.fmap.DriverException, VisitException {
256
                ScalableUnionVisitor visitor = new ScalableUnionVisitor();
257

    
258
                Strategy strategy = StrategyManager.getStrategy(overlayLayer);
259
                if (onlyClipLayerSelection) {
260
                        strategy.process(visitor, overlayLayer.getRecordset()
261
                                        .getSelection(), cancel);
262
                } else {
263
                        strategy.process(visitor, cancel);
264
                }
265
                return visitor.getJtsConvexHull();
266
        }
267

    
268
        public FBitSet getOverlays(IGeometry firstLayerGeometry, int index) {
269
                // TODO Auto-generated method stub
270
                return null;
271
        }
272

    
273
        public IFeature[] computeIntersection(IGeometry firsLayerGeometry,
274
                        int firstLayerFeatureIndex, IGeometry secondLayerGeometry,
275
                        int secondLayerFeatureIndex) {
276
                // TODO Auto-generated method stub
277
                return null;
278
        }
279

    
280
        public IMonitorableTask createTask() {
281
                final CancellableMonitorable cancelMonitor = 
282
                        createCancelMonitor();
283

    
284
                return new IMonitorableTask() {
285
                        String CLIP_MESSAGE = "Computing clip polygon: ";
286
                        String INTERS_MESSAGE = "Clipping geometries: ";
287
                        String currentMsg = CLIP_MESSAGE;
288
                        private boolean finished = false;
289

    
290
                        public int getInitialStep() {
291
                                return cancelMonitor.getInitialStep();
292
                        }
293

    
294
                        public int getFinishStep() {
295
                                return cancelMonitor.getFinalStep();
296
                        }
297

    
298
                        public int getCurrentStep() {
299
                                return cancelMonitor.getCurrentStep();
300
                        }
301

    
302
                        public String getStatusMessage() {
303
                                // FIXME Cambiar esto por un mecanismo de eventos,
304
                                // de forma que la tarea lo que tenga sea un escuchador
305
                                // que cambie el mensaje de estado segun los eventos
306
                                // de tareas que se est?n realizando
307
                                return "Clip Geoprocess...";
308
                        }
309

    
310
                        public String getNote() {
311
                                // FIXME Cambiar esto por un mecanismo de eventos,
312
                                // de forma que la tarea lo que tenga sea un escuchador
313
                                // que cambie el mensaje de estado segun los eventos
314
                                // de tareas que se est?n realizando
315
                                return currentMsg  +
316
                                getCurrentStep()+ 
317
                                " de "+
318
                                getFinishStep();
319
                        }
320

    
321
                        public void cancel() {
322
                                ((DefaultCancellableMonitorable) cancelMonitor)
323
                                                .setCanceled(true);
324
                        }
325

    
326
                        public void run() {
327
                                
328
                                Geometry clippingGeometry = null;
329
                                try {
330
                                        clippingGeometry = computeJtsClippingPoly(cancelMonitor);
331
                                } catch (Exception e) {
332
                                        //FIXME Ver que pasa con las excepciones que
333
                                        //que pueda lanzar un ITask
334
                                }
335
                                currentMsg = INTERS_MESSAGE;
336
                                visitor = new ClipVisitor(clippingGeometry, resultLayerDefinition,
337
                                                schemaManager, writer);
338
                                Strategy strategy = StrategyManager.getStrategy(firstLayer);
339
                                try {
340
                                        if (onlyFirstLayerSelection) {
341
                                                strategy.process(visitor, firstLayer.getRecordset()
342
                                                                .getSelection(), cancelMonitor);
343
                                        } else {
344
                                                strategy.process(visitor, cancelMonitor);
345
                                        }
346
                                } catch (Exception e) {
347
                                        //FIXME Ver que pasa con las excepciones de las ITask
348
                                }
349
                                finished = true;
350
                        }
351

    
352
                        public boolean isDefined() {
353
                                return cancelMonitor.isDeterminatedProcess();
354
                        }
355

    
356
                        public boolean isCanceled() {
357
                                return cancelMonitor.isCanceled();
358
                        }
359

    
360
                        public boolean isFinished() {
361
                                return finished;
362
                        }
363
                };
364
        }
365

    
366
        private DefaultCancellableMonitorable createCancelMonitor() {
367
                DefaultCancellableMonitorable monitor = new DefaultCancellableMonitorable();
368
                monitor.setInitialStep(0);
369
                monitor.setDeterminatedProcess(true);
370
                int clipSteps = 0;
371
                if (onlyClipLayerSelection){
372
                        FBitSet selection = overlayLayer.getRecordset().getSelection();
373
                        clipSteps = selection.cardinality();
374
                }else{
375
                        try {
376
                                clipSteps = overlayLayer.getSource().getShapeCount();
377
                        } catch (DriverIOException e) {
378
                                // TODO Auto-generated catch block
379
                                e.printStackTrace();
380
                        }
381
                }
382
                int  firstSteps = 0;
383
                if (onlyFirstLayerSelection) {
384
                        FBitSet selection = firstLayer.getRecordset().getSelection();
385
                        firstSteps = selection.cardinality();
386
                } else {
387
                        try {
388
                                firstSteps = firstLayer.getSource()
389
                                                                .getShapeCount();
390
                        } catch (DriverIOException e) {
391
                                e.printStackTrace();
392
                        }
393
                }
394
                int totalSteps = clipSteps + firstSteps;
395
                monitor.setFinalStep(totalSteps);
396
                return monitor;
397
        }
398

    
399
}