Statistics
| Revision:

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

History | View | Annotate | Download (11.6 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>();
68
        
69
        ArrayList<GvTurn> turnCosts = new ArrayList<GvTurn>(); // 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().getIdEdge() == idEdgeOut)
219
                        {
220
                                return c.getFrom_link_c();
221
                        }
222
                        
223
                }
224
                // TODO: throw exception??
225
                return -1;
226
                                
227
        }
228
        public int get_best_from_link()
229
        {
230
                // Queremos saber desde qu? arco hemos entrado para llegar a este arco.
231
                GvConnector c;
232
                int best_link = -1;
233
                double bestCost = Double.MAX_VALUE;
234
                for (int iConec=0; iConec< connectors.size();  iConec++)
235
                {
236
                        c = connectors.get(iConec);
237
                        if (c.getBestCostOut() < bestCost)
238
                        {
239
                                bestCost = c.getBestCostOut();
240
                                best_link = c.getFrom_link_c();
241
                        }
242
                        
243
                }
244
                return best_link;
245
                                
246
        }
247

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

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

    
272
                        if (c.getEdgeOut() == null) continue;
273

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

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

    
297
                        if (c.getEdgeIn() == edge)
298
                        {
299
                                if (c.getBestCostIn() > newCost)
300
                                {
301
                                        c.setBestCostIn(newCost);
302
                                        // pC->from_link_c = idArcoEntrada;
303
                                }
304
                                continue; // Miramos solo los conectores distintos al de entrada
305
                        }
306
                        // Si est? prohibido, vamos a por otro enlace
307
                        if (bGiroProhibido)
308
                        {
309
                                c.setMustBeRevised(true);
310
                                // sprintf(Msg, "Encontrado giro prohibido en conector %ld del nodo %ld", iConec, idNodo);
311
                                // log(Msg);
312
                                continue;                                        
313
                        }
314
                        auxCost = newCost + costeGiro;
315
                        c.setMustBeRevised(false);                                                                                                                        
316
                        if (c.getBestCostOut() > auxCost)
317
                        {
318
                                hayMejora = true;
319
                                c.setFrom_link_c(edge.getIdEdge());
320
                                c.setBestCostOut(auxCost);
321
                                c.setMustBeRevised(true);
322
                                // sprintf(Msg, "HAY MEJORA: idNodo=%ld, iConec=%ld, idArcoEntrada=%ld, auxCost= %lf", idNodo, iConec, idArcoEntrada, auxCost);
323
                        }
324
                }
325
                return hayMejora;
326
                                
327
        }
328
        public double getBestCost()
329
        {
330
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
331
                        return Double.MAX_VALUE;
332

    
333
                double bestCost = Double.MAX_VALUE;
334
                GvConnector c;
335
                for (int iConec=0; iConec< connectors.size();  iConec++)
336
                {
337
                        c = connectors.get(iConec);
338
                        
339
                        if (c.getBestCostOut() < bestCost)
340
                        {
341
                                bestCost = c.getBestCostOut();
342
                        }
343
                }
344
                return bestCost;
345
                                
346
        }
347

    
348
        public double getBestCostOfDirty()
349
        {
350
                if (numSoluc != GlobalCounter.getGlobalSolutionNumber())
351
                        return Double.MAX_VALUE;
352

    
353
                double bestCost = Double.MAX_VALUE;
354
                GvConnector c;
355
                for (int iConec=0; iConec< connectors.size();  iConec++)
356
                {
357
                        c = connectors.get(iConec);
358
                        
359
                        if ((c.isMustBeRevised()) && (c.getBestCostOut() < bestCost))
360
                        {
361
                                bestCost = c.getBestCostOut();
362
                        }
363
                }
364
                return bestCost;
365
                                
366
        }
367

    
368
        public void setCostZero()
369
        {
370
                GvConnector c;
371
                for (int iConec=0; iConec< connectors.size();  iConec++)
372
                {
373
                        c = connectors.get(iConec);
374
                        c.setBestCostOut(0);
375
                        c.setBestCostIn(0);
376
                }
377
                
378
                // TODO: provisional. QUITAR bestCost como atributo
379
//                best_cost = 0;
380
                                
381
        }
382

    
383
        /**
384
         * Add an edge out to this node. This function takes care of creating the needed connectors
385
         * @param edge
386
         */
387
        public void addOutputLink(GvEdge edge) {
388
//                outputLinks.add(edge);
389
                // Create connectors
390
                // First, search the connector if it is already created
391
                GvConnector c;
392
                boolean bFound = false;
393
                GvConnector cFound = null;
394
                for (int iConec=0; iConec< connectors.size();  iConec++)
395
                {
396
                        c = connectors.get(iConec);
397
                        if ((c.getEdgeIn() != null) && (c.getEdgeIn().getIdArc() == edge.getIdArc())) {
398
                                // Found. This connector has been originated before by the same arc
399
                                bFound = true;
400
                                cFound = c;
401
                                break;
402
                        }
403
                }
404
                if (!bFound) {
405
                        GvConnector newCon = new GvConnector();
406
                        newCon.setEdgeOut(edge);
407
                        connectors.add(newCon);
408
                }
409
                else
410
                {
411
                        cFound.setEdgeOut(edge);
412
                }
413
                
414
        }
415

    
416
        /**
417
         * Add an input edge to this node. This function takes care of creating the needed connectors
418
         * @param edge
419
         */
420
        public void addInputLink(GvEdge edge) {
421
//                inputLinks.add(edge);
422
                // First, search the connector if it is already created
423
                GvConnector c;
424
                boolean bFound = false;
425
                GvConnector cFound = null;
426
                for (int iConec=0; iConec< connectors.size();  iConec++)
427
                {
428
                        c = connectors.get(iConec);
429
                        if ((c.getEdgeOut() != null) && (c.getEdgeOut().getIdArc() == edge.getIdArc())) {
430
                                // Found. This connector has been originated before by the same arc
431
                                bFound = true;
432
                                cFound = c;
433
                                break;
434
                        }
435
                }
436
                if (!bFound) {
437
                        GvConnector newCon = new GvConnector();
438
                        newCon.setEdgeIn(edge);
439
                        connectors.add(newCon);
440
                }
441
                else
442
                {
443
                        cFound.setEdgeIn(edge);
444
                }
445
                
446
        }
447

    
448
        public ArrayList<GvConnector> getConnectors() {
449
                return connectors;
450
        }
451

    
452
        /**
453
         * Adds turnCost and setNode to turnCost. Useful to clear turncosts
454
         * @param turnCost
455
         */
456
        public void addTurnCost(GvTurn turnCost) {
457
                turnCost.setNode(this);
458
                turnCosts.add(turnCost);
459
                
460
        }
461

    
462
        public void removeTurnCosts() {
463
                turnCosts = new ArrayList<GvTurn>();
464
                
465
        }
466
}
467

    
468