예제 #1
0
 static FSofTUtils.Geometry.PolylineSimplification.PointListExt CreateProfileList(List <GpxPointExt> pt)
 {
     FSofTUtils.Geometry.PolylineSimplification.PointListExt profile = new FSofTUtils.Geometry.PolylineSimplification.PointListExt(pt.Count);
     profile.Set(0, 0, pt[0].Elevation);
     for (int i = 1; i < profile.Length; i++)
     {
         profile.Set(i,
                     profile.Get(i - 1).X + PointDistance(pt[i - 1], pt[i]),
                     pt[i].Elevation);
     }
     return(profile);
 }
예제 #2
0
        /// <summary>
        /// eine einfache statistische Anzeige für die Höhen der spez. Punktliste
        /// </summary>
        /// <param name="profile"></param>
        static void ShowHeightData(FSofTUtils.Geometry.PolylineSimplification.PointListExt profile)
        {
            double dAscent      = 0.0;
            double dDescent     = 0.0;
            double dMaxHeigth   = double.MinValue;
            double dMinHeigth   = double.MaxValue;
            double dStartHeigth = double.MaxValue;
            double dEndHeigth   = double.MaxValue;

            double dLastHeigth = double.MaxValue;

            for (int i = 0; i < profile.Length; i++)
            {
                if (profile.Get(i).IsValid)
                {
                    double heigth = profile.Get(i).Y;
                    if (dLastHeigth != double.MaxValue &&
                        heigth != double.MaxValue)
                    {
                        if (heigth - dLastHeigth > 0)
                        {
                            dAscent += heigth - dLastHeigth;
                        }
                        else
                        {
                            dDescent += dLastHeigth - heigth;
                        }
                    }
                    dLastHeigth = heigth;
                    if (heigth != double.MaxValue)
                    {
                        if (dMaxHeigth < heigth)
                        {
                            dMaxHeigth = heigth;
                        }
                        if (dMinHeigth > heigth)
                        {
                            dMinHeigth = heigth;
                        }
                        if (dStartHeigth == double.MaxValue)
                        {
                            dStartHeigth = heigth;
                        }
                        dEndHeigth = heigth;
                    }
                }
            }

            Console.Error.WriteLine(string.Format("      Start-/Endhöhe:    {0,6:F0} / {1,6:F0}m", dStartHeigth, dEndHeigth));
            Console.Error.WriteLine(string.Format("      Min./Max.:         {0,6:F0} / {1,6:F0}m", dMinHeigth, dMaxHeigth));
            Console.Error.WriteLine(string.Format("      Summe An-/Abstieg: {0,6:F0} / {1,6:F0}m", dAscent, -dDescent));
        }
예제 #3
0
 static FSofTUtils.Geometry.PolylineSimplification.PointListExt CreateList4Simplification(List <GpxTrackPoint> pt)
 {
     FSofTUtils.Geometry.PolylineSimplification.PointListExt lst = new FSofTUtils.Geometry.PolylineSimplification.PointListExt(pt.Count);
     lst.Set(0, 0, 0);
     lst.Get(0).IsLocked = true;
     for (int i = 1; i < lst.Length; i++)
     {
         GeoHelper.Wgs84ShortXYDelta(pt[i - 1].Lon, pt[i].Lon, pt[i - 1].Lat, pt[i].Lat, out double dx, out double dy);
         lst.Set(i,
                 lst.Get(i - 1).X + dx,
                 lst.Get(i - 1).Y + dy);
     }
     return(lst);
 }
