private int BuscaPosibleExtremosDesconectados( Vía laVía, Vía laVíaDestino) { int númeroDeProblemasDetectados = 0; // Necesitamos al menos dos nodos. Coordenadas[] losNodos = laVía.Coordenadas; int númeroDeNodos = losNodos.Length; if (númeroDeNodos >= 2) { #region Crea los nodos extremos. int índiceUltimoNodo = númeroDeNodos - 1; List <int> índicesNodosExtremos = new List <int>(); // Nos saltamos el nodo si éste tiene el atributo de índice desconectado. string atributoNodoDesconectado = AtributoNodoDesconectado + ",0"; if (!laVía.TieneAtributo(atributoNodoDesconectado)) { índicesNodosExtremos.Add(0); } atributoNodoDesconectado = AtributoNodoDesconectado + ',' + índiceUltimoNodo.ToString(CultureInfo.InvariantCulture); if (!laVía.TieneAtributo(atributoNodoDesconectado)) { índicesNodosExtremos.Add(índiceUltimoNodo); } #endregion // Busca la distancia mínima a los nodos de la vía. foreach (int índiceNodo in índicesNodosExtremos) { Coordenadas nodo = laVía.Coordenadas[índiceNodo]; double distanciaNodoMasCercano = double.MaxValue; int índiceNodoMasCercano = 0; int númeroDeNodosDestino = laVíaDestino.Coordenadas.Length; for (int índiceNodoDestino = 0; índiceNodoDestino < númeroDeNodosDestino; ++índiceNodoDestino) { Coordenadas nodoDestino = laVíaDestino.Coordenadas[índiceNodoDestino]; // Nos saltamos este nodo si tiene las mismas coordenadas. bool tienenLasMismasCoordenadas = (nodo == nodoDestino); if (tienenLasMismasCoordenadas) { distanciaNodoMasCercano = 0; continue; } // Busca el nodo mas cercano. double distancia = Coordenadas.DistanciaEnMetros(nodo, nodoDestino); if (distancia < distanciaNodoMasCercano) { distanciaNodoMasCercano = distancia; índiceNodoMasCercano = índiceNodoDestino; } } // Si la distancia al nodo mas cercano es cero quiere decir que tiene las mismas // coordenadas. En este caso nos saltamos este nodo extremo porque // nodos con las mismas coordenadas son procesados en otro ciclo. if (distanciaNodoMasCercano == 0) { continue; } // Los nodos son posibles nodos desconectados si la distancia entre // ellos es menor que la distancia máxima de búsqueda. if (distanciaNodoMasCercano < DistanciaMáxima) { // Si la vía tiene algun otro nodo conectado al nodo destino // entonces nos saltamos este nodo. bool laVíaTieneOtroNodoConectadoAlNodoDestino = false; foreach (Coordenadas nodoDeLaVía in laVía.Coordenadas) { Coordenadas nodoMasCercano = laVíaDestino.Coordenadas[índiceNodoMasCercano]; if (nodoDeLaVía == nodoMasCercano) { laVíaTieneOtroNodoConectadoAlNodoDestino = true; break; } } if (!laVíaTieneOtroNodoConectadoAlNodoDestino) { string error = string.Format("E107: La distancia es menor que {0:0.0} m: {1:0.0} m.", DistanciaMáxima, distanciaNodoMasCercano); InformaciónNodoDesconectado posibleNodoDesconectado = new InformaciónNodoDesconectado( new Nodo(laVía, índiceNodo), new Nodo(laVíaDestino, índiceNodoMasCercano), distanciaNodoMasCercano, error); PosibleNodosDesconectados.Add(posibleNodoDesconectado); ++númeroDeProblemasDetectados; } } } } return(númeroDeProblemasDetectados); }
/// <summary> /// Procesa una Vía. /// </summary> /// <param name="laVía">La Vía.</param> /// <returns>El número de problemas detectados al procesar el elemento.</returns> protected override int ProcesaElemento(Vía laVía) { int númeroDeProblemasDetectados = 0; Coordenadas[] nodos = laVía.Coordenadas; int númeroDeNodos = nodos.Length; // Crea mapa de nodos desconectados por adelantado para hacerlo // afuera del loop. bool[] mapaNodoDesconectado = new bool[númeroDeNodos]; for (int i = 0; i < númeroDeNodos; ++i) { string atributoNodoDesconectado = AtributoNodoDesconectado + ',' + i; if (laVía.TieneAtributo(atributoNodoDesconectado)) { mapaNodoDesconectado[i] = true; } } // Busca en todos los nodos de todas las vías (comenzando desde la siguiente // para no repetir búsquedas.) for (int índiceVíaDestino = IndiceDeElementoProcesándose + 1; índiceVíaDestino < NúmeroDeElementos; ++índiceVíaDestino) { Vía víaDestino = this[índiceVíaDestino]; #region Busca todos los nodos con las mismas coordenadas. foreach (Nodo nodo in laVía.Nodos) { // Nos saltamos el nodo si éste tiene el atributo de nodo desconectado. if (mapaNodoDesconectado[nodo.Indice]) { continue; } bool esNodoRuteable = nodo.EsRuteable; // Buscamos en todos los nodos destino. Coordenadas coordenadasNodo = nodo.Coordenadas; foreach (Nodo nodoDestino in víaDestino.Nodos) { #region Analizamos los nodos si tiene las mismas coordenadas. Coordenadas coordenadasNodoDestino = nodoDestino.Coordenadas; bool tienenLasMismasCoordenadas = (coordenadasNodo == coordenadasNodoDestino); if (tienenLasMismasCoordenadas) { string error = null; const double distancia = 0; bool esNodoDestinoRuteable = nodoDestino.EsRuteable; if (esNodoRuteable && esNodoDestinoRuteable) { // Si los identificadores de nodo no son el mismo entonces es un // posible nodo desconectado. if (nodo.IdentificadorGlobal != nodoDestino.IdentificadorGlobal) { error = string.Format("E104: Los nodos tienen Identificadores Globales distintos: {0} != {1}.", nodo.IdentificadorGlobal, nodoDestino.IdentificadorGlobal); } } else if (!esNodoRuteable & !esNodoDestinoRuteable) { error = "E105: Ambos nodos tienen las mismas coordenadas pero ninguno es ruteable."; } else { error = "E106: Ambos nodos tienen las mismas coordenadas pero solo uno es ruteable."; } if (error != null) { InformaciónNodoDesconectado posibleNodoDesconectado = new InformaciónNodoDesconectado( nodo, nodoDestino, distancia, error); PosibleNodosDesconectados.Add(posibleNodoDesconectado); ++númeroDeProblemasDetectados; // Añade las vías involucradas al filtro. FiltroDeVíasConPosiblesNodosDesconectados[IndiceDeElementoProcesándose] = true; FiltroDeVíasConPosiblesNodosDesconectados[índiceVíaDestino] = true; } // Nos salimos del ciclo porque si los nodos tienen las mismas // coordenadas entonces ya no pueden estar conectados en otro nodo. break; } #endregion } } #endregion // Busca nodos desconectados extremos. int númeroDeNodosDetectados = BuscaPosibleExtremosDesconectados(laVía, víaDestino); númeroDeNodosDetectados += BuscaPosibleExtremosDesconectados(víaDestino, laVía); if (númeroDeNodosDetectados > 0) { // Añade las vías involucradas al filtro. FiltroDeVíasConPosiblesNodosDesconectados[IndiceDeElementoProcesándose] = true; FiltroDeVíasConPosiblesNodosDesconectados[índiceVíaDestino] = true; } númeroDeProblemasDetectados += númeroDeNodosDetectados; } return(númeroDeProblemasDetectados); }