Statistics
| Revision:

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

History | View | Annotate | Download (16.8 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.io.File;
45
import java.util.HashMap;
46

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

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

    
59
import com.iver.andami.PluginServices;
60
import com.iver.andami.messages.NotificationManager;
61
import com.iver.andami.plugins.Extension;
62
import com.iver.andami.preferences.IPreference;
63
import com.iver.andami.preferences.IPreferenceExtension;
64
import com.iver.andami.ui.mdiManager.IWindow;
65
import com.iver.cit.gvsig.fmap.MapContext;
66
import com.iver.cit.gvsig.fmap.MapControl;
67
import com.iver.cit.gvsig.fmap.core.FShape;
68
import com.iver.cit.gvsig.fmap.drivers.SHPLayerDefinition;
69
import com.iver.cit.gvsig.fmap.edition.IWriter;
70
import com.iver.cit.gvsig.fmap.edition.ShpSchemaManager;
71
import com.iver.cit.gvsig.fmap.edition.writers.dbf.DbfWriter;
72
import com.iver.cit.gvsig.fmap.edition.writers.shp.MultiShpWriter;
73
import com.iver.cit.gvsig.fmap.edition.writers.shp.ShpWriter;
74
import com.iver.cit.gvsig.fmap.layers.FLayer;
75
import com.iver.cit.gvsig.fmap.layers.FLayers;
76
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
77
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
78
import com.iver.cit.gvsig.geoprocess.core.fmap.GeoprocessException;
79
import com.iver.cit.gvsig.geoprocess.core.fmap.XTypes;
80
import com.iver.cit.gvsig.project.documents.view.IProjectView;
81
import com.iver.cit.gvsig.project.documents.view.gui.IView;
82
import com.iver.cit.gvsig.project.documents.view.gui.View;
83
import com.iver.utiles.SimpleFileFilter;
84
import com.iver.utiles.swing.threads.AbstractMonitorableTask;
85
import com.iver.utiles.swing.threads.IPipedTask;
86
import com.iver.utiles.swing.threads.PipeTask;
87

    
88
public class GenerateNetworkExtension extends Extension implements
89
                IPreferenceExtension {
90
        private static final IPreference[] thePreferencePages = new IPreference[] { new RoutePage() };
91
        
92
        public boolean onlySnapNodes = true;
93

    
94
        private double snapTolerance;
95

    
96
        public void initialize() {
97
                PluginServices.getIconTheme().registerDefault(
98
                                "build_graph",
99
                                this.getClass().getClassLoader().getResource(
100
                                                "images/build_graph.png"));
101

    
102
                // ExtensionPoints extensionPoints =
103
                // ExtensionPointsSingleton.getInstance();
104
                // ((ExtensionPoint)
105
                // extensionPoints.get("View_TocActions")).remove("FLyrVectEditProperties");
106
                // ((ExtensionPoint)
107
                // extensionPoints.get("View_TocActions")).remove("FLyrVectEditProperties2");
108
                // ((ExtensionPoint)
109
                // extensionPoints.get("View_TocActions")).put("FLyrVectEditProperties",new
110
                // FLyrVectEditPropertiesTocMenuEntry2());
111
                // extensionPoints.add("View_TocActions","FLyrVectEditProperties2",new
112
                // FLyrVectEditPropertiesTocMenuEntry2());
113

    
114
        }
115

    
116
        public void execute(String actionCommand) {
117
                IView view = (View) PluginServices.getMDIManager().getActiveWindow();
118
                MapControl mapControl = view.getMapControl();
119
                MapContext map = mapControl.getMapContext();
120
                FLayers tocLyrs = map.getLayers();
121
                SingleLayerIterator lyrIterator = new SingleLayerIterator(tocLyrs);
122
                while (lyrIterator.hasNext()) {
123
                        FLayer lyr = lyrIterator.next();
124
                        if ((lyr.isActive()) && (lyr instanceof FLyrVect)) {
125
                                FLyrVect lyrVect = (FLyrVect) lyr;
126
                                int shapeType;
127
                                try {
128
                                        shapeType = lyrVect.getShapeType();
129
                                        if ((shapeType & FShape.LINE) == FShape.LINE) {
130
                                                if (actionCommand.equalsIgnoreCase("GENERATE_RED")) {
131
                                                        generateRedNetwork(lyrVect, tocLyrs);
132
                                                        return;
133
                                                }
134
                                        }
135
                                } catch (BaseException e) {
136
                                        e.printStackTrace();
137
                                        NotificationManager.addError(e);
138
                                }
139

    
140
                        }
141
                }
142

    
143
        }
144

    
145
        private void generateNetwork(FLyrVect lyr) {
146
                NetworkGvTableWriter netBuilder = new NetworkGvTableWriter();
147
                // Por ahora, a pelo, pero hay que sacar un cuadro
148
                // de di?logo para hecer el mapping.
149
                // Tambi?n un cuadro de di?logo para seleccionar
150
                // en qu? tablas quiere escribir, y su formato
151
                // (dbf, postgres, etc)
152
                String fieldType = "tipored";
153
                String fieldDist = "length";
154
                String fieldSense = "sen";
155
                String fieldCost = "cost";
156
                try {
157
                        netBuilder.setLayer(lyr);
158
                        netBuilder.setFieldType(fieldType);
159
                        netBuilder.setFieldDist(fieldDist);
160
                        netBuilder.setFieldSense(fieldSense);
161
                        netBuilder.setFieldCost(fieldCost);
162
                        DbfWriter nodeWriter = new DbfWriter();
163
                        nodeWriter.setFile(new File("c:/nodes.dbf"));
164

    
165
                        DbfWriter edgeWriter = new DbfWriter();
166
                        edgeWriter.setFile(new File("c:/edges.dbf"));
167

    
168
                        netBuilder.setEdgeWriter(edgeWriter);
169
                        netBuilder.setNodeWriter(nodeWriter);
170

    
171
                        netBuilder.writeNetwork();
172
                } catch (BaseException e1) {
173
                        // TODO Auto-generated catch block
174
                        e1.printStackTrace();
175
                }
176
                JOptionPane.showMessageDialog(null, PluginServices
177
                                .getText(this, "done"));
178
        }
179

    
180
        class GenerateRedNetworkAfterCleanTask extends AbstractMonitorableTask
181
                        implements IPipedTask {
182

    
183
                File redFile;
184
                NetworkFileRedWriter netBuilder;
185

    
186
                FLyrVect inputLayer;
187
                FLyrVect pseudonodes;
188
                FLayers tocLyrs;
189

    
190
                /**
191
                 * Constructor
192
                 * 
193
                 * @param tocLyrs
194
                 */
195
                GenerateRedNetworkAfterCleanTask(NetworkFileRedWriter netBuilder,
196
                                FLayers tocLyrs) {
197
                        this.netBuilder = netBuilder;
198
                        this.tocLyrs = tocLyrs;
199
                        setInitialStep(0);
200
                        setDeterminatedProcess(true);
201
                        setStatusMessage(PluginServices.getText(this,
202
                                        "Generando_red_a_partir_de_capa_lineal"));
203
                }
204

    
205
                public void run() throws Exception {
206
                        int numShapes;
207
                        try {
208
                                numShapes = inputLayer.getSource().getShapeCount();
209
                                // lo del 10 es para que termine despu?s de
210
                                // escribir los puntos
211
                                setFinalStep(numShapes + 10);
212

    
213
                        } catch (BaseException e) {
214
                                // TODO Auto-generated catch block
215
                                e.printStackTrace();
216
                        }
217
                        netBuilder.setLayer(inputLayer);
218
                        netBuilder.setCancellableMonitorable(this);
219
                        netBuilder.setRedFile(redFile);
220
                        netBuilder.writeNetwork();
221
                        tocLyrs.addLayer(inputLayer);
222
                        if (pseudonodes != null)
223
                                tocLyrs.addLayer(pseudonodes);
224
                        enableControls(inputLayer, redFile);
225
                }
226

    
227
                public String getNote() {
228
                        String processText = PluginServices.getText(this,
229
                                        "Procesando_linea");
230
                        String of = PluginServices.getText(this, "de");
231
                        return processText + " " + getCurrentStep() + " " + of + " "
232
                                        + getFinishStep();
233
                }
234

    
235
                public void cancel() {
236
                        setCanceled(true);
237
                }
238

    
239
                public boolean isFinished() {
240
                        return (getCurrentStep() >= getFinalStep());
241
                }
242

    
243
                /*
244
                 * (non-Javadoc)
245
                 * 
246
                 * @see com.iver.utiles.swing.threads.IPipedTask#getResult()
247
                 */
248
                public Object getResult() {
249
                        // TODO Auto-generated method stub
250
                        return null;
251
                }
252

    
253
                /**
254
                 * Implementation of PipeTask interface
255
                 */
256
                public void setEntry(Object object) {
257
                        // The previous task of this piped task is clean geoprocess
258
                        // whose result es FLayers with two layers
259
                        // first layer has cleaned layer
260
                        // and second layer has pseudonodes layer
261
                        if (object instanceof FLayers) {
262
                                FLayers layers = (FLayers) object;
263
                                this.inputLayer = (FLyrVect) layers.getLayer(0);
264
                                inputLayer.createSpatialIndex();
265
                                this.redFile = NetworkUtils.getNetworkFile(inputLayer);
266
                                this.pseudonodes = (FLyrVect) layers.getLayer(1);
267
                        }
268
                        else if (object instanceof FLyrVect) // no hab?a errores
269
                        {
270
                                this.inputLayer = (FLyrVect) object;
271
                                inputLayer.createSpatialIndex();
272
                                this.redFile = NetworkUtils.getNetworkFile(inputLayer);
273
                                this.pseudonodes = null;                                
274
                        }
275
                }
276
        }
277

    
278
        public void enableControls(final FLyrVect layer, final File netFile) throws BaseException {
279
                int resp = JOptionPane.showConfirmDialog((Component) PluginServices.getMDIManager().getActiveWindow(),
280
                                PluginServices.getText(null, "load_generated_network"),
281
                                PluginServices.getText(null, "Network"),
282
                                JOptionPane.YES_NO_OPTION);
283
                
284
                if (resp == JOptionPane.YES_OPTION) {
285
                        LoadDefaultNetworkExtension ext = (LoadDefaultNetworkExtension) PluginServices.getExtension(LoadDefaultNetworkExtension.class);
286
                        ext.loadNetwork(layer, netFile);
287
                }
288
                
289
                PluginServices.backgroundExecution(new Runnable() {
290
                        public void run() {
291
                                PluginServices.getMainFrame().enableControls();
292
                        }
293
                });
294
        }
295

    
296
        public class GenerateRedNetworkTask extends AbstractMonitorableTask {
297
                FLyrVect layer;
298

    
299
                File redFile;
300

    
301
                NetworkFileRedWriter netBuilder;
302

    
303
                /**
304
                 * Constructor
305
                 */
306
                public GenerateRedNetworkTask(FLyrVect layer, File redFile,
307
                                NetworkFileRedWriter netBuilder) {
308
                        this.layer = layer;
309
                        try {                        
310
//                                if (layer.isSpatiallyIndexed()) {
311
                                        layer.setISpatialIndex(NetworkUtils.createJtsQuadtree(layer));
312
//                                }
313
        
314
                                this.redFile = redFile;
315
                                this.netBuilder = netBuilder;
316
                                setInitialStep(0);
317
                                int numShapes;
318
                        
319
                                numShapes = layer.getSource().getShapeCount();
320
                                // lo del 10 es porque escribimos los nodos despu?s de
321
                                // los tramos.
322
                                setFinalStep(numShapes + 10);
323
                                setDeterminatedProcess(true);
324
                                setStatusMessage(PluginServices.getText(this,
325
                                                "Generando_red_a_partir_de_capa_lineal"));
326
                        } catch (BaseException e) {
327
                                // TODO Auto-generated catch block
328
                                e.printStackTrace();
329
                        }
330

    
331
                }
332

    
333
                public void run() throws Exception {
334
                        netBuilder.setLayer(layer);
335
                        netBuilder.setCancellableMonitorable(this);
336
                        netBuilder.setRedFile(redFile);
337
                        netBuilder.writeNetwork();
338
                        enableControls(layer, redFile);
339
                }
340

    
341
                public String getNote() {
342
                        String processText = PluginServices.getText(this,
343
                                        "Procesando_linea");
344
                        String of = PluginServices.getText(this, "de");
345
                        return processText + " " + getCurrentStep() + " " + of + " "
346
                                        + getFinishStep();
347
                }
348

    
349
                public void cancel() {
350
                        setCanceled(true);
351
                }
352

    
353
                public Object getResult() {
354
                        return null;
355

    
356
                }
357

    
358
                public void setEntry(Object object) {
359
                        this.layer = (FLyrVect) object;
360
                }
361
        }
362

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

    
436
                } catch (GeoprocessException e) {
437
                        String error = PluginServices.getText(this, "Error_ejecucion");
438
                        String errorDescription = PluginServices.getText(this,
439
                                        "Error_fallo_geoproceso");
440
                        return null;
441
                }
442

    
443
        }
