Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / graph / GenerateNetworkExtension.java @ 34418

History | View | Annotate | Download (17.5 KB)

1
/* gvSIG. Sistema de Informaci�n Geogr�fica de la Generalitat Valenciana
2
 *
3
 * Copyright (C) 2004 IVER T.I. and Generalitat Valenciana.
4
 *
5
 * This program is free software; you can redistribute it and/or
6
 * modify it under the terms of the GNU General Public License
7
 * as published by the Free Software Foundation; either version 2
8
 * of the License, or (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307,USA.
18
 *
19
 * For more information, contact:
20
 *
21
 *  Generalitat Valenciana
22
 *   Conselleria d'Infraestructures i Transport
23
 *   Av. Blasco Ib��ez, 50
24
 *   46010 VALENCIA
25
 *   SPAIN
26
 *
27
 *      +34 963862235
28
 *   gvsig@gva.es
29
 *      www.gvsig.gva.es
30
 *
31
 *    or
32
 *
33
 *   IVER T.I. S.A
34
 *   Salamanca 50
35
 *   46005 Valencia
36
 *   Spain
37
 *
38
 *   +34 963163400
39
 *   dac@iver.es
40
 */
41
package org.gvsig.graph;
42

    
43
import java.awt.Component;
44
import java.awt.geom.Rectangle2D;
45
import java.io.File;
46
import java.util.HashMap;
47

    
48
import javax.swing.ImageIcon;
49
import javax.swing.JFileChooser;
50
import javax.swing.JOptionPane;
51

    
52
import org.gvsig.exceptions.BaseException;
53
import org.gvsig.graph.core.NetworkUtils;
54
import org.gvsig.graph.core.writers.NetworkFileRedWriter;
55
import org.gvsig.graph.core.writers.NetworkGvTableWriter;
56
import org.gvsig.graph.gui.wizard.NetWizard;
57
import org.gvsig.graph.preferences.RoutePage;
58
import org.gvsig.graph.topology.LineSnapGeoprocess;
59

    
60
import com.hardcode.gdbms.driver.exceptions.InitializeDriverException;
61
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
62
import com.iver.andami.PluginServices;
63
import com.iver.andami.messages.NotificationManager;
64
import com.iver.andami.plugins.Extension;
65
import com.iver.andami.preferences.IPreference;
66
import com.iver.andami.preferences.IPreferenceExtension;
67
import com.iver.andami.ui.mdiManager.IWindow;
68
import com.iver.cit.gvsig.fmap.MapContext;
69
import com.iver.cit.gvsig.fmap.MapControl;
70
import com.iver.cit.gvsig.fmap.core.FShape;
71
import com.iver.cit.gvsig.fmap.drivers.BoundedShapes;
72
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
73
import com.iver.cit.gvsig.fmap.edition.IWriter;
74
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager;
75
import com.iver.cit.gvsig.fmap.edition.writers.dbf.DbfWriter;
76
import com.iver.cit.gvsig.fmap.edition.writers.shp.MultiShpWriter;
77
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
78
import com.iver.cit.gvsig.fmap.layers.FLayer;
79
import com.iver.cit.gvsig.fmap.layers.FLayers;
80
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
81
import com.iver.cit.gvsig.fmap.layers.ReadableVectorial;
82
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
83
import com.iver.cit.gvsig.fmap.layers.VectorialAdapter;
84
import com.iver.cit.gvsig.fmap.spatialindex.IPersistentSpatialIndex;
85
import com.iver.cit.gvsig.fmap.spatialindex.ISpatialIndex;
86
import com.iver.cit.gvsig.fmap.spatialindex.QuadtreeJts;
87
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
88
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
89
import com.iver.cit.gvsig.geoprocess.impl.topology.lineclean.fmap.LineCleanGeoprocess;
90
import com.iver.cit.gvsig.geoprocess.impl.topology.lineclean.fmap.LineCleanVisitor;
91
import com.iver.cit.gvsig.project.documents.view.IProjectView;
92
import com.iver.cit.gvsig.project.documents.view.gui.IView;
93
import com.iver.cit.gvsig.project.documents.view.gui.View;
94
import com.iver.utiles.SimpleFileFilter;
95
import com.iver.utiles.swing.threads.AbstractMonitorableTask;
96
import com.iver.utiles.swing.threads.IPipedTask;
97
import com.iver.utiles.swing.threads.PipeTask;
98

    
99
public class GenerateNetworkExtension extends Extension implements
100
                IPreferenceExtension {
101
        private static final IPreference[] thePreferencePages = new IPreference[] { new RoutePage() };
102
        
103
        public boolean onlySnapNodes = true;
104

    
105
        private double snapTolerance;
106

    
107
        public void initialize() {
108
                PluginServices.getIconTheme().registerDefault(
109
                                "build_graph",
110
                                this.getClass().getClassLoader().getResource(
111
                                                "images/build_graph.png"));
112

    
113
                // ExtensionPoints extensionPoints =
114
                // ExtensionPointsSingleton.getInstance();
115
                // ((ExtensionPoint)
116
                // extensionPoints.get("View_TocActions")).remove("FLyrVectEditProperties");
117
                // ((ExtensionPoint)
118
                // extensionPoints.get("View_TocActions")).remove("FLyrVectEditProperties2");
119
                // ((ExtensionPoint)
120
                // extensionPoints.get("View_TocActions")).put("FLyrVectEditProperties",new
121
                // FLyrVectEditPropertiesTocMenuEntry2());
122
                // extensionPoints.add("View_TocActions","FLyrVectEditProperties2",new
123
                // FLyrVectEditPropertiesTocMenuEntry2());
124

    
125
        }
126

    
127
        public void execute(String actionCommand) {
128
                IView view = (View) PluginServices.getMDIManager().getActiveWindow();
129
                MapControl mapControl = view.getMapControl();
130
                MapContext map = mapControl.getMapContext();
131
                FLayers tocLyrs = map.getLayers();
132
                SingleLayerIterator lyrIterator = new SingleLayerIterator(tocLyrs);
133
                while (lyrIterator.hasNext()) {
134
                        FLayer lyr = lyrIterator.next();
135
                        if ((lyr.isActive()) && (lyr instanceof FLyrVect)) {
136
                                FLyrVect lyrVect = (FLyrVect) lyr;
137
                                int shapeType;
138
                                try {
139
                                        shapeType = lyrVect.getShapeType();
140
                                        if ((shapeType & FShape.LINE) == FShape.LINE) {
141
                                                if (actionCommand.equalsIgnoreCase("GENERATE_RED")) {
142
                                                        generateRedNetwork(lyrVect, tocLyrs);
143
                                                        return;
144
                                                }
145
                                        }
146
                                } catch (BaseException e) {
147
                                        e.printStackTrace();
148
                                        NotificationManager.addError(e);
149
                                }
150

    
151
                        }
152
                }
153

    
154
        }
155

    
156
        private void generateNetwork(FLyrVect lyr) {
157
                NetworkGvTableWriter netBuilder = new NetworkGvTableWriter();
158
                // Por ahora, a pelo, pero hay que sacar un cuadro
159
                // de di�logo para hecer el mapping.
160
                // Tambi�n un cuadro de di�logo para seleccionar
161
                // en qu� tablas quiere escribir, y su formato
162
                // (dbf, postgres, etc)
163
                String fieldType = "tipored";
164
                String fieldDist = "length";
165
                String fieldSense = "sen";
166
                String fieldCost = "cost";
167
                try {
168
                        netBuilder.setLayer(lyr);
169
                        netBuilder.setFieldType(fieldType);
170
                        netBuilder.setFieldDist(fieldDist);
171
                        netBuilder.setFieldSense(fieldSense);
172
                        netBuilder.setFieldCost(fieldCost);
173
                        DbfWriter nodeWriter = new DbfWriter();
174
                        nodeWriter.setFile(new File("c:/nodes.dbf"));
175

    
176
                        DbfWriter edgeWriter = new DbfWriter();
177
                        edgeWriter.setFile(new File("c:/edges.dbf"));
178

    
179
                        netBuilder.setEdgeWriter(edgeWriter);
180
                        netBuilder.setNodeWriter(nodeWriter);
181

    
182
                        netBuilder.writeNetwork();
183
                } catch (BaseException e1) {
184
                        // TODO Auto-generated catch block
185
                        e1.printStackTrace();
186
                }
187
                JOptionPane.showMessageDialog(null, PluginServices
188
                                .getText(this, "done"));
189
        }
190

    
191
        class GenerateRedNetworkAfterCleanTask extends AbstractMonitorableTask
192
                        implements IPipedTask {
193

    
194
                File redFile;
195
                NetworkFileRedWriter netBuilder;
196

    
197
                FLyrVect inputLayer;
198
                FLyrVect pseudonodes;
199
                FLayers tocLyrs;
200

    
201
                /**
202
                 * Constructor
203
                 * 
204
                 * @param tocLyrs
205
                 */
206
                GenerateRedNetworkAfterCleanTask(NetworkFileRedWriter netBuilder,
207
                                FLayers tocLyrs) {
208
                        this.netBuilder = netBuilder;
209
                        this.tocLyrs = tocLyrs;
210
                        setInitialStep(0);
211
                        setDeterminatedProcess(true);
212
                        setStatusMessage(PluginServices.getText(this,
213
                                        "Generando_red_a_partir_de_capa_lineal"));
214
                }
215

    
216
                public void run() throws Exception {
217
                        int numShapes;
218
                        try {
219
                                numShapes = inputLayer.getSource().getShapeCount();
220
                                // lo del 10 es para que termine despu�s de
221
                                // escribir los puntos
222
                                setFinalStep(numShapes + 10);
223

    
224
                        } catch (BaseException e) {
225
                                // TODO Auto-generated catch block
226
                                e.printStackTrace();
227
                        }
228
                        netBuilder.setLayer(inputLayer);
229
                        netBuilder.setCancellableMonitorable(this);
230
                        netBuilder.setRedFile(redFile);
231
                        netBuilder.writeNetwork();
232
                        tocLyrs.addLayer(inputLayer);
233
                        if (pseudonodes != null)
234
                                tocLyrs.addLayer(pseudonodes);
235
                        enableControls(inputLayer, redFile);
236
                }
237

    
238
                public String getNote() {
239
                        String processText = PluginServices.getText(this,
240
                                        "Procesando_linea");
241
                        String of = PluginServices.getText(this, "de");
242
                        return processText + " " + getCurrentStep() + " " + of + " "
243
                                        + getFinishStep();
244
                }
245

    
246
                public void cancel() {
247
                        setCanceled(true);
248
                }
249

    
250
                public boolean isFinished() {
251
                        return (getCurrentStep() >= getFinalStep());
252
                }
253

    
254
                /*
255
                 * (non-Javadoc)
256
                 * 
257
                 * @see com.iver.utiles.swing.threads.IPipedTask#getResult()
258
                 */
259
                public Object getResult() {
260
                        // TODO Auto-generated method stub
261
                        return null;
262
                }
263

    
264
                /**
265
                 * Implementation of PipeTask interface
266
                 */
267
                public void setEntry(Object object) {
268
                        // The previous task of this piped task is clean geoprocess
269
                        // whose result es FLayers with two layers
270
                        // first layer has cleaned layer
271
                        // and second layer has pseudonodes layer
272
                        if (object instanceof FLayers) {
273
                                FLayers layers = (FLayers) object;
274
                                this.inputLayer = (FLyrVect) layers.getLayer(0);
275
                                inputLayer.createSpatialIndex();
276
                                this.redFile = NetworkUtils.getNetworkFile(inputLayer);
277
                                this.pseudonodes = (FLyrVect) layers.getLayer(1);
278
                        }
279
                        else if (object instanceof FLyrVect) // no hab�a errores
280
                        {
281
                                this.inputLayer = (FLyrVect) object;
282
                                inputLayer.createSpatialIndex();
283
                                this.redFile = NetworkUtils.getNetworkFile(inputLayer);
284
                                this.pseudonodes = null;                                
285
                        }
286
                }
287
        }
288

    
289
        public void enableControls(final FLyrVect layer, final File netFile) throws BaseException {
290
                int resp = JOptionPane.showConfirmDialog((Component) PluginServices.getMDIManager().getActiveWindow(),
291
                                PluginServices.getText(null, "load_generated_network"),
292
                                PluginServices.getText(null, "Network"),
293
                                JOptionPane.YES_NO_OPTION);
294
                
295
                if (resp == JOptionPane.YES_OPTION) {
296
                        LoadDefaultNetworkExtension ext = (LoadDefaultNetworkExtension) PluginServices.getExtension(LoadDefaultNetworkExtension.class);
297
                        ext.loadNetwork(layer, netFile);
298
                }
299
                
300
                PluginServices.backgroundExecution(new Runnable() {
301
                        public void run() {
302
                                PluginServices.getMainFrame().enableControls();
303
                        }
304
                });
305
        }
306

    
307
        public class GenerateRedNetworkTask extends AbstractMonitorableTask {
308
                FLyrVect layer;
309

    
310
                File redFile;
311

    
312
                NetworkFileRedWriter netBuilder;
313

    
314
                /**
315
                 * Constructor
316
                 */
317
                public GenerateRedNetworkTask(FLyrVect layer, File redFile,
318
                                NetworkFileRedWriter netBuilder) {
319
                        this.layer = layer;
320
                        try {                        
321
//                                if (layer.isSpatiallyIndexed()) {
322
                                        layer.setISpatialIndex(NetworkUtils.createJtsQuadtree(layer));
323
//                                }
324
        
325
                                this.redFile = redFile;
326
                                this.netBuilder = netBuilder;
327
                                setInitialStep(0);
328
                                int numShapes;
329
                        
330
                                numShapes = layer.getSource().getShapeCount();
331
                                // lo del 10 es porque escribimos los nodos despu�s de
332
                                // los tramos.
333
                                setFinalStep(numShapes + 10);
334
                                setDeterminatedProcess(true);
335
                                setStatusMessage(PluginServices.getText(this,
336
                                                "Generando_red_a_partir_de_capa_lineal"));
337
                        } catch (BaseException e) {
338
                                // TODO Auto-generated catch block
339
                                e.printStackTrace();
340
                        }
341

    
342
                }
343

    
344
                public void run() throws Exception {
345
                        netBuilder.setLayer(layer);
346
                        netBuilder.setCancellableMonitorable(this);
347
                        netBuilder.setRedFile(redFile);
348
                        netBuilder.writeNetwork();
349
                        enableControls(layer, redFile);
350
                }
351

    
352
                public String getNote() {
353
                        String processText = PluginServices.getText(this,
354
                                        "Procesando_linea");
355
                        String of = PluginServices.getText(this, "de");
356
                        return processText + " " + getCurrentStep() + " " + of + " "
357
                                        + getFinishStep();
358
                }
359

    
360
                public void cancel() {
361
                        setCanceled(true);
362
                }
363

    
364
                public Object getResult() {
365
                        return null;
366

    
367
                }
368

    
369
                public void setEntry(Object object) {
370
                        this.layer = (FLyrVect) object;
371
                }
372
        }
373

    
374
        /**
375
         * It returns a geoprocess to make a CLEAN of the input layer
376
         */
377
        private LineSnapGeoprocess createCleanGeoprocess(FLyrVect lineLyr) {
378
                File outputFile = null;
379
                JOptionPane.showMessageDialog(null, PluginServices.getText(null,
380
                                "Especifique_fichero_shp_resultante"), PluginServices.getText(
381
                                null, "Fichero_para_capa_corregida"),
382
                                JOptionPane.INFORMATION_MESSAGE);
383
                JFileChooser jfc = new JFileChooser();
384
                SimpleFileFilter filterShp = new SimpleFileFilter("shp", PluginServices
385
                                .getText(this, "shp_files"));
386
                jfc.setFileFilter(filterShp);
387
                if (jfc.showSaveDialog((Component) PluginServices.getMainFrame()) == JFileChooser.APPROVE_OPTION) {
388
                        File newFile = jfc.getSelectedFile();
389
                        String path = newFile.getAbsolutePath();
390
                        if (newFile.exists()) {
391
                                int resp = JOptionPane.showConfirmDialog(
392
                                                (Component) PluginServices.getMainFrame(),
393
                                                PluginServices.getText(this,
394
                                                                "fichero_ya_existe_seguro_desea_guardarlo"),
395
                                                PluginServices.getText(this, "guardar"),
396
                                                JOptionPane.YES_NO_OPTION);
397
                                if (resp != JOptionPane.YES_OPTION) {
398
                                        return null;
399
                                }
400
                        }// if
401
                        if (!(path.toLowerCase().endsWith(".shp"))) {
402
                                path = path + ".shp";
403
                        }
404
                        outputFile = new File(path);
405
                } else {
406
                        return null;
407
                }
408
//                LineCleanGeoprocess geoprocess = new LineCleanGeoprocess(lineLyr);
409
                LineSnapGeoprocess geoprocess = new LineSnapGeoprocess(lineLyr);
410
                geoprocess.setTolerance(snapTolerance);
411
                SHPLayerDefinition definition = (SHPLayerDefinition) geoprocess
412
                                .createLayerDefinition();
413
                definition.setFile(outputFile);
414
                ShpSchemaManager schemaManager = new ShpSchemaManager(outputFile
415
                                .getAbsolutePath());
416
                IWriter writer = null;
417
                try {
418
                        int shapeType = definition.getShapeType();
419
                        if (shapeType != XTypes.MULTI) {
420
                                writer = new ShpWriter();
421
                                ((ShpWriter) writer).setFile(definition.getFile());
422
                                writer.initialize(definition);
423
                        } else {
424
                                writer = new MultiShpWriter();
425
                                ((MultiShpWriter) writer).setFile(definition.getFile());
426
                                writer.initialize(definition);
427
                        }
428
                } catch (Exception e1) {
429
                        String error = PluginServices.getText(this,
430
                                        "Error_escritura_resultados");
431
                        String errorDescription = PluginServices.getText(this,
432
                                        "Error_preparar_escritura_resultados");
433
                        return null;
434
                }
435
                geoprocess.setResultLayerProperties(writer, schemaManager);
436
                HashMap params = new HashMap();
437
                params.put("layer_selection", new Boolean(false));
438
                params.put("onlysnapnodes", new Boolean(onlySnapNodes));
439
//                boolean createLayerWithError = true;
440
//                params.put("createlayerswitherrors", new Boolean(createLayerWithError));
441
                
442
                try {
443
                        geoprocess.setParameters(params);
444
                        geoprocess.checkPreconditions();
445
                        return geoprocess;
446

    
447
                } catch (GeoprocessException e) {
448
                        String error = PluginServices.getText(this, "Error_ejecucion");
449
                        String errorDescription = PluginServices.getText(this,
450
                                        "Error_fallo_geoproceso");
451
                        return null;
452
                }
453

    
454
        }
455

    
456
        private void generateRedNetwork(FLyrVect lyr, FLayers tocLyrs) {
457

    
458
                NetworkFileRedWriter netBuilder = new NetworkFileRedWriter();
459
                // Por ahora, a pelo, pero hay que sacar un cuadro
460
                // de di�logo para hecer el mapping.
461
                // Tambi�n un cuadro de di�logo para seleccionar
462
                // en qu� tablas quiere escribir, y su formato
463
                // (dbf, postgres, etc)
464

    
465
                ImageIcon icon = new ImageIcon(this.getClass().getClassLoader()
466
                                .getResource("images/net-wizard-logo.jpg"));
467

    
468
                NetWizard wiz = new NetWizard(icon, lyr);
469
                PluginServices.getMDIManager().addWindow(wiz);
470
                if (!wiz.wasFinishPressed())
471
                        return;
472
                // try {
473
                String fieldType = wiz.getFieldType();
474
                String fieldLength = wiz.getFieldLength();
475
                String fieldCost = wiz.getFieldCost();
476
                String fieldSense = wiz.getFieldSense();
477

    
478
                netBuilder.setLayer(lyr);
479
                netBuilder.setFieldType(fieldType);
480
                netBuilder.setFieldDist(fieldLength);
481
                netBuilder.setFieldSense(fieldSense);
482
                netBuilder.setFieldCost(fieldCost);
483
                netBuilder.setDigitalizationDirection(wiz.getSenseDigitalization());
484
                netBuilder.setReverseDigitalizationDirection(wiz
485
                                .getSenseReverseDigitalization());
486
                File redFile = wiz.getNetworkFile();
487

    
488
                boolean applySnap = wiz.getApplySnapTolerance();
489
                if (applySnap) {
490
                        snapTolerance = wiz.getSnapTolerance();
491
                        netBuilder.setSnapTolerance(snapTolerance);
492
                }
493

    
494
                boolean cleanOrigLyr = wiz.getCleanOriginalLayer();
495
                LineSnapGeoprocess clean = null;
496
                if (cleanOrigLyr) {
497
                        clean = createCleanGeoprocess(lyr);
498
                        if (clean == null)
499
                                return;
500
                        
501
                        
502
                }
503
                if (clean != null) {
504
                        // we wont start the process of network creation
505
                        // until clean geoprocess will be finished
506
                        IPipedTask cleanTask = (IPipedTask) clean.createTask();
507
                        GenerateRedNetworkAfterCleanTask task = new GenerateRedNetworkAfterCleanTask(
508
                                        netBuilder, tocLyrs);
509

    
510
                        PipeTask pipe = new PipeTask(cleanTask, (IPipedTask) task);
511

    
512
                        PluginServices.cancelableBackgroundExecution(pipe);
513
                        // PluginServices.cancelableBackgroundExecution(task);
514

    
515
                } else {
516
                        GenerateRedNetworkTask task = new GenerateRedNetworkTask(lyr,
517
                                        redFile, netBuilder);
518
                        PluginServices.cancelableBackgroundExecution(task);
519
                }
520
        }
521

    
522
        public boolean isEnabled() {
523
                return true;
524
        }
525

    
526
        public boolean isVisible() {
527
                IWindow f = PluginServices.getMDIManager().getActiveWindow();
528

    
529
                if (f == null) {
530
                        return false;
531
                }
532

    
533
                if (f instanceof View) {
534
                        View vista = (View) f;
535
                        IProjectView model = vista.getModel();
536
                        MapContext mapa = model.getMapContext();
537
                        FLayer[] activeLayers = mapa.getLayers().getActives();
538
                        if (activeLayers.length > 0)
539
                                if (activeLayers[0] instanceof FLyrVect) {
540
                                        FLyrVect lyrVect = (FLyrVect) activeLayers[0];
541
                                        int shapeType;
542
                                        try {
543
                                                if (!lyrVect.isAvailable())
544
                                                        return false;
545
                                                
546
                                                shapeType = lyrVect.getShapeType();
547
                                                if ((shapeType & FShape.LINE) == FShape.LINE)
548
                                                        // if (shapeType == FShape.LINE)
549
                                                        return true;
550
                                        } catch (BaseException e) {
551
                                                // TODO Auto-generated catch block
552
                                                e.printStackTrace();
553
                                        }
554
                                }
555
                }
556
                return false;
557

    
558
        }
559

    
560
        public IPreference[] getPreferencesPages() {
561
                return thePreferencePages;
562
        }
563

    
564
}