예제 #4
0
        /// <summary>
        /// (horizontale) Trackvereinfachung
        /// </summary>
        /// <param name="type">Art des Vereinfachungalgorithmus</param>
        /// <param name="width">Streifenbreite, innerhalb der die Vereinfachung erfolgt</param>
        public void HorizontalSimplification(Options.HSimplification type, double width)
        {
            if (type != Options.HSimplification.Nothing)
            {
                Console.Error.WriteLine("horizontale Track-Vereinfachung: {0}", type.ToString());
                Console.Error.WriteLine("   Breite {0}", width);
                for (int t = 0; t < TrackCount(); t++)
                {
                    for (int s = 0; s < TrackSegmentCount(t); s++)
                    {
                        List <GpxTrackPoint> ptlst = GetTrackSegmentPointList(t, s);
                        if (ptlst.Count > 2)
                        {
                            Console.Error.Write("   Track {0}, Segment {1}, {2} Punkte, {3:F3}km", t + 1, s + 1, ptlst.Count, GetLength(ptlst) / 1000);
                            FSofTUtils.Geometry.PolylineSimplification.PointListExt pl = CreateList4Simplification(ptlst);
                            pl.Get(pl.Length - 1).IsLocked = true;

                            switch (type)
                            {
                            case Options.HSimplification.Reumann_Witkam:
                                pl.ReumannWitkam(width);
                                break;

                            case Options.HSimplification.Douglas_Peucker:
                                pl.DouglasPeucker(width);
                                break;
                            }

                            for (int p = pl.Length - 1; p > 0; p--)
                            {
                                if (!pl.Get(p).IsValid)
                                {
                                    DeleteTrackSegmentPoint(t, s, p);
                                    ptlst.RemoveAt(p);
                                }
                            }

                            Console.Error.WriteLine(" --> {0} Punkte, {1:F3}km",
                                                    TrackSegmentPointCount(t, s),
                                                    GetLength(ptlst) / 1000);
                        }
                    }
                }
            }
        }
예제 #5
0
        /// <summary>
        /// Entfernung von Punkten für einen "Rastplatz" (eine Mindestanzahl von aufeinanderfolgenden Punkten innerhalb eines bestimmten Radius
        /// mit einer bestimmten durchschnittlichen Mindestrichtungsänderung)
        /// </summary>
        /// <param name="mincount">Mindestanzahl von Punkten</param>
        /// <param name="maxradius1">Radius</param>
        /// <param name="minturnaround">durchschnittlichen Mindestrichtungsänderung</param>
        public void RemoveRestingplace(int ptcount,
                                       int crossing1, double maxradius1, double minturnaround1,
                                       int crossing2, double maxradius2, double minturnaround2,
                                       string protfile = null)
        {
            if (ptcount >= 3 &&
                crossing1 >= 0 && maxradius1 > 0 && minturnaround1 > 0 &&
                crossing2 > 0 && maxradius2 > 0 && minturnaround2 > 0)
            {
                Console.Error.WriteLine("horizontale 'Rastplatz'-Entfernung");
                Console.Error.WriteLine("   Punktanzahl {0}", ptcount, crossing1, maxradius1, minturnaround1);
                Console.Error.WriteLine("      Kreuzungen {0}, Radius {1}m, durchschnittl. Richtungsänderung {2}°", crossing1, maxradius1, minturnaround1);
                Console.Error.WriteLine("      Kreuzungen {0}, Radius {1}m, durchschnittl. Richtungsänderung {2}°", crossing2, maxradius2, minturnaround2);

                for (int t = 0; t < TrackCount(); t++)
                {
                    for (int s = 0; s < TrackSegmentCount(t); s++)
                    {
                        List <GpxTrackPoint> ptlst = GetTrackSegmentPointList(t, s);

                        Console.Error.WriteLine("   Track {0}, Segment {1}, {2} Punkte", t + 1, s + 1, ptlst.Count);

                        FSofTUtils.Geometry.PolylineSimplification.PointListExt lst = CreateList4Simplification(ptlst);
                        lst.RemoveRestingplace(ptcount, crossing1, maxradius1, minturnaround1, crossing2, maxradius2, minturnaround2, protfile);

                        int           lastvalid  = -1;
                        int           lstunvalid = -1;
                        List <string> sDel       = new List <string>();
                        for (int p = lst.Length - 1; p > 0; p--)
                        {
                            if (!lst.Get(p).IsValid)
                            {
                                DeleteTrackSegmentPoint(t, s, p);
                                lstunvalid = p;
                            }
                            else
                            {
                                if (lstunvalid >= 0)
                                {
                                    sDel.Add(string.Format("{0}-{1}", lstunvalid + 1, lastvalid));
                                    lstunvalid = -1;
                                }
                                lastvalid = p;
                            }
                        }
                        if (sDel.Count > 0)
                        {
                            Console.Error.Write("   gelöscht: ");
                            for (int i = sDel.Count - 1; i >= 0; i--)
                            {
                                Console.Error.Write(sDel[i] + (i > 0 ? "," : ""));
                            }
                            Console.Error.WriteLine();
                        }

                        Console.Error.WriteLine("   --> {0} Punkte", TrackSegmentPointCount(t, s));

                        //Console.Error.WriteLine(string.Format("      {0} Punkte wegen zu hoher Geschwindigkeit entfernt", removed.Count));
                    }
                }
            }
        }
