Statistics
| Revision:

root / trunk / extensions / extGeoProcessing / src / com / iver / gvsig / geoprocessing / impl / dissolve / DissolveGeoprocess.java @ 4447

History | View | Annotate | Download (10.2 KB)

1
/*
2
 * Created on 23-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: DissolveGeoprocess.java 4447 2006-03-15 18:35:56Z azabala $
47
* $Log$
48
* Revision 1.6  2006-03-15 18:33:24  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:58:20  azabala
61
* *** empty log message ***
62
*
63
* Revision 1.1  2006/02/26 20:53:44  azabala
64
* *** empty log message ***
65
*
66
*
67
*/
68
package com.iver.gvsig.geoprocessing.impl.dissolve;
69

    
70
import java.util.ArrayList;
71
import java.util.Iterator;
72
import java.util.Map;
73

    
74
import com.iver.cit.gvsig.fmap.DriverException;
75
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
76
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
77
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
78
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
79
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
80
import com.iver.cit.gvsig.fmap.edition.EditionException;
81
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
82
import com.iver.cit.gvsig.fmap.operations.CancellableMonitorable;
83
import com.iver.cit.gvsig.fmap.operations.DefaultCancellableMonitorable;
84
import com.iver.cit.gvsig.fmap.operations.strategies.Strategy;
85
import com.iver.cit.gvsig.fmap.operations.strategies.StrategyManager;
86
import com.iver.cit.gvsig.fmap.operations.strategies.VisitException;
87
import com.iver.gvsig.geoprocessing.impl.AbstractGeoprocess;
88
import com.iver.gvsig.geoprocessing.impl.jtsprocessors.FeaturePersisterProcessor2;
89
import com.iver.gvsig.geoprocessing.model.GeoprocessException;
90
import com.iver.gvsig.geoprocessing.model.IOneLayerGeoprocess;
91
import com.iver.gvsig.geoprocessing.model.SummarizationFunction;
92
import com.iver.gvsig.geoprocessing.schemabuilder.XTypes;
93
import com.iver.utiles.swing.threads.IMonitorableTask;
94
/**
95
 * Processes each geometry of a polygonal vectorial layer, looking for
96
 * its adjacent polygons. If this adjacent polygons has the same specified 
97
 * field value as processed geometry, this polygons will be dissolved.
98
 * 
99
 * 
100
 * @author azabala
101
 *
102
 */
