Statistics
| Revision:

svn-gvsig-desktop / trunk / extensions / extGraph / src / org / gvsig / graph / core / GvNode.java @ 35157

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

    
43
import java.util.ArrayList;
44

    
45
import org.gvsig.fmap.algorithm.triangulation.visad.SetException;
46

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

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

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

    
90
                        c.setFrom_link_c(-1);
91
                        c.setBestCostOut(Double.MAX_VALUE);
92
                        c.setBestCostIn(Double.MAX_VALUE);
93
                        c.setMustBeRevised(true);
94
                }
95
                
96

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

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

    
166
                
167
        }
168

    
169
        public double getAccumulatedLength() {
170
                return accumulatedLength;
171
        }
172

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

    
183
                        if (c.getEdgeOut() == null) continue;
184
                        numOutLink++;                        
185
                }
186
                return numOutLink;
187
        }
188

    
189
        public int getInputDegree() {
190
                int numInLink = 0;
191
                for (int iConec=0; iConec< connectors.size();  iConec++)
192
                {
193
                        GvConnector c = connectors.get(iConec);
194

    
195
                        if (c.getEdgeIn() == null) continue;
196
                        numInLink++;                        
197
                }
198
                return numInLink;
199

    
200
        }
201

    
202
        public EdgeOutIterator getOutputEdgeIterator() {
203
                return new EdgeOutIterator(this);
204
        }
205
        
206
        public EdgeInIterator getInputEdgeIterator() {
207
                return new EdgeInIterator(this);
208
        }
209

    
210

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

    
253
        public boolean existeMejora(GvEdge edge, double newCost)
254
        {
255
                // Si entrando desde ese arco mejoramos el coste de alg?n conector, devolvemos que 
256
                // hay mejora
257
                // NO QUEREMOS TOCAR EL CONECTOR PROPIO!!!! (Para evitar que en un nodo hagamos un U-turn) (Pero s? hay que marcarlo como con mejora, si existe)
258
                // Y tampoco hay que tener en cuenta los costes de giros para los conectores que toque.
259
                boolean hayMejora = false;
260
                GvConnector c;
261
                double auxCost;
262
                boolean bGiroProhibido;
263
                double costeGiro;
264
                // char Msg[200];
265

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

    
277
                        if (c.getEdgeOut() == null) continue;
278

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

    
297
                                        break; // Salimos del for porque ya hemos encontrado el giro
298
                                }
299
                                // log("DESPUES del if");
300
                        }
301

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

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

    
359
                        if (c.getEdgeIn() == null) continue;
360

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

    
379
                                        break; // Salimos del for porque ya hemos encontrado el giro
380
                                }
381
                                // log("DESPUES del if");
382
                        }
383

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

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

    
438
        public double getBestCostIn()
439
        {
440
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
441
                        return Double.MAX_VALUE;
442

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

    
458
        public double getBestCostOfDirty()
459
        {
460
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
461
                        return Double.MAX_VALUE;
462

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

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

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

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

    
558
        public ArrayList<GvConnector> getConnectors() {
559
                return connectors;
560
        }
561

    
562
        /**
563
         * Adds turnCost and setNode to turnCost. Useful to clear turncosts
564
         * @param turnCost
565
         */
566
        public void addTurnCost(GvTurn turnCost) {
567
                turnCost.setNode(this);
568
                turnCosts.add(turnCost);
569
                
570
        }
571

    
572
        public void removeTurnCosts() {
573
                turnCosts = new ArrayList<GvTurn>();
574
                
575
        }
576
        
577
        public int compareTo(GvNode o) {
578
                return Double.compare(getStimation(), o.getStimation());
579
        }
580

    
581
}
582

    
583