예제 #6
0
        /// <summary>
        /// Höhenglättung der Tracks
        /// </summary>
        /// <param name="type">Art des Vereinfachungalgorithmus</param>
        /// <param name="width">Parameter für den Vereinfachungalgorithmus</param>
        public void VerticalSimplification(Options.VSimplification type, double width)
        {
            if (type != Options.VSimplification.Nothing)
            {
                Console.Error.WriteLine("vertikale Track-Glättung: {0}", type.ToString());
                switch (type)
                {
                case Options.VSimplification.SlidingMean:
                    int ptcount = Math.Max(2, (int)Math.Round(width));  // >= 2
                    width = ptcount;
                    Console.Error.WriteLine("   {0} Punkte", width);
                    break;

                case Options.VSimplification.SlidingIntegral:
                    Console.Error.WriteLine("   Breite {0}m", width);
                    break;
                }

                for (int t = 0; t < TrackCount(); t++)
                {
                    for (int s = 0; s < TrackSegmentCount(t); s++)
                    {
                        List <GpxTrackPoint> pt = GetTrackSegmentPointList(t, s);

                        Console.Error.Write("   Track {0}, Segment {1}, {2} Punkte", t + 1, s + 1, pt.Count);

                        bool bPointsNotValid = false;
                        for (int i = 0; i < pt.Count; i++)
                        {
                            if (pt[i].Elevation == GpxTrackPoint.NOTVALID_DOUBLE)
                            {
                                bPointsNotValid = true;
                                break;
                            }
                        }
                        if (bPointsNotValid || pt.Count < 2)
                        {
                            Console.Error.WriteLine(": zu wenig Punkte oder Punkte ohne Höhenangabe");
                            continue;
                        }
                        Console.Error.WriteLine();

                        // Daten übernehmen
                        FSofTUtils.Geometry.PolylineSimplification.PointListExt profile = CreateProfileList(pt);
                        Console.Error.WriteLine(string.Format("   Gesamtlänge:        {0:F0}m", profile.Get(profile.Length - 1).X));

                        Console.Error.WriteLine("   Ausgangsdaten:");
                        ShowHeightData(profile);

                        switch (type)
                        {
                        case Options.VSimplification.SlidingMean:
                            profile.HeigthProfileWithSlidingMean(Math.Max(3, (int)Math.Round(width)));
                            break;

                        case Options.VSimplification.SlidingIntegral:
                            profile.HeigthProfileWithSlidingIntegral(width);
                            break;
                        }
                        Console.Error.WriteLine("   geglättete Daten:");
                        ShowHeightData(profile);

                        // Daten speichern
                        for (int p = 0; p < profile.Length; p++)
                        {
                            ChangeTrackSegmentPointData(t, s, p, BaseElement.NOTUSE_TIME, profile.Get(p).Y);
                        }
                    }
                }
            }
        }