Revision 25628 trunk/extensions/extGraph/src/org/gvsig/graph/solvers/OneToManySolver.java

View differences:

OneToManySolver.java
68 68

  
69 69
public class OneToManySolver extends AbstractNetSolver {
70 70

  
71
	private int idStart = -1;
72
	private ArrayList idStops = null;
71
	protected int idStart = -1;
72
	protected ArrayList idStops = null;
73 73
	
74 74
	// Soporte listeners
75
	private ArrayList<IDijkstraListener> listeners = new ArrayList<IDijkstraListener>();
75
	protected ArrayList<IDijkstraListener> listeners = new ArrayList<IDijkstraListener>();
76 76
	
77 77
	public void addListener(IDijkstraListener listener) {
78 78
		listeners.add(listener);
79 79
	}
80
	private boolean callMinimumCostNodeSelectedListeners(GvNode node) {
80
	protected boolean callMinimumCostNodeSelectedListeners(GvNode node) {
81 81
		for (IDijkstraListener listener : listeners) {
82 82
			if (listener.minimumCostNodeSelected(node))
83 83
				return true;
84 84
		}
85 85
		return false;
86 86
	}
87
	private boolean callAdjacenteEdgeVisitedListeners(GvNode fromNode, GvEdge edge) {
87
	protected boolean callAdjacenteEdgeVisitedListeners(GvNode fromNode, GvEdge edge) {
88 88
		for (IDijkstraListener listener : listeners) {
89 89
			if (listener.adjacentEdgeVisited(fromNode, edge))
90 90
				return true;
......
92 92
		return false;
93 93
	}
94 94
	
95
	private class StopAux {
95
	protected class StopAux {
96 96
		public StopAux(Integer idStop2) {
97 97
			idStop = idStop2;
98 98
			bFound = false;
......
110 110
		}
111 111
	}
112 112
	
113
	private GvFlag sourceFlag;
114
	private boolean bExploreAll = false; // by default
115
	private double maxCost = Double.MAX_VALUE;
116
	private double maxDistance = Double.MAX_VALUE;
117
	private GvFlag[] destinations;
118
	private GeometryFactory geomFactory = new GeometryFactory();
113
	protected GvFlag sourceFlag;
114
	protected boolean bExploreAll = false; // by default
115
	protected double maxCost = Double.MAX_VALUE;
116
	protected double maxDistance = Double.MAX_VALUE;
117
	protected GvFlag[] destinations;
119 118
	protected Route route = new Route();
120
	private int fieldIndexStreetName;
121 119
	
122 120

  
123 121
	
......
418 416
	public void setMaxDistance(double maxDistance) {
419 417
		this.maxDistance = maxDistance;
420 418
	}
421
	public void setFielStreetName(String name) {
422
		try {
423
			int aux = net.getLayer().getRecordset().getFieldIndexByName(name);
424
			if (aux == -1)
425
				throw new RuntimeException("Field " + name + " not found.");
426
			fieldIndexStreetName = aux;
427
		} catch (BaseException e) {
428
			// TODO Auto-generated catch block
429
			e.printStackTrace();
430
		}
431
		
432
	}
433
	private void populateRouteSimple(int idStart, int idEnd)
434
			throws BaseException {
435
				int idEnlace;
436
				GvNode node;
437
				GvEdge link;
438
				double costeEntrada;
439
			
440
				// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los Enlaces
441
				double Coste = 0;
442
				double Coste2 = 0;
443
				IGraph graph = net.getGraph();
444
				node = graph.getNodeByID(idEnd);
445
				int from_link = node.get_best_from_link();
446
				VectorialAdapter va = (VectorialAdapter) net.getLayer().getSource();
447
				while (node.getIdNode() != idStart)
448
				{
449
					if (from_link == -1)
450
					{
451
						throw new RuntimeException("Fallo al recorrer de manera inversa la soluci?n. Encontrado arco con -1");
452
						// break; // FALLO!!
453
					} 
454
					link = graph.getEdgeByID(from_link);
455
					IFeature feat = va.getFeature(link.getIdArc());
456
					route.addRouteFeature(feat.getGeometry(), link.getIdArc(), 
457
							link.getWeight(), link.getDistance(), feat.getAttribute(getFieldIndexStreetName()).toString());
458
			
459
					node = graph.getNodeByID(link.getIdNodeOrig());
460
			
461
					Coste = Coste + link.getWeight();
462
					Coste2 = Coste2 + link.getDistance();
463
			
464
					// TODO:
465
					// from_link = node.get_from_link(idEnlace, &costeEntrada);
466
					from_link = node.get_best_from_link();
467
					
468
			    }	
469
				System.out.println("Salgo con node = " + node.getIdNode());
470
			}
471
	protected void populateRoute(GvFlag origin, GvFlag dest, int idStart,
472
			int idEnd) throws BaseException {
473
					int idEnlace;
474
					GvNode node;
475
					GvEdge link;
476
					double costeEntrada;
477
			
478
					// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los Enlaces
479
					IGraph graph = net.getGraph();
480
					node = graph.getNodeByID(idEnd);
481
					int from_link = node.get_best_from_link();
482
					VectorialAdapter va = (VectorialAdapter) net.getLayer().getSource();
483
					
484
					/*	Miramos los nodos de los tramos inicio y final, y cogemos el nodo que tenga el from_link rellenado. E IGUAL A NUMSOLUCGLOBAL!!!!
485
						A partir de ah?, recorremos hacia atr?s y tenemos el cuerpo principal del shape. Luego, para
486
						las puntas hay que tener en cuenta los porcentajes, viendo el trozo que est? pegando a los nodos
487
						que sabemos que est?n en el path
488
					*/
489
			
490
					/* 22/9/2003 Corregimos el fallo que hab?a de escribir el shape de atr?s adelante.
491
					*  Guardamos lo que necesitamos en listaShapes y recorremos esa lista guardando los tramos
492
					*	con el sentido adecuado.
493
					*/
494
			
495
					/* 3/Febrero/2005 Limpieza de c?digo superfluo y correci?n de un fallo raro. Ahora es m?s simple y parece
496
					* que no falla. A ver si dura. IDEA: quiz?s se necesite meter el porcentaje en los arcos partidos.
497
					*/	
498
			
499
					// Define a template class for a vector of IDs.
500
					InfoShp infoShp;
501
					Stack pilaShapes = new Stack();
502
			//		typedef stack<CInfoShp> PILAINFO;
503
			//		PILAINFO pilaShapes;
504
			
505
					double costeTramoFinal=-1;
506
					GvNode nodeEnd = graph.getNodeByID(idEnd);
507
					GvEdge finalEdge = graph.getEdgeByID(nodeEnd.get_best_from_link());
508
					costeTramoFinal = finalEdge.getWeight();
509
			
510
					GvNode pNodo;
511
					GvEdge pEnlace;
512
					
513
					boolean bFlipearShape = false;
514
			
515
					double pctMax, pctMin;
516
			
517
			
518
			
519
					//////////////////////////////////////////////////////////////////////////////////////
520
					// Trozo del final
521
					// El shape va de idStop1 a idStop2, y el porcentaje viene en ese sentido.
522
					// Si el idEnd es idStop1, quiere decir que el tramo que falta va en ese sentido tambi?n,
523
					// as? que recorremos ese shape desde idStop1 hasta que rebasemos o igualemos ese porcentaje.
524
					// Si no, hemos pasado por idStop2 y la parte que hay que meter es desde el pto interior a idStop2
525
					///////////////////////////////////////////////////////////////////////////////////////
526
					IFeature feat = va.getFeature(finalEdge.getIdArc());
527
					MultiLineString jtsGeom = (MultiLineString) feat.getGeometry().toJTSGeometry();
528
			//		CoordinateFilter removeDuplicates = new UniqueCoordinateArrayFilter(); 
529
			//		jtsGeom.apply(removeDuplicates);
530
			//		jtsGeom.geometryChanged();
531
					
532
					
533
					
534
					// SI ESTAMOS SOBRE EL MISMO TRAMO, CASO PARTICULAR
535
					// y el sentido de circulaci?n es correcto
536
					if ((origin.getIdArc() == dest.getIdArc()) && (nodeEnd.getBestCost() <= costeTramoFinal))
537
					{
538
						if (dest.getPct() > origin.getPct())
539
						{
540
							pctMax = dest.getPct();
541
							pctMin = origin.getPct(); 
542
						}
543
						else
544
						{
545
							pctMax = origin.getPct();
546
							pctMin = dest.getPct();
547
							bFlipearShape = true;
548
						}
549
			
550
						LineString line = NetworkUtils.getPartialLineString(jtsGeom, 
551
								pctMax, 1);
552
			
553
						pctMin = pctMin / pctMax; // Porque ha cambiado la longitud
554
													// del shape
555
			
556
						line = NetworkUtils.getPartialLineString(line, pctMin, 0);
557
			
558
						if (bFlipearShape)
559
							line = line.reverse();
560
						
561
						IGeometry geom = FConverter.jts_to_igeometry(line);
562
						// TODO: Calcular bien el length de este arco, 
563
						// basandonos en el porcentaje costeTramoFinal / costeOriginal
564
						route.addRouteFeature(geom, origin.getIdArc(), 
565
								costeTramoFinal, line.getLength(), feat.getAttribute(getFieldIndexStreetName()).toString());
566
			
567
			
568
						return ; // Deber?a sacar el coste
569
					}
570
			
571
					
572
			
573
					// Trazar el camino desde idEnd hasta idStart hacia atr?s marcando los Enlaces
574
					pNodo = graph.getNodeByID(idEnd);
575
			
576
					while ((pNodo.getIdNode() != idStart)) 
577
					{
578
						idEnlace = pNodo.get_best_from_link();
579
						pEnlace = graph.getEdgeByID(idEnlace);
580
			
581
						pNodo = graph.getNodeByID(pEnlace.getIdNodeOrig());
582
						
583
						infoShp = new InfoShp();
584
						infoShp.distance = pEnlace.getDistance();
585
						infoShp.cost = pEnlace.getWeight();
586
			
587
						if ((pEnlace.getIdArc() == origin.getIdArc()) || (pEnlace.getIdArc() == dest.getIdArc()))
588
						{
589
							if (pEnlace.getIdArc() == origin.getIdArc())
590
							{
591
								infoShp.pct = origin.getPct();
592
								infoShp.idArc = origin.getIdArc();
593
								if (pEnlace.getDirec() == 0) 
594
								{
595
									infoShp.direction = 1;
596
									infoShp.bFlip = true;
597
								}
598
								else // Hemos pasado por el 2
599
								{
600
									infoShp.direction = 0;
601
									infoShp.bFlip = false;
602
								} // if else */
603
							}
604
							else
605
							{
606
								infoShp.pct = dest.getPct();
607
								infoShp.idArc = dest.getIdArc();
608
								if (pEnlace.getDirec() == 0)
609
								{
610
									infoShp.direction = 0;
611
									infoShp.bFlip = true;
612
								}
613
								else
614
								{
615
									infoShp.direction = 1;
616
									infoShp.bFlip = false;
617
								} // if else */
618
							}
619
						}
620
						else
621
						{
622
							infoShp.pct = 1.0;
623
							infoShp.idArc = pEnlace.getIdArc();
624
							
625
							infoShp.direction =1;
626
							if (pEnlace.getDirec() == 1)
627
								infoShp.bFlip = false;
628
							else
629
								infoShp.bFlip = true;
630
						}
631
			
632
						pilaShapes.push(infoShp);
633
					}
634
			
635
					// Y ahora recorremos hacia atr?s el vector y escribimos los shapes.
636
					// VECTORINFO::iterator theIterator;
637
					int auxC = 0;
638
					
639
					while (!pilaShapes.empty())  
640
					{
641
						infoShp = (InfoShp) pilaShapes.peek();
642
						feat = va.getFeature(infoShp.idArc);
643
						MultiLineString line = (MultiLineString) feat.getGeometry().toJTSGeometry();
644
			//			line.apply(removeDuplicates);
645
			//			line.geometryChanged();
646
						
647
						LineString aux = null;
648
						if (infoShp.pct < 1.0)
649
							aux = NetworkUtils.getPartialLineString(line, infoShp.pct,
650
									infoShp.direction);
651
			
652
			
653
						IGeometry geom = null;
654
						if (aux == null)
655
						{
656
							if (infoShp.bFlip)
657
								line = line.reverse();
658
							geom = FConverter.jts_to_igeometry(line);
659
						}	
660
						else
661
						{
662
							if (infoShp.bFlip)
663
								aux = aux.reverse();
664
							geom = FConverter.jts_to_igeometry(aux);
665
						}	
666
			
667
			
668
						route.addRouteFeature(geom, infoShp.idArc, 
669
								infoShp.cost, infoShp.distance, feat.getAttribute(getFieldIndexStreetName()).toString());
670
			
671
			
672
						pilaShapes.pop();
673
						auxC++;
674
						
675
					}
676
			
677
					return;
678
			
679
					
680
				}
681
	LineString SituaSobreTramo(Geometry geom, int idArc, double pct, int parte) {
682
		int j, numVertices;
683
		double longAcum, longReal, longBuscada, distSobre, miniPorcentaje;
684
		double nuevaX, nuevaY; // Por cuestiones de claridad al programar
685
		double dist=0;
686
	
687
		longAcum = 0;
688
		longReal = geom.getLength();
689
		longBuscada = longReal * pct;
690
		Coordinate[] coords = geom.getCoordinates();
691
		Coordinate c1 = null, c2 = null;
692
		ArrayList savedCoords = new ArrayList();
693
	
694
	 	if (parte > 0) // Hemos entrado por el 1 hacia el 2 (al 2 no llegamos)
695
		{
696
			for( j = 0; j < coords.length-1; j++ ) 
697
			{
698
				c1 = coords[j];
699
				c2 = coords[j+1];
700
				dist = c1.distance(c2);
701
				longAcum += dist;
702
				savedCoords.add(c1);
703
				if (longAcum >= longBuscada)
704
				{
705
					// Hasta aqu?. Ahora ahi que poner el punto sobre el tramo
706
					distSobre = dist - (longAcum - longBuscada);
707
					miniPorcentaje = distSobre/dist;
708
	
709
					nuevaX = c1.x + (c2.x-c1.x) * miniPorcentaje;
710
					nuevaY = c1.y + (c2.y-c1.y) * miniPorcentaje;
711
		
712
					savedCoords.add(new Coordinate(nuevaX, nuevaY));
713
					break;
714
				} // if longAcum >= longBuscada
715
			} // for j
716
			
717
		}
718
		else // Hemos entrado por el 2 hacia el 1
719
		{
720
			numVertices = 0;
721
			for( j = 0; j < coords.length; j++ ) 
722
			{
723
				////////////////////////////////////////////////////////////////
724
				// 13_ene_2005: Si el ?ltimo punto es el ?ltimo punto no
725
				// podemos acceder al elemento j+1 porque nos salimos del shape
726
				/////////////////////////////////////////////////////////////////
727
				c1 = coords[j];
728
				if (j < coords.length -1)
729
				{					
730
					c2 = coords[j+1];
731
	
732
					dist = c1.distance(c2);
733
					longAcum += dist;
734
				}
735
	
736
				if (longAcum >= longBuscada)
737
				{
738
					// Hasta aqu?. Empezamos a meter puntos
739
	
740
					if (numVertices == 0) 
741
					{
742
						distSobre = dist - (longAcum - longBuscada);
743
						miniPorcentaje = distSobre/dist;
744
						nuevaX = c1.x + (c2.x-c1.x) * miniPorcentaje;
745
						nuevaY = c1.y + (c2.y-c1.y) * miniPorcentaje;
746
						
747
						savedCoords.add(new Coordinate(nuevaX, nuevaY));
748
					}
749
					else
750
					{
751
						savedCoords.add(c2);
752
					}
753
					numVertices ++;
754
					// break;
755
				} // if longAcum >= longBuscada
756
			} // for j
757
			
758
			// savedCoords.add(c2);
759
			
760
		} // if else
761
	
762
	 	
763
	 	return geomFactory.createLineString((Coordinate[] )savedCoords.toArray(new Coordinate[0]));
764
	}
765
	private int getFieldIndexStreetName() {
766
		return fieldIndexStreetName;
767
	}
768 419

  
769 420
}

Also available in: Unified diff