Beispiel #1
0
        private void EnSeBuscaronDuplicados(object elEnviador, EventArgs losArgumentos)
        {
            // Añade los PDIs duplicados.
            miLista.SuspendLayout();
            miLista.Items.Clear();
            miLista.Groups.Clear();
            foreach (KeyValuePair <Pdi, IList <Pdi> > item in miBuscadorDeDuplicados.GruposDeDuplicados)
            {
                Pdi         pdiBase    = item.Key;
                IList <Pdi> duplicados = item.Value;
                List <Pdi>  pdis       = new List <Pdi> {
                    pdiBase
                };
                pdis.AddRange(duplicados);

                // Crea un grupo para cada conjunto de duplicados.
                ListViewGroup grupo = new ListViewGroup(pdiBase.Nombre)
                {
                    Tag = pdis
                };
                miLista.Groups.Add(grupo);

                // Añade todos los PDIs.
                miLista.Items.Add(CreaItemDeLista(pdiBase, grupo, 0));
                foreach (Pdi duplicado in duplicados)
                {
                    double distancia = Coordenadas.DistanciaEnMetros(pdiBase.Coordenadas, duplicado.Coordenadas);
                    miLista.Items.Add(CreaItemDeLista(duplicado, grupo, distancia));
                }
            }
            miLista.ResumeLayout(false);

            // Actualiza el Número de PDIs a Eliminar.
            ActualizaNúmeroDePdisAEliminar();
        }
