Statistics
| Revision:

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

History | View | Annotate | Download (12.3 KB)

1 13583 fjp
/* 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 22182 fpenarrubia
package org.gvsig.graph;
42 13583 fjp
43
import java.awt.Color;
44
import java.text.NumberFormat;
45 14712 fpenarrubia
import java.util.Arrays;
46 15909 fpenarrubia
import java.util.Random;
47 13583 fjp
48 17628 falario
import javax.swing.ImageIcon;
49 13583 fjp
import javax.swing.JOptionPane;
50
51 14459 fpenarrubia
import org.gvsig.exceptions.BaseException;
52 22182 fpenarrubia
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 25359 fpenarrubia
import org.gvsig.graph.solvers.ServiceAreaExtractor;
62 22182 fpenarrubia
import org.gvsig.graph.solvers.ServiceAreaExtractor2;
63 14459 fpenarrubia
64 15909 fpenarrubia
import com.hardcode.gdbms.engine.values.DoubleValue;
65
import com.hardcode.gdbms.engine.values.ValueFactory;
66 13583 fjp
import com.iver.andami.PluginServices;
67
import com.iver.andami.plugins.Extension;
68
import com.iver.andami.ui.mdiManager.IWindow;
69
import com.iver.cit.gvsig.fmap.MapContext;
70
import com.iver.cit.gvsig.fmap.MapControl;
71 15909 fpenarrubia
import com.iver.cit.gvsig.fmap.core.FShape;
72 13583 fjp
import com.iver.cit.gvsig.fmap.core.IGeometry;
73
import com.iver.cit.gvsig.fmap.core.ShapeFactory;
74 15909 fpenarrubia
import com.iver.cit.gvsig.fmap.core.SymbologyFactory;
75
import com.iver.cit.gvsig.fmap.core.symbols.IFillSymbol;
76
import com.iver.cit.gvsig.fmap.core.symbols.ISymbol;
77 13583 fjp
import com.iver.cit.gvsig.fmap.core.v02.FConstant;
78
import com.iver.cit.gvsig.fmap.core.v02.FLabel;
79
import com.iver.cit.gvsig.fmap.core.v02.FSymbol;
80
import com.iver.cit.gvsig.fmap.layers.FLayer;
81 14459 fpenarrubia
import com.iver.cit.gvsig.fmap.layers.FLyrVect;
82 13583 fjp
import com.iver.cit.gvsig.fmap.layers.GraphicLayer;
83
import com.iver.cit.gvsig.fmap.layers.LayerFactory;
84
import com.iver.cit.gvsig.fmap.layers.SingleLayerIterator;
85
import com.iver.cit.gvsig.fmap.rendering.FGraphic;
86
import com.iver.cit.gvsig.fmap.rendering.FGraphicLabel;
87 15909 fpenarrubia
import com.iver.cit.gvsig.fmap.rendering.IVectorialUniqueValueLegend;
88
import com.iver.cit.gvsig.fmap.rendering.LegendFactory;
89 13583 fjp
import com.iver.cit.gvsig.project.documents.view.gui.View;
90
91
/**
92
 * @author fjp
93
 *
94
 * Extension to perform ServiceArea calculations. Here you will find code to:
95
 * 1.- See the distances to every node on the network to one or many point
96
 * sources. 2.- TODO: Calculate a polyline layer with costs and length
97
 * calculated to nearest source point. 3.- TODO: Calculate polygons covering
98
 * those service areas.
99
 */
