Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / graph / topology / LineSnapGeoprocess.java @ 35010

History | View | Annotate | Download (9.66 KB)

1
/*
2
 * Created on 10-oct-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
*/
47
package org.gvsig.graph.topology;
48

    
49
import java.io.File;
50
import java.util.Map;
51

    
52
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
53
import com.iver.andami.PluginServices;
54
import com.iver.cit.gvsig.fmap.MapContext;
55
import com.iver.cit.gvsig.fmap.core.IFeature;
56
import com.iver.cit.gvsig.fmap.core.IGeometry;
57
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
58
import com.iver.cit.gvsig.fmap.core.v02.FConverter;
59
import com.iver.cit.gvsig.fmap.drivers.DriverIOException;
60
import com.iver.cit.gvsig.fmap.drivers.FieldDescription;
61
import com.iver.cit.gvsig.fmap.drivers.ILayerDefinition;
62
import com.iver.cit.gvsig.fmap.drivers.LayerDefinition;
63
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
64
import com.iver.cit.gvsig.fmap.edition.IWriter;
65
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager;
66
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
67
import com.iver.cit.gvsig.fmap.layers.FBitSet;
68
import com.iver.cit.gvsig.fmap.layers.FLayer;
69
import com.iver.cit.gvsig.fmap.layers.FLayers;
70
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
71
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
72
import com.iver.cit.gvsig.geoprocess.core.fmap.AbstractGeoprocess;
73
import com.iver.cit.gvsig.geoprocess.core.fmap.DefinitionUtils;
74
import com.iver.cit.gvsig.geoprocess.core.fmap.FeaturePersisterProcessor2;
75
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
76
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
77
import com.iver.cit.gvsig.geoprocess.impl.topology.lineclean.fmap.LineCleanVisitor;
78
import com.iver.cit.gvsig.project.documents.view.gui.View;
79
import com.iver.cit.gvsig.util.SnappingCoordinateMap;
80
import com.iver.utiles.swing.threads.AbstractMonitorableTask;
81
import com.iver.utiles.swing.threads.IMonitorableTask;
82
import com.iver.utiles.swing.threads.IPipedTask;
83
import com.vividsolutions.jts.geom.Coordinate;
84
import com.vividsolutions.jts.geom.Geometry;
85

    
86
public class LineSnapGeoprocess extends AbstractGeoprocess {
87

    
88
        /**
89
         * Schema of the result layer
90
         */
91
        private ILayerDefinition resultLayerDefinition;
92

    
93

    
94
        /**
95
         * flag to only clip selection of input layer
96
         */
97
        private boolean onlyFirstLayerSelection = false;
98
        
99
        /**
100
         * flag to mark if must create a layer with the detected
101
         * pseudonodes
102
         */
103
        private boolean createLyrsWithErrorGeometries = false;
104

    
105
        /**
106
         * Processes features (writing them)
107
         */
108
        FeaturePersisterProcessor2 processor;
109

    
110

    
111
        private boolean onlySnapNodes = false;
112
        
113
        private double tolerance = 0.1;
114

    
115

    
116
        public LineSnapGeoprocess(FLyrVect inputLayer){
117
                this.firstLayer = inputLayer;
118
        }
119

    
120

    
121
        public void setParameters(Map params) throws GeoprocessException {
122
                Boolean firstLayerSelection = (Boolean) params.get("firstlayerselection");
123
                if (firstLayerSelection != null)
124
                        this.onlyFirstLayerSelection =
125
                                firstLayerSelection.booleanValue();
126
                
127
                Boolean createLyrsWithError = (Boolean) params.get("createlayerswitherrors");
128
                if (createLyrsWithError != null)
129
                        this.createLyrsWithErrorGeometries =
130
                                createLyrsWithError.booleanValue();
131

    
132
                Boolean onlySnapNodes = (Boolean) params.get("onlysnapnodes");
133
                if (onlySnapNodes != null)
134
                        this.onlySnapNodes  =
135
                                onlySnapNodes.booleanValue();
136

    
137
        }
138

    
139
        public void checkPreconditions() throws GeoprocessException {
140
                if (firstLayer == null)
141
                        throw new GeoprocessException("CLEAN: capa de entrada a null");
142
                if (this.writer == null || this.schemaManager == null) {
143
                        throw new GeoprocessException(
144
                                        "Operacion de CLEAN sin especificar capa de resultados");
145
                }
146
                try {
147
                        if(firstLayer.getSource().getShapeCount() == 0){
148
                                throw new GeoprocessException(
149
                                "Capa de entrada vacia");
150
                        }
151
                } catch (ReadDriverException e) {
152
                        throw new GeoprocessException(
153
                        "Error al verificar si la capa est? vac?a");
154
                }
155
        }
156

    
157
        public void process() throws GeoprocessException {
158
                try {
159
                        createTask().run();
160
                } catch (Exception e) {
161
                        throw new GeoprocessException("Error al ejecutar el geoproceso", e);
162
                }
163
        }
164

    
165
        public ILayerDefinition createLayerDefinition() {
166
                if (resultLayerDefinition == null) {
167
                        try {
168
                                resultLayerDefinition = DefinitionUtils.
169
                                                        createLayerDefinition(firstLayer);
170
                        } catch (Exception e) {
171
                                e.printStackTrace();
172
                        }
173
                }
174
                return resultLayerDefinition;
175
        }
176

    
177

    
178
        class LineCleanTask extends AbstractMonitorableTask implements IPipedTask{
179

    
180
                private SnappingCoordinateMap coordMap;
181

    
182
                private LineCleanTask() {
183
                        setInitialStep(0);
184
                        try {
185
                                if (onlyFirstLayerSelection) {
186
                                        int numSelected = firstLayer.getRecordset().getSelection()
187
                                                        .cardinality();
188
                                        setFinalStep(numSelected);
189
                                } else {
190
                                        int numShapes = firstLayer.getSource().getShapeCount();
191
                                        setFinalStep(numShapes);
192
                                }// else
193
                        } catch (ReadDriverException e) {
194
                                // TODO Auto-generated catch block
195
                                e.printStackTrace();
196
                        }
197
                        setDeterminatedProcess(true);
198
                        setStatusMessage(PluginServices.getText(this,
199
                                        "LineClean._Progress_Message"));
200

    
201
                }
202

    
203
                /**
204
                 * Verifies cancelation events, and return a boolean flag if processes must
205
                 * be stopped for this cancelations events.
206
                 *
207
                 * @param cancel
208
                 * @param va
209
                 * @param visitor
210
                 * @return
211
                 * @throws DriverIOException
212
                 */
213
                protected boolean verifyCancelation(ReadableVectorial va) {
214
                        if (isCanceled()) {
215
                                try {
216
                                        va.stop();
217
                                } finally {
218
                                        return true;
219
                                }
220
                        }
221
                        return false;
222
                }
223

    
224

    
225
                public void run() throws Exception {
226
                        processor =
227
                                new FeaturePersisterProcessor2(writer);
228

    
229
                        FBitSet selection = null;
230
                        coordMap = new SnappingCoordinateMap(tolerance);
231
                        try {
232
                                processor.start();
233

    
234
                                ReadableVectorial va = firstLayer.getSource();
235
                                va.start();
236
                                for (int i = 0; i < va.getShapeCount(); i++) {// for each geometry
237
                                        if (verifyCancelation(va)) {
238
                                                return;
239
                                        }
240
                                        IFeature feat = null;
241
                                        if(selection != null){
242
                                                if (selection.get(i)) {
243
                                                                reportStep();
244
                                                                feat = va.getFeature(i);
245
                                                                feat = processFeature(feat);
246
                                                                processor.processFeature(feat);
247
                                                }
248

    
249
                                        }else{
250
                                                reportStep();
251
                                                feat = va.getFeature(i);
252
                                                feat = processFeature(feat);
253
                                        }
254
                                        processor.processFeature(feat);
255
                                }// for
256
                                va.stop();
257
                                processor.finish();
258

    
259

    
260
                        } catch (ReadDriverException e) {
261
                                e.printStackTrace();
262
                        }
263
                }
264

    
265
                private IFeature processFeature(IFeature feat) {
266
                        IGeometry geom = feat.getGeometry();
267
                        Geometry jtsGeom = geom.toJTSGeometry();
268
                        Coordinate[] coords = jtsGeom.getCoordinates();
269
                        Coordinate c1 = coords[0];
270
                        Coordinate c2 = coords[coords.length-1];
271
                        if (coordMap.containsKey(c1)) {
272
                                c1 = (Coordinate) coordMap.get(c1);
273
                        }
274
                        else
275
                        {
276
                                coordMap.put(c1, c1);
277
                        }
278
                        if (coordMap.containsKey(c2)) {
279
                                c2 = (Coordinate) coordMap.get(c2);
280
                        }
281
                        else
282
                        {
283
                                coordMap.put(c2, c2);
284
                        }
285
                        coords[0] = c1;
286
                        coords[coords.length-1] = c2;
287
                        Geometry newJtsG = jtsGeom.getFactory().createLineString(coords);
288
                        feat.setGeometry(FConverter.jts_to_igeometry(newJtsG));
289
                        return feat;
290
                        
291
                }
292

    
293
                // TODO INTERNACIONALIZAR LOS MENSAJES
294
                public String getNote() {
295
                        String cleaningText = PluginServices.getText(this, "Limpiando_lineas");
296
                        String of = PluginServices.getText(this, "de");
297
                        return cleaningText + " " + getCurrentStep() + " "
298
                                        + of + " " + getFinishStep();
299
                }
300

    
301
                public void cancel() {
302
                        setCanceled(true);
303
                        LineSnapGeoprocess.this.cancel();
304
                }
305

    
306
                /* (non-Javadoc)
307
                 * @see com.iver.utiles.swing.threads.IPipedTask#getResult()
308
                 */
309
                public Object getResult() {
310
                        try {
311
                                return LineSnapGeoprocess.this.getResult();
312
                        } catch (GeoprocessException e) {
313
                                return null;
314
                        }
315
                }
316

    
317
                /* (non-Javadoc)
318
                 * @see com.iver.utiles.swing.threads.IPipedTask#setEntry(java.lang.Object)
319
                 */
320
                public void setEntry(Object object) {
321
                        // TODO Auto-generated method stub
322

    
323
                }
324

    
325
                /* (non-Javadoc)
326
                 * @see com.iver.utiles.swing.threads.IMonitorableTask#finished()
327
                 */
328
                public void finished() {
329
                        // TODO Auto-generated method stub
330

    
331
                }
332
        }
333

    
334

    
335
        public IMonitorableTask createTask() {
336
                return new LineCleanTask();
337
        }
338

    
339
        public FLayer getResult() throws GeoprocessException {
340
                FLyrVect cleanedLayer = (FLyrVect) createLayerFrom(this.writer);
341
                return cleanedLayer;
342
        }
343

    
344

    
345
        public double getTolerance() {
346
                return tolerance;
347
        }
348

    
349

    
350
        public void setTolerance(double tolerance) {
351
                this.tolerance = tolerance;
352
        }
353

    
354
}
355