444

    
445
        private void generateRedNetwork(FLyrVect lyr, FLayers tocLyrs) {
446

    
447
                NetworkFileRedWriter netBuilder = new NetworkFileRedWriter();
448
                // Por ahora, a pelo, pero hay que sacar un cuadro
449
                // de di?logo para hecer el mapping.
450
                // Tambi?n un cuadro de di?logo para seleccionar
451
                // en qu? tablas quiere escribir, y su formato
452
                // (dbf, postgres, etc)
453

    
454
                ImageIcon icon = new ImageIcon(this.getClass().getClassLoader()
455
                                .getResource("images/net-wizard-logo.jpg"));
456

    
457
                NetWizard wiz = new NetWizard(icon, lyr);
458
                PluginServices.getMDIManager().addWindow(wiz);
459
                if (!wiz.wasFinishPressed())
460
                        return;
461
                // try {
462
                String fieldType = wiz.getFieldType();
463
                String fieldLength = wiz.getFieldLength();
464
                String fieldCost = wiz.getFieldCost();
465
                String fieldSense = wiz.getFieldSense();
466

    
467
                netBuilder.setLayer(lyr);
468
                netBuilder.setFieldType(fieldType);
469
                netBuilder.setFieldDist(fieldLength);
470
                netBuilder.setFieldSense(fieldSense);
471
                netBuilder.setFieldCost(fieldCost);
472
                netBuilder.setDigitalizationDirection(wiz.getSenseDigitalization());
473
                netBuilder.setReverseDigitalizationDirection(wiz
474
                                .getSenseReverseDigitalization());
475
                File redFile = wiz.getNetworkFile();
476

    
477
                boolean applySnap = wiz.getApplySnapTolerance();
478
                if (applySnap) {
479
                        snapTolerance = wiz.getSnapTolerance();
480
                        netBuilder.setSnapTolerance(snapTolerance);
481
                }
482

    
483
                boolean cleanOrigLyr = wiz.getCleanOriginalLayer();
484
                LineSnapGeoprocess clean = null;
485
                if (cleanOrigLyr) {
486
                        clean = createCleanGeoprocess(lyr);
487
                        if (clean == null)
488
                                return;
489
                        
490
                        
491
                }
492
                if (clean != null) {
493
                        // we wont start the process of network creation
494
                        // until clean geoprocess will be finished
495
                        IPipedTask cleanTask = (IPipedTask) clean.createTask();
496
                        GenerateRedNetworkAfterCleanTask task = new GenerateRedNetworkAfterCleanTask(
497
                                        netBuilder, tocLyrs);
498

    
499
                        PipeTask pipe = new PipeTask(cleanTask, (IPipedTask) task);
500

    
501
                        PluginServices.cancelableBackgroundExecution(pipe);
502
                        // PluginServices.cancelableBackgroundExecution(task);
503

    
504
                } else {
505
                        GenerateRedNetworkTask task = new GenerateRedNetworkTask(lyr,
506
                                        redFile, netBuilder);
507
                        PluginServices.cancelableBackgroundExecution(task);
508
                }
509
        }
