Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / graph / ServiceAreaExtension.java @ 22687

History | View | Annotate | Download (12 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.wizard.servicearea.ServiceAreaWizard;
59
import org.gvsig.graph.solvers.EdgesMemoryDriver;
60
import org.gvsig.graph.solvers.OneToManySolver;
61
import org.gvsig.graph.solvers.ServiceAreaExtractor2;
62

    
63
import com.hardcode.gdbms.engine.values.DoubleValue;
64
import com.hardcode.gdbms.engine.values.ValueFactory;
65
import com.iver.andami.PluginServices;
66
import com.iver.andami.plugins.Extension;
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.core.IGeometry;
72
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
73
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
74
import com.iver.cit.gvsig.fmap.core.symbols.IFillSymbol;
75
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
76
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
77
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
78
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
79
import com.iver.cit.gvsig.fmap.layers.FLayer;
80
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
81
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
82
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
83
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
84
import com.iver.cit.gvsig.fmap.rendering.FGraphic;
85
import com.iver.cit.gvsig.fmap.rendering.FGraphicLabel;
86
import com.iver.cit.gvsig.fmap.rendering.IVectorialUniqueValueLegend;
87
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
88
import com.iver.cit.gvsig.project.documents.view.gui.View;
89

    
90
/**
91
 * @author fjp
92
 * 
93
 * Extension to perform ServiceArea calculations. Here you will find code to:
94
 * 1.- See the distances to every node on the network to one or many point
95
 * sources. 2.- TODO: Calculate a polyline layer with costs and length
96
 * calculated to nearest source point. 3.- TODO: Calculate polygons covering
97
 * those service areas.
98
 */
99
public class ServiceAreaExtension extends Extension {
100

    
101
        private int idSymbolLine = -1;
102

    
103
        public void initialize() {
104
                PluginServices.getIconTheme().registerDefault(
105
                                "service_area",
106
                                this.getClass().getClassLoader().getResource("images/service_area.png")
107
                        );
108
                
109
                PluginServices.getIconTheme().registerDefault(
110
                                "service_area_wrong_costs",
111
                                this.getClass().getClassLoader().getResource("images/service_area_wrong_costs.png"));
112
                
113
                PluginServices.getIconTheme().registerDefault(
114
                                "service_area_compact",
115
                                this.getClass().getClassLoader().getResource("images/service_area_compact.png"));
116
                
117
                PluginServices.getIconTheme().registerDefault(
118
                                "service_area_convex",
119
                                this.getClass().getClassLoader().getResource("images/service_area_convex.png"));
120
                
121
                PluginServices.getIconTheme().registerDefault(
122
                                "service_area_fusion",
123
                                this.getClass().getClassLoader().getResource("images/service_area_fusion.png"));
124
                
125
                PluginServices.getIconTheme().registerDefault(
126
                                "service_area_non_fusion",
127
                                this.getClass().getClassLoader().getResource("images/service_area_non_fusion.png"));
128
                
129
                PluginServices.getIconTheme().registerDefault(
130
                                "service_area_disks",
131
                                this.getClass().getClassLoader().getResource("images/service_area_disks.png"));
132
                
133
                PluginServices.getIconTheme().registerDefault(
134
                                "service_area_rings",
135
                                this.getClass().getClassLoader().getResource("images/service_area_rings.png"));
136
        }
137

    
138
        public void execute(String actionCommand) {
139

    
140
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
141
                MapControl mapCtrl = v.getMapControl();
142
                MapContext map = mapCtrl.getMapContext();
143
                SingleLayerIterator it = new SingleLayerIterator(map.getLayers());                
144
                while (it.hasNext()) {
145
                        FLayer aux = it.next();
146
                        if (!aux.isActive())
147
                                continue;
148
                        Network net = (Network) aux.getProperty("network");
149

    
150
                        if (net != null) {
151
                                GvFlag[] flags = net.getFlags();
152
                                if (flags.length == 0) {
153
                                        JOptionPane.showMessageDialog(null,
154
                                                        "Primero carga las paradas.");
155
                                        return;
156
                                }
157
//                                        setVelocities(net);
158
                                try {
159
                                        OneToManySolver solver = new OneToManySolver();
160
                                        solver.setNetwork(net);
161
                                        solver.putDestinationsOnNetwork();
162
                                        if (actionCommand.equals("LABEL_NODE_DISTANCES")) {
163
                                                calculateLabels(mapCtrl, map, net, flags, solver);
164
                                        }
165
                                        if (actionCommand.equals("SERVICE_AREA")) {
166
                                                calculateServiceArea(map, net, flags, solver);
167
                                        }
168
                                        if(actionCommand.equals("PRUEBA_WIZARD_SERVICE_AREA")){
169
                                                ImageIcon icon = new ImageIcon(this.getClass().getClassLoader()
170
                                                                .getResource("images/service_area-wizard-logo.jpg"));
171
                                                ServiceAreaWizard wiz=new ServiceAreaWizard(icon, null);
172
                                                PluginServices.getMDIManager().addWindow(wiz);
173
                                        }
174
                                        solver.removeDestinationsFromNetwork();
175
                                } catch (BaseException e) {
176
                                        // TODO Auto-generated catch block
177
                                        e.printStackTrace();
178
                                }
179

    
180
                                return;
181
                        }
182
                }
183

    
184
        }
185

    
186
        /**
187
         * @param mapCtrl
188
         * @param map
189
         * @param net
190
         * @param flags
191
         * @param solver
192
         * @return
193
         * @throws GraphException
194
         */
195
        private void calculateLabels(MapControl mapCtrl, MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws GraphException {
196
                GraphicLayer graphicLayer = mapCtrl.getMapContext()
197
                                .getGraphicsLayer();
198
                removeOldLabels(graphicLayer);
199
                for (int i = 0; i < flags.length; i++) {
200

    
201
                        solver.setSourceFlag(flags[i]);
202
                        long t1 = System.currentTimeMillis();
203
                        solver.setExploreAllNetwork(true);
204
                        solver.calculate();
205
                        long t2 = System.currentTimeMillis();
206
                        System.out.println("Punto " + i + " de "
207
                                        + flags.length + ". " + (t2 - t1)
208
                                        + " msecs.");
209
                        // Despu?s de esto, los nodos de la red est?n
210
                        // etiquetados con los costes al nodo or?gen
211
                        EdgesMemoryDriver driver = new EdgesMemoryDriver(net);
212
                        FLayer lyr = LayerFactory.createLayer("Edges", driver, null);
213
                        map.getLayers().addLayer(lyr);
214
                        // doLabeling(mapCtrl, net, flags[i]);
215

    
216
                }
217
        
218
        }
219

    
220
        private void calculateServiceArea(MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws BaseException {
221
                ServiceAreaExtractor2 extractor = new ServiceAreaExtractor2(net);
222
                String aux = JOptionPane.showInputDialog("Por favor, introduzca el coste m?ximo del ?rea de servicio:");
223
                if (aux == null)
224
                        return;
225
                double[] costs = NetworkUtils.string2doubleArray(aux, ",");
226
                Arrays.sort(costs);
227
                solver.addListener(extractor);
228
                for (int i = 0; i < flags.length; i++) {
229
                        solver.setSourceFlag(flags[i]);
230
                        long t1 = System.currentTimeMillis();                        
231
                        solver.setExploreAllNetwork(true);
232
                        // TODO: El coste m?ximo deber?a ser un array de costes m?ximos
233
                        // para obtener varios pol?gonos por cada intervalo. Y 2 opciones m?s:
234
                        // Si se desea ?rea compacta y
235
                        // Si los pol?gonos se quieren como anillos conc?ntricos.
236
                        // Cada Flag deber?a tener asociado un array de costes m?ximos o distancias
237
                        solver.setMaxCost(costs[costs.length -1]);
238
                        extractor.setIdFlag(i);
239
                        extractor.setCosts(costs);
240
                        
241
                        extractor.setDoCompactArea(true);
242
                        
243
                        solver.calculate();
244
                        long t2 = System.currentTimeMillis();
245
                        System.out.println("Punto " + i + " de "
246
                                        + flags.length + ". " + (t2 - t1)
247
                                        + " msecs.");
248
                        extractor.writeServiceArea();
249
                                                
250
                }
251
                extractor.closeFiles();
252
                FLyrVect lyrPol = extractor.getPolygonLayer();
253
                lyrPol.setProjection(map.getProjection());
254
                IVectorialUniqueValueLegend defaultLegend = LegendFactory.createVectorialUniqueValueLegend(FShape.POLYGON);
255
                defaultLegend.setClassifyingFieldNames(new String[] {"COST"} );
256
                ISymbol myDefaultSymbol = SymbologyFactory.
257
                        createDefaultSymbolByShapeType(FShape.POLYGON);
258

    
259
                defaultLegend.setDefaultSymbol(myDefaultSymbol);
260

    
261
                DoubleValue clave;
262
                IFillSymbol theSymbol = null;
263
                Random rnd = new Random(System.currentTimeMillis());
264

    
265
                for (int j = 0; j < costs.length; j++) {
266
                        clave = ValueFactory.createValue(costs[j]);
267
                        if (defaultLegend.getSymbolByValue(clave) == null) {
268
                                theSymbol =        (IFillSymbol) SymbologyFactory.
269
                                        createDefaultSymbolByShapeType(FShape.POLYGON);
270
                                theSymbol.setDescription(clave.toString());
271
                                Color newColor = new Color(rnd.nextFloat(), 
272
                                                rnd.nextFloat(),
273
                                                rnd.nextFloat(), 0.7f);
274
                                theSymbol.setFillColor(newColor);
275

    
276
                                defaultLegend.addSymbol(clave, theSymbol);
277
                        }
278

    
279
                } // for
280
                lyrPol.setLegend(defaultLegend);
281
                
282
                FLyrVect lyrLine = extractor.getLineLayer();
283
                lyrLine.setProjection(map.getProjection());
284
                map.beginAtomicEvent();
285
                map.getLayers().addLayer(lyrPol);
286
                map.getLayers().addLayer(lyrLine);
287
                map.endAtomicEvent();
288

    
289
        
290
        }
291
        
292
        private FSymbol getTextSymbol() {
293
                FSymbol theSymbol = new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
294
                theSymbol.setColor(Color.RED);
295
                theSymbol.setStyle(FConstant.SYMBOL_STYLE_MARKER_CIRCLE);
296
                theSymbol.setFontColor(Color.BLACK);
297
                theSymbol.setSizeInPixels(true);
298
                theSymbol.setSize(9);
299
                return theSymbol;
300
        }
301

    
302
        private void removeOldLabels(GraphicLayer gLyr) {
303
                for (int i = gLyr.getNumGraphics() - 1; i >= 0; i--) {
304
                        FGraphic gr = gLyr.getGraphic(i);
305
                        if (gr.equals("N"))
306
                                gLyr.removeGraphic(i);
307

    
308
                }
309
        }
310

    
311
        private void doLabeling(MapControl mapControl, Network net, GvFlag flag) {
312
                GraphicLayer graphicLayer = mapControl.getMapContext()
313
                                .getGraphicsLayer();
314
                IGraph g = net.getGraph();
315
                int idSymbol = graphicLayer.addSymbol(getTextSymbol());
316
                String tag = "N";
317
                for (int i = 0; i < g.numVertices(); i++) {
318
                        GvNode node = g.getNodeByID(i);
319
                        IGeometry geom = ShapeFactory.createPoint2D(node.getX(), node
320
                                        .getY());
321
                        NumberFormat nf = NumberFormat.getInstance();
322
                        nf.setMaximumFractionDigits(1);
323
                        String aux = "\u221E"; // infinito
324
                        if (node.getBestCost() < Double.MAX_VALUE)
325
                                aux = nf.format(node.getBestCost()) + " - " + nf.format(node.getAccumulatedLength());
326
                        FGraphicLabel theGLabel = new FGraphicLabel(geom, idSymbol, aux);
327
                        theGLabel.setObjectTag(tag);
328
                        theGLabel.getLabel().setJustification(FLabel.CENTER_TOP);
329
                        graphicLayer.addGraphic(theGLabel);
330
                }
331
                mapControl.drawGraphics();
332

    
333
        }
334

    
335
        public boolean isEnabled() {
336
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
337
                if (window instanceof View)
338
                {
339
                        View v = (View) window;
340
                MapControl mapCtrl = v.getMapControl();
341
                        MapContext map = mapCtrl.getMapContext();
342
                        
343
                        SingleLayerIterator it = new SingleLayerIterator(map.getLayers());
344
                        while (it.hasNext())
345
                        {
346
                                FLayer aux = it.next();
347
                                if (!aux.isActive())
348
                                        continue;
349
                                Network net = (Network) aux.getProperty("network");
350
                                
351
                                if ( net != null)
352
                                {
353
                                        return true;
354
                                }
355
                        }
356
                }
357
                return false;
358
        }
359

    
360
        public boolean isVisible() {
361
                IWindow f = PluginServices.getMDIManager()
362
                 .getActiveWindow();
363
                if (f == null) {
364
                    return false;
365
                }
366
                if (f instanceof View) {
367
                        return true;
368
                }
369
                return false;
370

    
371
        }
372

    
373
}