103
public class DissolveGeoprocess extends AbstractGeoprocess
104
                                                        implements IOneLayerGeoprocess {
105

    
106
        private String dissolveField;
107
        private boolean dissolveOnlySelection;
108
        private LayerDefinition resultLayerDefinition;
109
        private Map fields_functions;
110
        private DissolveVisitor visitor;
111
        
112
        
113
        /**
114
         * Constructor.
115
         * 
116
         * @param inputLayer Layer whose geometries we are 
117
         * going to dissolve
118
         */
119
        public DissolveGeoprocess(FLyrVect inputLayer, String dissolveField) {
120
                setFirstOperand(inputLayer);
121
                this.dissolveField = dissolveField;
122
        }
123
        
124
        public void setFieldsFunctions(Map fieldsFunctions){
125
                this.fields_functions = fieldsFunctions;
126
        }
127

    
128
        public void setFirstOperand(FLyrVect inputLayer) {
129
                this.firstLayer = inputLayer;
130

    
131
        }
132

    
133
        public void setParameters(Map params) throws GeoprocessException {
134
                Boolean onlySelection =
135
                        (Boolean) params.get("layer_selection");
136
                if(onlySelection != null)
137
                        dissolveOnlySelection = onlySelection.booleanValue();
138
                
139
        }
140

    
141
        public void checkPreconditions() throws GeoprocessException {
142
                if (firstLayer == null)
143
                        throw new GeoprocessException("Buffer con capa de entrada a null");
144
                if(this.writer == null || 
145
                   this.schemaManager == null){
146
                        throw new GeoprocessException("Operacion de dissolve sin especificar capa de resultados");
147
                }
148
                if(this.dissolveField == null)
149
                        throw new GeoprocessException("No se ha proporcionado el campo para dissolver");
150

    
151
        }
152

    
153
        public void process() throws GeoprocessException {
154
                try {
155
                        FeaturePersisterProcessor2 processor =
156
                                new FeaturePersisterProcessor2(writer);
157
                        visitor = new DissolveVisitor(this.dissolveField, processor);
158
                        visitor.setDissolvedAttributesInfo(fields_functions);
159
                        Strategy strategy =
160
                                StrategyManager.getStrategy(firstLayer);
161
                        visitor.setStrategy(strategy);
162
                        if(this.dissolveOnlySelection){
163
                                strategy.process(visitor, firstLayer.
164
                                                                                           getRecordset().
165
                                                                                           getSelection());
166
                        }else{
167
                                strategy.process(visitor);
168
                        }
169
                } catch (DriverException e) {
170
                        throw new GeoprocessException("Error accediendo a los datos durante un dissolve");
171
                } catch (VisitException e) {
172
                        throw new GeoprocessException("Error al procesar los elementos de la capa de entrada durante un dissolve");
173
                }
174
        }
175
        
176
        
177

    
178
        public void cancel() {
179
                try {
180
                        schemaManager.drop();
181
                } catch (EditionException e) {
182
                        // TODO Auto-generated catch block
183
                        e.printStackTrace();
184
                }
185
        }
186
        
187
        public ILayerDefinition createLayerDefinition() {
188
                if(resultLayerDefinition == null){
189
                        ArrayList fields = new ArrayList();
190
                        resultLayerDefinition = new SHPLayerDefinition();
191
                        resultLayerDefinition.setShapeType(XTypes.POLYGON);
192
                        
193
                        Iterator fieldsIt = fields_functions.keySet().iterator();
194
                        while(fieldsIt.hasNext()){
195
                                String field = (String) fieldsIt.next();
196
                                SummarizationFunction[] functions =
197
                                        (SummarizationFunction[]) fields_functions.get(field);
198
                                for(int i = 0; i < functions.length; i++){
199
                                        FieldDescription description = 
200
                                                new FieldDescription();
201
                                        description.setFieldLength(10);
202
                                        description.setFieldDecimalCount(4);
203
                                        //to avoid truncation of field names (f.example shp)
204
                                        //we only catch three first letters
205
                                        String shortName = null;
206
                                        if(field.length() > 3)
207
                                                shortName = field.substring(0,3);
208
                                        else
209
                                                shortName = field;
210
                                        description.setFieldName(
211
                                                        shortName + "_" + functions[i].toString());
212
                                        description.setFieldType(XTypes.DOUBLE);
213
                                        
214
                                        fields.add(description);
215
                                }//for
216
                        }//while
217
                        FieldDescription[] fieldsDesc = null;
218
                        if(fields.size() == 0){
219
                                fieldsDesc = new FieldDescription[0];
220
                        }else{
221
                                fieldsDesc = new FieldDescription[fields.size()];
222
                                fields.toArray(fieldsDesc);
223
                        }
224
                        resultLayerDefinition.setFieldsDesc(fieldsDesc);
225
                }
226
                return resultLayerDefinition;
227
        }
228

    
229
        public IMonitorableTask createTask() {
230
                try {
231
                        return new DissolveMonitorableTask();
232
                } catch (DriverIOException e) {
233
                        return null;
234
                }
235
        }
236
        
237
        /**
238
         * IMonitorableTask that allows to run diff geoprocess in background,
239
         * with cancelation requests.
240
         * 
241
         * @author azabala
242
         * 
243
         */
244
        class DissolveMonitorableTask implements IMonitorableTask {
245
                private CancellableMonitorable cancelMonitor = null;
246

    
247
                // FIXME INTERNACIONALIZAR ESTO
248
                String DISSOLVE_MESSAGE = "Computing dissolve: ";
249

    
250
                private boolean finished = false;
251

    
252
                DissolveMonitorableTask() throws DriverIOException {
253
                        initialize();
254
                }
255
                void initialize() throws DriverIOException{
256
                        cancelMonitor = createCancelMonitor();
257
                }
258

    
259
                private CancellableMonitorable createCancelMonitor() throws DriverIOException{
260
                        DefaultCancellableMonitorable monitor = new 
261
                                                        DefaultCancellableMonitorable();
262
                        monitor.setInitialStep(0);
263
                        //monitor.setDeterminatedProcess(false);
264
                        monitor.setFinalStep(firstLayer.getSource().getShapeCount());
265
                        monitor.setDeterminatedProcess(true);
266
                        return monitor;
267
                }
268

    
269
                public int getInitialStep() {
270
                        return cancelMonitor.getInitialStep();
271
                }
272

    
273
                public int getFinishStep() {
274
                        return cancelMonitor.getFinalStep();
275
                }
276

    
277
                public int getCurrentStep() {
278
                        //return cancelMonitor.getCurrentStep();
279
                        if(visitor == null)
280
                                return getInitialStep();
281
                        else
282
                                return visitor.getNumProcessedGeometries();
283
                }
284

    
285
                public String getStatusMessage() {
286
                        // FIXME Cambiar esto por un mecanismo de eventos,
287
                        // de forma que la tarea lo que tenga sea un escuchador
288
                        // que cambie el mensaje de estado segun los eventos
289
                        // de tareas que se est?n realizando
290
                        return "Dissolve Geoprocess...";
291
                }
292

    
293
                public String getNote() {
294
                        // FIXME Cambiar esto por un mecanismo de eventos,
295
                        // de forma que la tarea lo que tenga sea un escuchador
296
                        // que cambie el mensaje de estado segun los eventos
297
                        // de tareas que se est?n realizando
298
                        return DISSOLVE_MESSAGE + getCurrentStep() + " of " +
299
                                                                                                        getFinishStep();
300
                }
301

    
302
                public void cancel() {
303
                        ((DefaultCancellableMonitorable) cancelMonitor).setCanceled(true);
304
                }
305

    
306
                public void run() throws GeoprocessException {
307

    
308
                        try {
309

    
310
                                FeaturePersisterProcessor2 processor =
311
                                        new FeaturePersisterProcessor2(writer);
312
                                visitor = new DissolveVisitor(dissolveField, processor);
313
                                visitor.setDissolvedAttributesInfo(fields_functions);
314
                                Strategy strategy =
315
                                        StrategyManager.getStrategy(firstLayer);
316
                                visitor.setStrategy(strategy);
317
                                if(dissolveOnlySelection){
318
                                        strategy.process(visitor, firstLayer.
319
                                                                                                   getRecordset().
320
                                                                                                   getSelection(),
321
                                                                                                   cancelMonitor);
322
                                }else{
323
                                        strategy.process(visitor, cancelMonitor);
324
                                }
325
                        } catch (DriverException e) {
326
                                throw new GeoprocessException("Error accediendo a los datos durante un dissolve");
327
                        } catch (VisitException e) {
328
                                throw new GeoprocessException("Error al procesar los elementos de la capa de entrada durante un dissolve");
329
                        } finally{
330
                                finished = true;
331
                        }
332
                }
333

    
334
                public boolean isDefined() {
335
                        return cancelMonitor.isDeterminatedProcess();
336
                }
337

    
338
                public boolean isCanceled() {
339
                        return cancelMonitor.isCanceled();
340
                }
341

    
342
                public boolean isFinished() {
343
                        return finished;
344
                }
345
        }
346

    
347
}
348