510

    
511
        public boolean isEnabled() {
512
                return true;
513
        }
514

    
515
        public boolean isVisible() {
516
                IWindow f = PluginServices.getMDIManager().getActiveWindow();
517

    
518
                if (f == null) {
519
                        return false;
520
                }
521

    
522
                if (f instanceof View) {
523
                        View vista = (View) f;
524
                        IProjectView model = vista.getModel();
525
                        MapContext mapa = model.getMapContext();
526
                        FLayer[] activeLayers = mapa.getLayers().getActives();
527
                        if (activeLayers.length > 0)
528
                                if (activeLayers[0] instanceof FLyrVect) {
529
                                        FLyrVect lyrVect = (FLyrVect) activeLayers[0];
530
                                        int shapeType;
531
                                        try {
532
                                                if (!lyrVect.isAvailable())
533
                                                        return false;
534
                                                
535
                                                shapeType = lyrVect.getShapeType();
536
                                                if ((shapeType & FShape.LINE) == FShape.LINE)
537
                                                        // if (shapeType == FShape.LINE)
538
                                                        return true;
539
                                        } catch (BaseException e) {
540
                                                // TODO Auto-generated catch block
541
                                                e.printStackTrace();
542
                                        }
543
                                }
544
                }
545
                return false;
546

    
547
        }
548

    
549
        public IPreference[] getPreferencesPages() {
550
                return thePreferencePages;
551
        }
552

    
553
}