Statistics
| Revision:

root / trunk / extensions / extGraph / src / org / gvsig / graph / ConnectivityExtension.java @ 29993

History | View | Annotate | Download (11.4 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.Color;
44
import java.text.NumberFormat;
45
import java.util.Arrays;
46
import java.util.Random;
47

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

    
51
import org.gvsig.exceptions.BaseException;
52
import org.gvsig.graph.core.GraphException;
53
import org.gvsig.graph.core.GvFlag;
54
import org.gvsig.graph.core.GvNode;
55
import org.gvsig.graph.core.IGraph;
56
import org.gvsig.graph.core.Network;
57
import org.gvsig.graph.core.NetworkUtils;
58
import org.gvsig.graph.gui.ConnectivityControlPanel;
59
import org.gvsig.graph.gui.wizard.servicearea.ServiceAreaWizard;
60
import org.gvsig.graph.solvers.EdgesMemoryDriver;
61
import org.gvsig.graph.solvers.OneToManySolver;
62
import org.gvsig.graph.solvers.ServiceAreaExtractor;
63
import org.gvsig.graph.solvers.ServiceAreaExtractor2;
64

    
65
import com.hardcode.gdbms.driver.exceptions.ReadDriverException;
66
import com.hardcode.gdbms.engine.values.DoubleValue;
67
import com.hardcode.gdbms.engine.values.ValueFactory;
68
import com.iver.andami.PluginServices;
69
import com.iver.andami.plugins.Extension;
70
import com.iver.andami.ui.mdiManager.IWindow;
71
import com.iver.cit.gvsig.fmap.MapContext;
72
import com.iver.cit.gvsig.fmap.MapControl;
73
import com.iver.cit.gvsig.fmap.core.FShape;
74
import com.iver.cit.gvsig.fmap.core.IGeometry;
75
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
76
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
77
import com.iver.cit.gvsig.fmap.core.symbols.IFillSymbol;
78
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
79
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
80
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
81
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
82
import com.iver.cit.gvsig.fmap.layers.FLayer;
83
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
84
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
85
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
86
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
87
import com.iver.cit.gvsig.fmap.rendering.FGraphic;
88
import com.iver.cit.gvsig.fmap.rendering.FGraphicLabel;
89
import com.iver.cit.gvsig.fmap.rendering.IVectorialUniqueValueLegend;
90
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
91
import com.iver.cit.gvsig.project.documents.view.gui.View;
92

    
93
/**
94
 * @author fjp
95
 * 
96
 * Extension to perform Connectivity calculations. 
97
 * The user can put a flag and select a point associated layer, and set
98
 * if he wants to use a max cost and/or max distance.
99
 * The algorithm will explore the network in reverse order or in normal order and
100
 * the arcs reached will be selected. If the user selects an associated layer, the
101
 * points reached will be selected also.
102
 * This may be useful in the following situations:
103
 * 1.- Searching for connectivity. The unconnected parts of the network will be unselected.
104
 * 2.- Selecting points connected to the network and affected by a cut in the graph
105
 * 3.- Using reverse order, you may find the closest valve to close and avoid leaks.
106
 */
107
public class ConnectivityExtension extends Extension {
108

    
109
        private int idSymbolLine = -1;
110

    
111
        public void initialize() {
112
                PluginServices.getIconTheme().registerDefault(
113
                                "connectivity",
114
                                this.getClass().getClassLoader().getResource("images/connectivity.gif")
115
                        );
116
                
117
        }
118

    
119
        public void execute(String actionCommand) {
120

    
121
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
122
                MapControl mapCtrl = v.getMapControl();
123
                MapContext map = mapCtrl.getMapContext();
124
                SingleLayerIterator it = new SingleLayerIterator(map.getLayers());                
125
                while (it.hasNext()) {
126
                        FLayer aux = it.next();
127
                        if (!aux.isActive())
128
                                continue;
129
                        Network net = (Network) aux.getProperty("network");
130

    
131
                        if (net != null) {
132
                                if(actionCommand.equals("CONNECTIVITY")){
133
                                        ImageIcon icon = new ImageIcon(this.getClass().getClassLoader()
134
                                                        .getResource("images/wizard_connectivity.png"));
135
                                        ConnectivityControlPanel w =new ConnectivityControlPanel();
136
                                        try {
137
                                                w.setMapControl(mapCtrl);
138
                                                PluginServices.getMDIManager().addWindow(w);                                                
139
                                        } catch (ReadDriverException e) {
140
                                                // TODO Auto-generated catch block
141
                                                e.printStackTrace();
142
                                        }
143
                                        
144
                                }
145
                                return;
146
                        }
147
                }
148

    
149
        }
150

    
151
        /**
152
         * @param mapCtrl
153
         * @param map
154
         * @param net
155
         * @param flags
156
         * @param solver
157
         * @return
158
         * @throws GraphException
159
         */
160
        private void calculateLabels(MapControl mapCtrl, MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws GraphException {
161
                GraphicLayer graphicLayer = mapCtrl.getMapContext()
162
                                .getGraphicsLayer();
163
                removeOldLabels(graphicLayer);
164
                for (int i = 0; i < flags.length; i++) {
165

    
166
                        solver.setSourceFlag(flags[i]);
167
                        long t1 = System.currentTimeMillis();
168
                        solver.setExploreAllNetwork(true);
169
                        solver.calculate();
170
                        long t2 = System.currentTimeMillis();
171
                        System.out.println("Punto " + i + " de "
172
                                        + flags.length + ". " + (t2 - t1)
173
                                        + " msecs.");
174
                        // Despu?s de esto, los nodos de la red est?n
175
                        // etiquetados con los costes al nodo or?gen
176
                        EdgesMemoryDriver driver = new EdgesMemoryDriver(net);
177
                        FLayer lyr = LayerFactory.createLayer("Edges", driver, null);
178
                        map.getLayers().addLayer(lyr);
179
                        // doLabeling(mapCtrl, net, flags[i]);
180

    
181
                }
182
        
183
        }
184

    
185
        private void calculateServiceArea(MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws BaseException {
186
                ServiceAreaExtractor2 extractor = new ServiceAreaExtractor2(net);
187
                String aux = JOptionPane.showInputDialog("Por favor, introduzca el coste m?ximo del ?rea de servicio:");
188
                if (aux == null)
189
                        return;
190
                double[] costs = NetworkUtils.string2doubleArray(aux, ",");
191
                Arrays.sort(costs);
192
                solver.addListener(extractor);
193
                for (int i = 0; i < flags.length; i++) {
194
                        solver.setSourceFlag(flags[i]);
195
                        long t1 = System.currentTimeMillis();                        
196
                        solver.setExploreAllNetwork(true);
197
                        // TODO: El coste m?ximo deber?a ser un array de costes m?ximos
198
                        // para obtener varios pol?gonos por cada intervalo. Y 2 opciones m?s:
199
                        // Si se desea ?rea compacta y
200
                        // Si los pol?gonos se quieren como anillos conc?ntricos.
201
                        // Cada Flag deber?a tener asociado un array de costes m?ximos o distancias
202
                        solver.setMaxCost(costs[costs.length -1]);
203
                        extractor.setIdFlag(i);
204
                        extractor.setCosts(costs);
205
                        
206
                        extractor.setDoCompactArea(true);
207
                        
208
                        solver.calculate();
209
                        long t2 = System.currentTimeMillis();
210
                        System.out.println("Punto " + i + " de "
211
                                        + flags.length + ". " + (t2 - t1)
212
                                        + " msecs.");
213
                        extractor.writeServiceArea();
214
                                                
215
                }
216
                extractor.closeFiles();
217
                FLyrVect lyrPol = extractor.getPolygonLayer();
218
                lyrPol.setProjection(map.getProjection());
219
                IVectorialUniqueValueLegend defaultLegend = LegendFactory.createVectorialUniqueValueLegend(FShape.POLYGON);
220
                defaultLegend.setClassifyingFieldNames(new String[] {"COST"} );
221
                ISymbol myDefaultSymbol = SymbologyFactory.
222
                        createDefaultSymbolByShapeType(FShape.POLYGON);
223

    
224
                defaultLegend.setDefaultSymbol(myDefaultSymbol);
225

    
226
                DoubleValue clave;
227
                IFillSymbol theSymbol = null;
228
                Random rnd = new Random(System.currentTimeMillis());
229

    
230
                for (int j = 0; j < costs.length; j++) {
231
                        clave = ValueFactory.createValue(costs[j]);
232
                        if (defaultLegend.getSymbolByValue(clave) == null) {
233
                                theSymbol =        (IFillSymbol) SymbologyFactory.
234
                                        createDefaultSymbolByShapeType(FShape.POLYGON);
235
                                theSymbol.setDescription(clave.toString());
236
                                Color newColor = new Color(rnd.nextFloat(), 
237
                                                rnd.nextFloat(),
238
                                                rnd.nextFloat(), 0.7f);
239
                                theSymbol.setFillColor(newColor);
240

    
241
                                defaultLegend.addSymbol(clave, theSymbol);
242
                        }
243

    
244
                } // for
245
                lyrPol.setLegend(defaultLegend);
246
                
247
                FLyrVect lyrLine = extractor.getLineLayer();
248
                lyrLine.setProjection(map.getProjection());
249

    
250
                // provisional
251
                FLyrVect lyrPoints= extractor.getBorderPoints();
252
                lyrPoints.setProjection(map.getProjection());
253
                
254
                map.beginAtomicEvent();
255
                map.getLayers().addLayer(lyrPol);
256
                map.getLayers().addLayer(lyrLine);
257
                map.getLayers().addLayer(lyrPoints);
258
                map.endAtomicEvent();
259

    
260
        
261
        }
262
        
263
        private FSymbol getTextSymbol() {
264
                FSymbol theSymbol = new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
265
                theSymbol.setColor(Color.RED);
266
                theSymbol.setStyle(FConstant.SYMBOL_STYLE_MARKER_CIRCLE);
267
                theSymbol.setFontColor(Color.BLACK);
268
                theSymbol.setSizeInPixels(true);
269
                theSymbol.setSize(9);
270
                return theSymbol;
271
        }
272

    
273
        private void removeOldLabels(GraphicLayer gLyr) {
274
                for (int i = gLyr.getNumGraphics() - 1; i >= 0; i--) {
275
                        FGraphic gr = gLyr.getGraphic(i);
276
                        if (gr.equals("N"))
277
                                gLyr.removeGraphic(i);
278

    
279
                }
280
        }
281

    
282
        private void doLabeling(MapControl mapControl, Network net, GvFlag flag) {
283
                GraphicLayer graphicLayer = mapControl.getMapContext()
284
                                .getGraphicsLayer();
285
                IGraph g = net.getGraph();
286
                int idSymbol = graphicLayer.addSymbol(getTextSymbol());
287
                String tag = "N";
288
                for (int i = 0; i < g.numVertices(); i++) {
289
                        GvNode node = g.getNodeByID(i);
290
                        IGeometry geom = ShapeFactory.createPoint2D(node.getX(), node
291
                                        .getY());
292
                        NumberFormat nf = NumberFormat.getInstance();
293
                        nf.setMaximumFractionDigits(1);
294
                        String aux = "\u221E"; // infinito
295
                        if (node.getBestCost() < Double.MAX_VALUE)
296
                                aux = nf.format(node.getBestCost()) + " - " + nf.format(node.getAccumulatedLength());
297
                        FGraphicLabel theGLabel = new FGraphicLabel(geom, idSymbol, aux);
298
                        theGLabel.setObjectTag(tag);
299
                        theGLabel.getLabel().setJustification(FLabel.CENTER_TOP);
300
                        graphicLayer.addGraphic(theGLabel);
301
                }
302
                mapControl.drawGraphics();
303

    
304
        }
305

    
306
        public boolean isEnabled() {
307
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
308
                if (window instanceof View)
309
                {
310
                        View v = (View) window;
311
                MapControl mapCtrl = v.getMapControl();
312
                        MapContext map = mapCtrl.getMapContext();
313
                        
314
                        SingleLayerIterator it = new SingleLayerIterator(map.getLayers());
315
                        while (it.hasNext())
316
                        {
317
                                FLayer aux = it.next();
318
                                if (!aux.isActive())
319
                                        continue;
320
                                Network net = (Network) aux.getProperty("network");
321
                                
322
                                if ( net != null)
323
                                {
324
                                        return true;
325
                                }
326
                        }
327
                }
328
                return false;
329
        }
330

    
331
        public boolean isVisible() {
332
                IWindow f = PluginServices.getMDIManager()
333
                 .getActiveWindow();
334
                if (f == null) {
335
                    return false;
336
                }
337
                if (f instanceof View) {
338
                        return true;
339
                }
340
                return false;
341

    
342
        }
343

    
344
}