Statistics
| Revision:

root / trunk / extensions / extGraph / src / org / gvsig / graph / core / GvNode.java @ 28552

History | View | Annotate | Download (14.3 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.core;
42

    
43
import java.util.ArrayList;
44

    
45
public class GvNode {
46
        public final static int statNotInList = 0;
47
        public final static int statNowInList = 1;
48
        public final static int statWasInList = 2;
49
        private int idNode;
50
        private double x;
51
        private double y;
52
        
53
//        int from_link = -1; // id del Arco desde el que hemos llegado
54
        int   numSoluc = 0; // Empezamos con esto a cero en toda la red. 
55
                                        // De manera global, habr? una variable numSolucGlobal que indica el n? de cada petici?n de ruta.
56
                                        // Sirve para no tener que inicializar siempre tooooda la red. Lo que hacemos es comparar el 
57
                                        // n? de petici?n global con este. Si no coinciden, antes de hacer nada hay que inicializar su
58
                                        // best_cost a infinito.
59

    
60
//        double best_cost = Double.MAX_VALUE;
61
        double accumulatedLength = 0;
62
        double stimation = Double.MAX_VALUE; // bestCost + something related to destiny's euclidean length
63
        int status;
64
//        ArrayList<GvEdge> outputLinks  = new ArrayList<GvEdge>(); // Neighbors links
65
//        ArrayList<GvEdge> inputLinks  = new ArrayList<GvEdge>(); // links with end node in this node.
66
        
67
        ArrayList<GvConnector> connectors = new ArrayList<GvConnector>(2);
68
        
69
        ArrayList<GvTurn> turnCosts = new ArrayList<GvTurn>(0); // Turn costs. If a GvTurnCost exists, we add its cost.
70
                                                  // If the cost is < 0, it is a prohibited cost.
71

    
72
        public GvNode() {
73
                initialize();
74
        }
75
        
76
        public void initialize() {
77
                numSoluc = GlobalCounter.numSolucGlobal;
78
//                from_link = -1;
79
//                best_cost = Double.MAX_VALUE;
80
                stimation = Double.MAX_VALUE;
81
                accumulatedLength = 0;
82
                status = statNotInList;
83
                GvConnector c;
84
                for (int iConec=0; iConec< connectors.size();  iConec++)
85
                {
86
                        c = connectors.get(iConec);
87

    
88
                        c.setFrom_link_c(-1);
89
                        c.setBestCostOut(Double.MAX_VALUE);
90
                        c.setMustBeRevised(true);
91
                }
92
                
93

    
94
        }
95
        
96
        public int getIdNode() {
97
                return idNode;
98
        }
99
        public void setIdNode(int idNode) {
100
                this.idNode = idNode;
101
        }
102
        public double getX() {
103
                return x;
104
        }
105
        public void setX(double x) {
106
                this.x = x;
107
        }
108
        public double getY() {
109
                return y;
110
        }
111
        public void setY(double y) {
112
                this.y = y;
113
        }
114
//        public double getBestCost() {
115
//                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
116
//                        return Double.MAX_VALUE;
117
//                return best_cost;
118
//        }
119
//        public void setBestCost(double best_cost) {
120
//                this.best_cost = best_cost;
121
//        }
122
//        public ArrayList getOutputLinks() {
123
//                return outputLinks;
124
//        }
125
        public double getStimation() {
126
                return stimation;
127
        }
128
        public void setStimation(double estimacion) {
129
                this.stimation = estimacion;
130
        }
131
//        public int getFromLink() {
132
//                return from_link;
133
//        }
134
//        public void setFromLink(int from_link) {
135
//                this.from_link = from_link;
136
//        }
137
        public ArrayList<GvTurn> getTurnCosts() {
138
                return turnCosts;
139
        }
140
        
141
        public void setTurnCosts(ArrayList<GvTurn> turns) {
142
                this.turnCosts = turns;
143
        }
144
        public int getNumSoluc() {
145
                return numSoluc;
146
        }
147
        public void setNumSoluc(int numSoluc) {
148
                this.numSoluc = numSoluc;
149
        }
150
        public int getStatus() {
151
                return status;
152
        }
153
        public void setStatus(int status) {
154
                this.status = status;
155
        }
156

    
157
        public void calculateStimation(GvNode finalNode, double newCost) {
158
                double DeltaX = ((finalNode.getX() - x)/1000.0)*((finalNode.getX() - x)/1000.0);
159
                double DeltaY = ((finalNode.getY() - y)/1000.0)*((finalNode.getY() - y)/1000.0);
160
                double distLineaRecta = Math.sqrt(DeltaX + DeltaY); // En Km
161
                stimation = newCost + (distLineaRecta* 30.0);  // Segundos que tardamos en recorrer esos Km a 120 Km/hora
162

    
163
                
164
        }
165

    
166
        public double getAccumulatedLength() {
167
                return accumulatedLength;
168
        }
169

    
170
        public void setAccumulatedLength(double accumulatedLength) {
171
                this.accumulatedLength = accumulatedLength;
172
        }
173
        
174
        public int getOutputDegree() {
175
                int numOutLink = 0;
176
                for (int iConec=0; iConec< connectors.size();  iConec++)
177
                {
178
                        GvConnector c = connectors.get(iConec);
179

    
180
                        if (c.getEdgeOut() == null) continue;
181
                        numOutLink++;                        
182
                }
183
                return numOutLink;
184
        }
185

    
186
        public int getInputDegree() {
187
                int numInLink = 0;
188
                for (int iConec=0; iConec< connectors.size();  iConec++)
189
                {
190
                        GvConnector c = connectors.get(iConec);
191

    
192
                        if (c.getEdgeIn() == null) continue;
193
                        numInLink++;                        
194
                }
195
                return numInLink;
196

    
197
        }
198

    
199
        public EdgeOutIterator getOutputEdgeIterator() {
200
                return new EdgeOutIterator(this);
201
        }
202
        
203
        public EdgeInIterator getInputEdgeIterator() {
204
                return new EdgeInIterator(this);
205
        }
206

    
207

    
208
        /**
209
         * Returns the link that we have used to reach idEdgeOut. Important for turn costs.
210
         * @param idArcoS
211
         * @return
212
         */
213
        public int get_from_link(long idEdgeOut)
214
        {
215
                // Queremos saber desde qu? arco hemos entrado para llegar a este arco.
216
                for (int iConec =0; iConec < connectors.size(); iConec++) {
217
                        GvConnector c = connectors.get(iConec);
218
                        if (c.getEdgeOut() != null) {
219
                                if (c.getEdgeOut().getIdEdge() == idEdgeOut)
220
                                {
221
                                        return c.getFrom_link_c();
222
                                }
223
                        }
224
                        
225
                }
226
                // TODO: throw exception??
227
                return -1;
228
                                
229
        }
230
        public int get_best_from_link()
231
        {
232
                // Queremos saber desde qu? arco hemos entrado para llegar a este arco.
233
                GvConnector c;
234
                int best_link = -1;
235
                double bestCost = Double.MAX_VALUE;
236
                for (int iConec=0; iConec< connectors.size();  iConec++)
237
                {
238
                        c = connectors.get(iConec);
239
                        if (c.getBestCostOut() < bestCost)
240
                        {
241
                                bestCost = c.getBestCostOut();
242
                                best_link = c.getFrom_link_c();
243
                        }
244
                        
245
                }
246
                return best_link;
247
                                
248
        }
249

    
250
        public boolean existeMejora(GvEdge edge, double newCost)
251
        {
252
                // Si entrando desde ese arco mejoramos el coste de alg?n conector, devolvemos que 
253
                // hay mejora
254
                // NO QUEREMOS TOCAR EL CONECTOR PROPIO!!!!
255
                // Y tampoco hay que tener en cuenta los costes de giros para los conectores que toque.
256
                boolean hayMejora = false;
257
                GvConnector c;
258
                double auxCost;
259
                boolean bGiroProhibido;
260
                double costeGiro;
261
                // char Msg[200];
262

    
263
                // log("Dentro de existeMejora");
264
        
265
                for (int iConec=0; iConec< connectors.size();  iConec++)
266
                {
267
                        // sprintf(Msg,"Conector iConec=%ld de %ld. Capacity=%ld", iConec, Conectores.size(), Conectores.capacity());
268
                        // log(Msg);
269
                        auxCost = newCost;
270
                        c = connectors.get(iConec);
271
                        // sprintf(Msg,"pC->idArcoS=%ld, pc-idArcoE=%ld", pC->idArcoS, pC->idArcoE);
272
                        // log(Msg);
273

    
274
                        if (c.getEdgeOut() == null) continue;
275

    
276
                        // Miramos la lista de Giros de ese nodo
277
                        bGiroProhibido = false;
278
                        costeGiro = 0;
279
                        for (int idGiro=0; idGiro < getTurnCosts().size(); idGiro++)
280
                        {
281
                                // Si est? prohibido, a por otro
282
                                GvTurn elGiro = getTurnCosts().get(idGiro);
283
                                // log("ANTES del if");
284
                                if ((elGiro.getIdArcFrom() == edge.getIdArc()) && 
285
                                        (elGiro.getIdArcTo() == c.getEdgeOut().getIdArc()))
286
                                {
287
                                        if (elGiro.getCost() < 0)
288
                                        {
289
                                                bGiroProhibido = true;
290
                                        }
291
                                        else
292
                                                costeGiro = elGiro.getCost();
293

    
294
                                        break; // Salimos del for porque ya hemos encontrado el giro
295
                                }
296
                                // log("DESPUES del if");
297
                        }
298

    
299
                        auxCost = newCost + costeGiro;
300
                        if (c.getEdgeIn() == edge)
301
                        {
302
                                if (c.getBestCostIn() > newCost)
303
                                {
304
                                        c.setBestCostIn(newCost);
305
                                        // pC->from_link_c = idArcoEntrada;
306
                                }
307
                                continue; // Miramos solo los conectores distintos al de entrada
308
                        }
309
                        // Si est? prohibido, vamos a por otro enlace
310
                        if (bGiroProhibido)
311
                        {
312
                                c.setMustBeRevised(true);
313
                                // sprintf(Msg, "Encontrado giro prohibido en conector %ld del nodo %ld", iConec, idNodo);
314
                                // log(Msg);
315
                                continue;                                        
316
                        }
317
                        
318
                        c.setMustBeRevised(false);                                                                                                                        
319
                        if (c.getBestCostOut() > auxCost)
320
                        {
321
                                hayMejora = true;
322
                                c.setFrom_link_c(edge.getIdEdge());
323
                                c.setBestCostOut(auxCost);
324
                                c.setMustBeRevised(true);
325
                                // sprintf(Msg, "HAY MEJORA: idNodo=%ld, iConec=%ld, idArcoEntrada=%ld, auxCost= %lf", idNodo, iConec, idArcoEntrada, auxCost);
326
                        }
327
                }
328
                return hayMejora;
329
                                
330
        }
331
        public boolean reverseFoundBetterPath(GvEdge edge, double newCost)
332
        {
333
                // Si entrando desde ese arco mejoramos el coste de alg?n conector, devolvemos que 
334
                // hay mejora
335
                // NO QUEREMOS TOCAR EL CONECTOR PROPIO!!!!
336
                // Y tampoco hay que tener en cuenta los costes de giros para los conectores que toque.
337
                boolean hayMejora = false;
338
                GvConnector c;
339
                double auxCost;
340
                boolean bGiroProhibido;
341
                double costeGiro;
342
                // char Msg[200];
343

    
344
                // log("Dentro de existeMejora");
345
        
346
                for (int iConec=0; iConec< connectors.size();  iConec++)
347
                {
348
                        // sprintf(Msg,"Conector iConec=%ld de %ld. Capacity=%ld", iConec, Conectores.size(), Conectores.capacity());
349
                        // log(Msg);
350
                        auxCost = newCost;
351
                        c = connectors.get(iConec);
352
                        // sprintf(Msg,"pC->idArcoS=%ld, pc-idArcoE=%ld", pC->idArcoS, pC->idArcoE);
353
                        // log(Msg);
354

    
355
                        if (c.getEdgeIn() == null) continue;
356

    
357
                        // Miramos la lista de Giros de ese nodo
358
                        bGiroProhibido = false;
359
                        costeGiro = 0;
360
                        for (int idGiro=0; idGiro < getTurnCosts().size(); idGiro++)
361
                        {
362
                                // Si est? prohibido, a por otro
363
                                GvTurn elGiro = getTurnCosts().get(idGiro);
364
                                // log("ANTES del if");
365
                                if ((elGiro.getIdArcTo() == edge.getIdArc()) && 
366
                                        (elGiro.getIdArcFrom() == c.getEdgeIn().getIdArc()))
367
                                {
368
                                        if (elGiro.getCost() < 0)
369
                                        {
370
                                                bGiroProhibido = true;
371
                                        }
372
                                        else
373
                                                costeGiro = elGiro.getCost();
374

    
375
                                        break; // Salimos del for porque ya hemos encontrado el giro
376
                                }
377
                                // log("DESPUES del if");
378
                        }
379

    
380
                        auxCost = newCost + costeGiro;
381
                        if (c.getEdgeOut() == edge)
382
                        {
383
                                if (c.getBestCostIn() > newCost)
384
                                {
385
                                        c.setBestCostIn(newCost);
386
                                        // pC->from_link_c = idArcoEntrada;
387
                                }
388
                                continue; // Miramos solo los conectores distintos al de entrada
389
                        }
390
                        // Si est? prohibido, vamos a por otro enlace
391
                        if (bGiroProhibido)
392
                        {
393
                                c.setMustBeRevised(true);
394
                                // sprintf(Msg, "Encontrado giro prohibido en conector %ld del nodo %ld", iConec, idNodo);
395
                                // log(Msg);
396
                                continue;                                        
397
                        }
398
                        
399
                        c.setMustBeRevised(false);                                                                                                                        
400
                        if (c.getBestCostOut() > auxCost)
401
                        {
402
                                hayMejora = true;
403
                                c.setFrom_link_c(edge.getIdEdge());
404
                                c.setBestCostOut(auxCost);
405
                                c.setMustBeRevised(true);
406
                                // sprintf(Msg, "HAY MEJORA: idNodo=%ld, iConec=%ld, idArcoEntrada=%ld, auxCost= %lf", idNodo, iConec, idArcoEntrada, auxCost);
407
                        }
408
                }
409
                return hayMejora;
410
                                
411
        }
412
        
413
        
414
        public double getBestCost()
415
        {
416
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
417
                        return Double.MAX_VALUE;
418

    
419
                double bestCost = Double.MAX_VALUE;
420
                GvConnector c;
421
                for (int iConec=0; iConec< connectors.size();  iConec++)
422
                {
423
                        c = connectors.get(iConec);
424
                        
425
                        if (c.getBestCostOut() < bestCost)
426
                        {
427
                                bestCost = c.getBestCostOut();
428
                        }
429
                }
430
                return bestCost;
431
                                
432
        }
433

    
434
        public double getBestCostIn()
435
        {
436
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
437
                        return Double.MAX_VALUE;
438

    
439
                double bestCost = Double.MAX_VALUE;
440
                GvConnector c;
441
                for (int iConec=0; iConec< connectors.size();  iConec++)
442
                {
443
                        c = connectors.get(iConec);
444
                        
445
                        if (c.getBestCostIn() < bestCost)
446
                        {
447
                                bestCost = c.getBestCostIn();
448
                        }
449
                }
450
                return bestCost;
451
                                
452
        }
453

    
454
        public double getBestCostOfDirty()
455
        {
456
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
457
                        return Double.MAX_VALUE;
458

    
459
                double bestCost = Double.MAX_VALUE;
460
                GvConnector c;
461
                for (int iConec=0; iConec< connectors.size();  iConec++)
462
                {
463
                        c = connectors.get(iConec);
464
                        
465
                        if ((c.isMustBeRevised()) && (c.getBestCostOut() < bestCost))
466
                        {
467
                                bestCost = c.getBestCostOut();
468
                        }
469
                }
470
                return bestCost;
471
                                
472
        }
473

    
474
        public void setCostZero()
475
        {
476
                GvConnector c;
477
                for (int iConec=0; iConec< connectors.size();  iConec++)
478
                {
479
                        c = connectors.get(iConec);
480
                        c.setBestCostOut(0);
481
                        c.setBestCostIn(0);
482
                }
483
                
484
                // TODO: provisional. QUITAR bestCost como atributo
485
//                best_cost = 0;
486
                                
487
        }
488

    
489
        /**
490
         * Add an edge out to this node. This function takes care of creating the needed connectors
491
         * @param edge
492
         */
493
        public void addOutputLink(GvEdge edge) {
494
//                outputLinks.add(edge);
495
                // Create connectors
496
                // First, search the connector if it is already created
497
                GvConnector c;
498
                boolean bFound = false;
499
                GvConnector cFound = null;
500
                for (int iConec=0; iConec< connectors.size();  iConec++)
501
                {
502
                        c = connectors.get(iConec);
503
                        if ((c.getEdgeIn() != null) && (c.getEdgeIn().getIdArc() == edge.getIdArc())) {
504
                                // Found. This connector has been originated before by the same arc
505
                                bFound = true;
506
                                cFound = c;
507
                                break;
508
                        }
509
                }
510
                if (!bFound) {
511
                        GvConnector newCon = new GvConnector();
512
                        newCon.setEdgeOut(edge);
513
                        connectors.add(newCon);
514
                }
515
                else
516
                {
517
                        cFound.setEdgeOut(edge);
518
                }
519
                
520
        }
521

    
522
        /**
523
         * Add an input edge to this node. This function takes care of creating the needed connectors
524
         * @param edge
525
         */
526
        public void addInputLink(GvEdge edge) {
527
//                inputLinks.add(edge);
528
                // First, search the connector if it is already created
529
                GvConnector c;
530
                boolean bFound = false;
531
                GvConnector cFound = null;
532
                for (int iConec=0; iConec< connectors.size();  iConec++)
533
                {
534
                        c = connectors.get(iConec);
535
                        if ((c.getEdgeOut() != null) && (c.getEdgeOut().getIdArc() == edge.getIdArc())) {
536
                                // Found. This connector has been originated before by the same arc
537
                                bFound = true;
538
                                cFound = c;
539
                                break;
540
                        }
541
                }
542
                if (!bFound) {
543
                        GvConnector newCon = new GvConnector();
544
                        newCon.setEdgeIn(edge);
545
                        connectors.add(newCon);
546
                }
547
                else
548
                {
549
                        cFound.setEdgeIn(edge);
550
                }
551
                
552
        }
553

    
554
        public ArrayList<GvConnector> getConnectors() {
555
                return connectors;
556
        }
557

    
558
        /**
559
         * Adds turnCost and setNode to turnCost. Useful to clear turncosts
560
         * @param turnCost
561
         */
562
        public void addTurnCost(GvTurn turnCost) {
563
                turnCost.setNode(this);
564
                turnCosts.add(turnCost);
565
                
566
        }
567

    
568
        public void removeTurnCosts() {
569
                turnCosts = new ArrayList<GvTurn>();
570
                
571
        }
572
}
573

    
574