Beispiel #2
0
        /// <summary>
        /// Process one road.
        /// </summary>
        /// <param name="theRoad">The road.</param>
        /// <returns>The number of changes made to the element.</returns>
        protected override int ProcesaElemento(Vía theRoad)
        {
            int    numberOfChanges = 0;
            string targetName      = null;
            double minimumDistance = double.NaN;

            // For each road we look for a match.
            var currentName = theRoad.Nombre.Trim();

            // We only consider non-empty names.
            if (!string.IsNullOrEmpty(currentName))
            {
                foreach (ElementoDelMapa element in mySourceElements)
                {
                    var sourceRoad = element as Vía;
                    if (sourceRoad != null)
                    {
                        // The first match is the road name.
                        var sourceName = sourceRoad.Nombre.Trim();
                        if (!string.IsNullOrEmpty(sourceName))
                        {
                            if (sourceName.StartsWith(currentName, StringComparison.InvariantCultureIgnoreCase))
                            {
                                // We may have a match.
                                // Now we look for coordinates.
                                var    start       = theRoad.Coordenadas[0];
                                var    sourceStart = sourceRoad.Coordenadas[0];
                                double distance    = Coordenadas.DistanciaEnMetros(start, sourceStart);
                                if ((distance < MinimumDistanceInMeters) && !(distance >= minimumDistance))
                                {
                                    minimumDistance = distance;
                                    targetName      = sourceName;
                                }
                            }
                        }
                    }
                }
            }

            if (targetName != null)
            {
                bool cambió = theRoad.ActualizaNombre(
                    targetName,
                    string.Format(Recursos.M108, string.Format("{0:0.0 m.}", minimumDistance)));
                if (cambió)
                {
                    ++numberOfChanges;
                }
            }

            return(numberOfChanges);
        }
        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);
        }
        private void DibujaEscala()
        {
            // Calcula el largo del segmento de la escala en metros.
            // Para eso calculamos las coordenadas de los extremos del segmento
            // y con las coordenadas calculamos la distancia en metros.
            int    bordeDeAbajoEnPixels                = ClientRectangle.Bottom;
            Point  origenDelSegmentoEnPixels           = new Point(miOffsetDeEscalaEnPixels.X, bordeDeAbajoEnPixels - miOffsetDeEscalaEnPixels.Y);
            PointF origenDelSegmentoEnCoordenadas      = PixelsACoordenadas(origenDelSegmentoEnPixels);
            Point  finalDelSegmentoMínimoEnPixels      = new Point(origenDelSegmentoEnPixels.X + miLargoDelSegmentoMínimoEnPixels, origenDelSegmentoEnPixels.Y);
            PointF finalDelSegmentoMínimoEnCoordenadas = PixelsACoordenadas(finalDelSegmentoMínimoEnPixels);

            miLargoDelSegmentoMínimoEnMetros = Coordenadas.DistanciaEnMetros(origenDelSegmentoEnCoordenadas, finalDelSegmentoMínimoEnCoordenadas);

            // Si el largo del segmento es zero entonces nos salimos.
            if (miLargoDelSegmentoMínimoEnMetros <= 0)
            {
                return;
            }

            // Descompone el largo del segmento mínimo en exponente y mantisa.
            int    exponenteDelSegmentoMínimo = (int)Math.Log10(miLargoDelSegmentoMínimoEnMetros);
            double mantisaDelSegmentoMínimo   = miLargoDelSegmentoMínimoEnMetros / Math.Pow(10, exponenteDelSegmentoMínimo);

            // Como queremos mostrar la escala en números enteros tenemos que hacer
            // que la mantisa de la escala sea el menor número entero que sea mayor
            // o igual que la mantisa del segmento mínimo.
            // Por ejemplo, si el largo del segmento mínimo es 93m, entonces el
            // exponente es 1 y la mantisa es 9,3 (93 = 9,3 * 10^1). Como en la
            // escala queremos mostar 100m en vez de 93m, entonces usamos una
            // mantisa de 10.
            int mantisaDeLaEscala        = (int)Math.Ceiling(mantisaDelSegmentoMínimo);
            int largoDelSegmentoEnMetros = mantisaDeLaEscala * (int)Math.Pow(10, exponenteDelSegmentoMínimo);

            // Como la escala que vamos a mostrar puede ser mayor que la escala
            // del segmento mínimo (por ejemplo: 100m en vez de 93m), entonces
            // tenemos que ajustar el largo del segmento a dibujar.
            double factor            = largoDelSegmentoEnMetros / miLargoDelSegmentoMínimoEnMetros;
            int    intervaloEnPixels = (int)Math.Round(miLargoDelSegmentoMínimoEnPixels * factor);

            // Pone la unidad de la escala (metros o kilómetros).
            string unidad;
            int    exponenteDeLaEscala;

            if (exponenteDelSegmentoMínimo < 3)
            {
                unidad = "m";
                exponenteDeLaEscala = 0;
            }
            else
            {
                unidad = "km";
                exponenteDeLaEscala = 3;
            }
            int largoDelSegmentoEnMetrosOKilómetros = (int)Math.Round(largoDelSegmentoEnMetros / Math.Pow(10, exponenteDeLaEscala));

            #region Dibuja la Escala
            // Construye los puntos del segmento y los marcadores.
            const int largoMarcador     = 5;
            Point     marcadorIzquierdo = new Point(origenDelSegmentoEnPixels.X, origenDelSegmentoEnPixels.Y - largoMarcador);
            Point     finalDelSegmento  = new Point(origenDelSegmentoEnPixels.X + intervaloEnPixels, origenDelSegmentoEnPixels.Y);
            Point     marcadorDerecho   = new Point(origenDelSegmentoEnPixels.X + intervaloEnPixels, origenDelSegmentoEnPixels.Y - largoMarcador);
            Point[]   líneas            = new[] {
                marcadorIzquierdo,
                origenDelSegmentoEnPixels,
                finalDelSegmento,
                marcadorDerecho
            };

            // Dibuja el segmento y los marcadores con un fondo para que
            // tenga un buen contraste.
            miGráficador.DrawLines(miLápizDeFondoParaEscala, líneas);
            miGráficador.DrawLines(miLápizParaEscala, líneas);

            // Dibuja el texto.
            string texto = largoDelSegmentoEnMetrosOKilómetros + " " + unidad;
            DibujaTextoConFondo(texto, origenDelSegmentoEnPixels.X + 2, origenDelSegmentoEnPixels.Y - 14, miLetraParaEscala, miPincelParaEscala, miPincelDeFondoParaEscala);
            #endregion
        }
        /// <summary>
        /// Procesa un PDI.
        /// </summary>
        /// <param name="elPdi">El PDI.</param>
        /// <returns>El número de problemas detectados al procesar el elemento.</returns>
        protected override int ProcesaElemento(Pdi elPdi)
        {
            int númeroDeProblemasDetectados = 0;

            // Retorna si el PDI ya ha sido identificado como duplicado.
            if (misPdisDuplicados.Contains(elPdi))
            {
                return(númeroDeProblemasDetectados);
            }

            List <Pdi> duplicados = new List <Pdi>();

            // Busca en todos los PDIs desde la posición n + 1 que
            // no estén eliminados.
            for (int i = IndiceDeElementoProcesándose + 1; i < NúmeroDeElementos; ++i)
            {
                Pdi posiblePdiDuplicado = this[i];
                if (!posiblePdiDuplicado.FuéEliminado)
                {
                    // Si el PDI es idéntico entonces se puede borrar de una.
                    if (posiblePdiDuplicado.TieneLaMismaInformación(elPdi))
                    {
                        posiblePdiDuplicado.Elimina(string.Format(Properties.Recursos.M006, elPdi.Número));
                        misPdisDuplicados.Add(posiblePdiDuplicado);
                        ++miNúmeroDeElementosEliminados;
                    }
                    else
                    {
                        // Si el PDI no es idéntico entonces puede ser duplicado si:
                        //  - El tipo principal es el mismo, y
                        //  - La distancia es cercana, y
                        //      - El nombre es igual, o
                        //      - Uno es las siglas del otro, o
                        //      - El nombre es parecido.
                        if ((elPdi.Tipo != null) &&
                            (posiblePdiDuplicado.Tipo != null) &&
                            (((Tipo)elPdi.Tipo).TipoPrincipal == ((Tipo)posiblePdiDuplicado.Tipo).TipoPrincipal))
                        {
                            double distanciaEnMetros = Coordenadas.DistanciaEnMetros(elPdi.Coordenadas, posiblePdiDuplicado.Coordenadas);
                            if (distanciaEnMetros <= miDistanciaMáxima)
                            {
                                bool esDuplicado = false;

                                // Nombre es igual?
                                if (elPdi.Nombre == posiblePdiDuplicado.Nombre)
                                {
                                    esDuplicado = true;
                                }
                                // El PDI es las siglas del posible duplicado?
                                else if (PuedeSerSiglas(elPdi.Nombre))
                                {
                                    string siglasPosibleDuplicado = ObtieneSiglas(posiblePdiDuplicado.Nombre);

                                    if (elPdi.Nombre == siglasPosibleDuplicado)
                                    {
                                        esDuplicado = true;
                                    }
                                }
                                // El posible duplicado es las siglas del PDI?
                                else if (PuedeSerSiglas(posiblePdiDuplicado.Nombre))
                                {
                                    string siglasPdi = ObtieneSiglas(elPdi.Nombre);

                                    if (siglasPdi == posiblePdiDuplicado.Nombre)
                                    {
                                        esDuplicado = true;
                                    }
                                }
                                // El nombre es parecido?
                                else
                                {
                                    TstDictionary diccionario = new TstDictionary {
                                        { elPdi.Nombre, null }
                                    };
                                    ICollection resultados = diccionario.NearNeighbors(posiblePdiDuplicado.Nombre, miDistanciaHamming);

                                    // Como solo estamos comparando el nombre del PDI con el nombre del
                                    // posible duplicado, entonces al tener un solo resultado significa
                                    // que son parecidos.
                                    if (resultados.Count > 0)
                                    {
                                        esDuplicado = true;
                                    }
                                }

                                if (esDuplicado)
                                {
                                    duplicados.Add(posiblePdiDuplicado);
                                    misPdisDuplicados.Add(posiblePdiDuplicado);
                                }
                            }
                        }
                    }
                }
            }

            if (duplicados.Count > 0)
            {
                misGruposDeDuplicados.Add(elPdi, duplicados);
                ++númeroDeProblemasDetectados;
            }

            return(númeroDeProblemasDetectados);
        }