100
public class ServiceAreaExtension extends Extension {
101
102
        private int idSymbolLine = -1;
103
104
        public void initialize() {
105 15909 fpenarrubia
                PluginServices.getIconTheme().registerDefault(
106
                                "service_area",
107
                                this.getClass().getClassLoader().getResource("images/service_area.png")
108 17628 falario
                        );
109 15909 fpenarrubia
110 17628 falario
                PluginServices.getIconTheme().registerDefault(
111
                                "service_area_wrong_costs",
112
                                this.getClass().getClassLoader().getResource("images/service_area_wrong_costs.png"));
113
114
                PluginServices.getIconTheme().registerDefault(
115
                                "service_area_compact",
116
                                this.getClass().getClassLoader().getResource("images/service_area_compact.png"));
117
118
                PluginServices.getIconTheme().registerDefault(
119
                                "service_area_convex",
120
                                this.getClass().getClassLoader().getResource("images/service_area_convex.png"));
121
122
                PluginServices.getIconTheme().registerDefault(
123
                                "service_area_fusion",
124
                                this.getClass().getClassLoader().getResource("images/service_area_fusion.png"));
125
126
                PluginServices.getIconTheme().registerDefault(
127
                                "service_area_non_fusion",
128
                                this.getClass().getClassLoader().getResource("images/service_area_non_fusion.png"));
129
130
                PluginServices.getIconTheme().registerDefault(
131
                                "service_area_disks",
132
                                this.getClass().getClassLoader().getResource("images/service_area_disks.png"));
133
134
                PluginServices.getIconTheme().registerDefault(
135
                                "service_area_rings",
136
                                this.getClass().getClassLoader().getResource("images/service_area_rings.png"));
137 13583 fjp
        }
138
139
        public void execute(String actionCommand) {
140
141
                View v = (View) PluginServices.getMDIManager().getActiveWindow();
142
                MapControl mapCtrl = v.getMapControl();
143
                MapContext map = mapCtrl.getMapContext();
144 14459 fpenarrubia
                SingleLayerIterator it = new SingleLayerIterator(map.getLayers());
145
                while (it.hasNext()) {
146
                        FLayer aux = it.next();
147
                        if (!aux.isActive())
148
                                continue;
149
                        Network net = (Network) aux.getProperty("network");
150 13583 fjp
151 14459 fpenarrubia
                        if (net != null) {
152
                                GvFlag[] flags = net.getFlags();
153
                                if (flags.length == 0) {
154
                                        JOptionPane.showMessageDialog(null,
155
                                                        "Primero carga las paradas.");
156
                                        return;
157
                                }
158
//                                        setVelocities(net);
159
                                try {
160
                                        OneToManySolver solver = new OneToManySolver();
161
                                        solver.setNetwork(net);
162 24380 fpenarrubia
                                        solver.putDestinationsOnNetwork(net.getFlags());
163 14459 fpenarrubia
                                        if (actionCommand.equals("LABEL_NODE_DISTANCES")) {
164
                                                calculateLabels(mapCtrl, map, net, flags, solver);
165 13583 fjp
                                        }
166 14459 fpenarrubia
                                        if (actionCommand.equals("SERVICE_AREA")) {
167
                                                calculateServiceArea(map, net, flags, solver);
168 17628 falario
                                        }
169
                                        if(actionCommand.equals("PRUEBA_WIZARD_SERVICE_AREA")){
170
                                                ImageIcon icon = new ImageIcon(this.getClass().getClassLoader()
171
                                                                .getResource("images/service_area-wizard-logo.jpg"));
172
                                                ServiceAreaWizard wiz=new ServiceAreaWizard(icon, null);
173
                                                PluginServices.getMDIManager().addWindow(wiz);
174
                                        }
175 24380 fpenarrubia
                                        solver.removeDestinationsFromNetwork(net.getFlags());
176 14459 fpenarrubia
                                } catch (BaseException e) {
177
                                        // TODO Auto-generated catch block
178
                                        e.printStackTrace();
179
                                }
180 13583 fjp
181 14459 fpenarrubia
                                return;
182
                        }
183
                }
184 13583 fjp
185 14459 fpenarrubia
        }
186 13583 fjp
187 14459 fpenarrubia
        /**
188
         * @param mapCtrl
189
         * @param map
190
         * @param net
191
         * @param flags
192
         * @param solver
193
         * @return
194
         * @throws GraphException
195
         */
196
        private void calculateLabels(MapControl mapCtrl, MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws GraphException {
197
                GraphicLayer graphicLayer = mapCtrl.getMapContext()
198
                                .getGraphicsLayer();
199
                removeOldLabels(graphicLayer);
200
                for (int i = 0; i < flags.length; i++) {
201 13583 fjp
202 14459 fpenarrubia
                        solver.setSourceFlag(flags[i]);
203
                        long t1 = System.currentTimeMillis();
204
                        solver.setExploreAllNetwork(true);
205
                        solver.calculate();
206
                        long t2 = System.currentTimeMillis();
207
                        System.out.println("Punto " + i + " de "
208
                                        + flags.length + ". " + (t2 - t1)
209
                                        + " msecs.");
210
                        // Despu?s de esto, los nodos de la red est?n
211
                        // etiquetados con los costes al nodo or?gen
212
                        EdgesMemoryDriver driver = new EdgesMemoryDriver(net);
213
                        FLayer lyr = LayerFactory.createLayer("Edges", driver, null);
214
                        map.getLayers().addLayer(lyr);
215
                        // doLabeling(mapCtrl, net, flags[i]);
216
217 13583 fjp
                }
218 14459 fpenarrubia
219
        }
220 13583 fjp
221 14459 fpenarrubia
        private void calculateServiceArea(MapContext map, Network net, GvFlag[] flags, OneToManySolver solver) throws BaseException {
222 15509 fpenarrubia
                ServiceAreaExtractor2 extractor = new ServiceAreaExtractor2(net);
223 14459 fpenarrubia
                String aux = JOptionPane.showInputDialog("Por favor, introduzca el coste m?ximo del ?rea de servicio:");
224
                if (aux == null)
225
                        return;
226 14712 fpenarrubia
                double[] costs = NetworkUtils.string2doubleArray(aux, ",");
227
                Arrays.sort(costs);
228 15509 fpenarrubia
                solver.addListener(extractor);
229 14459 fpenarrubia
                for (int i = 0; i < flags.length; i++) {
230
                        solver.setSourceFlag(flags[i]);
231
                        long t1 = System.currentTimeMillis();
232
                        solver.setExploreAllNetwork(true);
233
                        // TODO: El coste m?ximo deber?a ser un array de costes m?ximos
234
                        // para obtener varios pol?gonos por cada intervalo. Y 2 opciones m?s:
235
                        // Si se desea ?rea compacta y
236
                        // Si los pol?gonos se quieren como anillos conc?ntricos.
237
                        // Cada Flag deber?a tener asociado un array de costes m?ximos o distancias
238 14712 fpenarrubia
                        solver.setMaxCost(costs[costs.length -1]);
239 15509 fpenarrubia
                        extractor.setIdFlag(i);
240
                        extractor.setCosts(costs);
241 22687 fpenarrubia
242 26237 fpenarrubia
                        extractor.setDoCompactArea(true);
243 22687 fpenarrubia
244 14459 fpenarrubia
                        solver.calculate();
245
                        long t2 = System.currentTimeMillis();
246
                        System.out.println("Punto " + i + " de "
247
                                        + flags.length + ". " + (t2 - t1)
248
                                        + " msecs.");
249 15509 fpenarrubia
                        extractor.writeServiceArea();
250
251 14459 fpenarrubia
                }
252 15509 fpenarrubia
                extractor.closeFiles();
253 14712 fpenarrubia
                FLyrVect lyrPol = extractor.getPolygonLayer();
254
                lyrPol.setProjection(map.getProjection());
255 15909 fpenarrubia
                IVectorialUniqueValueLegend defaultLegend = LegendFactory.createVectorialUniqueValueLegend(FShape.POLYGON);
256
                defaultLegend.setClassifyingFieldNames(new String[] {"COST"} );
257
                ISymbol myDefaultSymbol = SymbologyFactory.
258
                        createDefaultSymbolByShapeType(FShape.POLYGON);
259
260
                defaultLegend.setDefaultSymbol(myDefaultSymbol);
261
262
                DoubleValue clave;
263
                IFillSymbol theSymbol = null;
264
                Random rnd = new Random(System.currentTimeMillis());
265
266
                for (int j = 0; j < costs.length; j++) {
267
                        clave = ValueFactory.createValue(costs[j]);
268
                        if (defaultLegend.getSymbolByValue(clave) == null) {
269
                                theSymbol =        (IFillSymbol) SymbologyFactory.
270
                                        createDefaultSymbolByShapeType(FShape.POLYGON);
271
                                theSymbol.setDescription(clave.toString());
272
                                Color newColor = new Color(rnd.nextFloat(),
273
                                                rnd.nextFloat(),
274
                                                rnd.nextFloat(), 0.7f);
275
                                theSymbol.setFillColor(newColor);
276
277
                                defaultLegend.addSymbol(clave, theSymbol);
278
                        }
279
280
                } // for
281
                lyrPol.setLegend(defaultLegend);
282
283 14712 fpenarrubia
                FLyrVect lyrLine = extractor.getLineLayer();
284
                lyrLine.setProjection(map.getProjection());
285 25434 fpenarrubia
286
                // provisional
287
                FLyrVect lyrPoints= extractor.getBorderPoints();
288
                lyrPoints.setProjection(map.getProjection());
289
290 14712 fpenarrubia
                map.beginAtomicEvent();
291
                map.getLayers().addLayer(lyrPol);
292
                map.getLayers().addLayer(lyrLine);
293 25434 fpenarrubia
                map.getLayers().addLayer(lyrPoints);
294 14712 fpenarrubia
                map.endAtomicEvent();
295
296 14459 fpenarrubia
297 13583 fjp
        }
298 14459 fpenarrubia
299 13583 fjp
        private FSymbol getTextSymbol() {
300
                FSymbol theSymbol = new FSymbol(FConstant.SYMBOL_TYPE_TEXT);
301
                theSymbol.setColor(Color.RED);
302
                theSymbol.setStyle(FConstant.SYMBOL_STYLE_MARKER_CIRCLE);
303
                theSymbol.setFontColor(Color.BLACK);
304
                theSymbol.setSizeInPixels(true);
305
                theSymbol.setSize(9);
306
                return theSymbol;
307
        }
308
309
        private void removeOldLabels(GraphicLayer gLyr) {
310
                for (int i = gLyr.getNumGraphics() - 1; i >= 0; i--) {
311
                        FGraphic gr = gLyr.getGraphic(i);
312
                        if (gr.equals("N"))
313
                                gLyr.removeGraphic(i);
314
315
                }
316
        }
317
318
        private void doLabeling(MapControl mapControl, Network net, GvFlag flag) {
319
                GraphicLayer graphicLayer = mapControl.getMapContext()
320
                                .getGraphicsLayer();
321
                IGraph g = net.getGraph();
322
                int idSymbol = graphicLayer.addSymbol(getTextSymbol());
323
                String tag = "N";
324
                for (int i = 0; i < g.numVertices(); i++) {
325
                        GvNode node = g.getNodeByID(i);
326
                        IGeometry geom = ShapeFactory.createPoint2D(node.getX(), node
327
                                        .getY());
328
                        NumberFormat nf = NumberFormat.getInstance();
329
                        nf.setMaximumFractionDigits(1);
330
                        String aux = "\u221E"; // infinito
331
                        if (node.getBestCost() < Double.MAX_VALUE)
332
                                aux = nf.format(node.getBestCost()) + " - " + nf.format(node.getAccumulatedLength());
333
                        FGraphicLabel theGLabel = new FGraphicLabel(geom, idSymbol, aux);
334
                        theGLabel.setObjectTag(tag);
335
                        theGLabel.getLabel().setJustification(FLabel.CENTER_TOP);
336
                        graphicLayer.addGraphic(theGLabel);
337
                }
338
                mapControl.drawGraphics();
339
340
        }
341
342
        public boolean isEnabled() {
343
                IWindow window = PluginServices.getMDIManager().getActiveWindow();
344
                if (window instanceof View)
345
                {
346
                        View v = (View) window;
347
                MapControl mapCtrl = v.getMapControl();
348
                        MapContext map = mapCtrl.getMapContext();
349
350
                        SingleLayerIterator it = new SingleLayerIterator(map.getLayers());
351
                        while (it.hasNext())
352
                        {
353
                                FLayer aux = it.next();
354
                                if (!aux.isActive())
355
                                        continue;
356
                                Network net = (Network) aux.getProperty("network");
357
358
                                if ( net != null)
359
                                {
360 23588 fpenarrubia
                                        if (net.getFlags().length > 0)
361
                                        {
362
                                                return true;
363
                                        }
364 13583 fjp
                                }
365
                        }
366
                }
367
                return false;
368
        }
369
370
        public boolean isVisible() {
371
                IWindow f = PluginServices.getMDIManager()
372
                 .getActiveWindow();
373
                if (f == null) {
374
                    return false;
375
                }
376
                if (f instanceof View) {
377
                        return true;
378
                }
379
                return false;
380
381
        }
382
383
}