internal void GenerateProfile(GpxParser parser, string filePath) { using (Bitmap bmp = new Bitmap(bitmapRect.Width, bitmapRect.Height, PixelFormat.Format32bppPArgb)) { using (Font font = new Font("Tahoma", 10.0f)) { using (Graphics g = Graphics.FromImage(bmp)) { g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias; g.DrawRectangle(Pens.BlueViolet, graphRect); TrackPoint prevPoint = null; Track t = parser.Tracks[0]; double currPos = 0.0; minH = t.MinElevation; maxH = t.MaxElevation; maxW = t.Distance3D; PointF startPoint = GetLogicalPoint(0, minH); foreach (TrackSegment seg in t.Segments) { foreach (TrackPoint tp in seg.ReducedPoints) { if (prevPoint == null) { prevPoint = tp; continue; } currPos += tp - prevPoint; PointF endPoint = GetLogicalPoint(currPos, tp.ele); using (Pen p = new Pen(ColorProvider.GetColor(Math.Max(tp.ele, prevPoint.ele), minH, maxH))) g.DrawLine(p, startPoint, endPoint); prevPoint = tp; startPoint = endPoint; } } int heightRulerSpacing = Convert.ToInt32((maxH - minH) / 5); //suddivido in 5 segmenti heightRulerSpacing = (int)(Math.Ceiling(heightRulerSpacing / 10.0d) * 10); //arrotondo ai 10 metri double currH = Math.Round(minH / heightRulerSpacing, 0) * heightRulerSpacing; if (currH < minH) { currH += heightRulerSpacing; } StringFormat sf = new StringFormat(); sf.LineAlignment = StringAlignment.Far; sf.Alignment = StringAlignment.Far; g.DrawString(GetHeightLabel(minH), font, Brushes.Red, GetLogicalPoint(0, minH), sf); while (currH < maxH) { PointF p1 = GetLogicalPoint(0, currH); PointF p2 = GetLogicalPoint(maxW, currH); g.DrawLine(Pens.BlueViolet, p1, p2); using (Brush b = new SolidBrush(ColorProvider.GetColor(currH, minH, maxH))) g.DrawString(GetHeightLabel(currH), font, b, p1, sf); currH += heightRulerSpacing; } using (Brush b = new SolidBrush(ColorProvider.GetColor(maxH, minH, maxH))) g.DrawString(GetHeightLabel(maxH), font, b, GetLogicalPoint(0, maxH), sf); sf.Alignment = StringAlignment.Center; sf.LineAlignment = StringAlignment.Near; int widthRulerSpacing = Convert.ToInt32(maxW / 5); //suddivido in 5 segmenti Km widthRulerSpacing = (int)(Math.Ceiling(widthRulerSpacing / 100.0d) * 100); //arrotondo ai 100 metri double currW = widthRulerSpacing; while (currW < maxW) { PointF p1 = GetLogicalPoint(currW, minH); PointF p2 = GetLogicalPoint(currW, maxH); g.DrawLine(Pens.BlueViolet, p1, p2); g.DrawString(GetWidthLabel(currW), font, Brushes.BlueViolet, p1, sf); currW += widthRulerSpacing; } g.DrawString(GetWidthLabel(currW), font, Brushes.BlueViolet, GetLogicalPoint(maxW, minH), sf); g.DrawString("Distanza (Km)", font, Brushes.BlueViolet, graphRect.X + graphRect.Width / 2, graphRect.Bottom + 20, sf); sf.FormatFlags |= StringFormatFlags.DirectionVertical; g.DrawString("Altitudine (m)", font, Brushes.BlueViolet, graphRect.X - 70, graphRect.Top + graphRect.Height / 2, sf); } string path = Path.GetDirectoryName(filePath); if (!Directory.Exists(path)) { Directory.CreateDirectory(path); } bmp.Save(filePath); } } }
public TrackPoint(TrackPoint tp) : base(tp) { time = tp.time; }
/// <summary> /// The distance of a point from a line made from point1 and point2. /// </summary> /// <param name="pt1">The PT1.</param> /// <param name="pt2">The PT2.</param> /// <param name="p">The p.</param> /// <returns></returns> public static double PerpendicularDistance(TrackPoint Point1, TrackPoint Point2, TrackPoint Point) { //Area = |(1/2)(x1y2 + x2y3 + x3y1 - x2y1 - x3y2 - x1y3)| *Area of triangle //Base = v((x1-x2)²+(x1-x2)²) *Base of Triangle* //Area = .5*Base*H *Solve for height //Height = Area/.5/Base double area = Math.Abs(.5 * (Point1.lat * Point2.lon + Point2.lat * Point.lon + Point.lat * Point1.lon - Point2.lat * Point1.lon - Point.lat * Point2.lon - Point1.lat * Point.lon)); double bottom = Math.Sqrt(Math.Pow(Point1.lat - Point2.lat, 2) + Math.Pow(Point1.lon - Point2.lon, 2)); double height = area / bottom * 2; return(height); //Another option //double A = Point.lat - Point1.lat; //double B = Point.lon - Point1.lon; //double C = Point2.lat - Point1.lat; //double D = Point2.lon - Point1.lon; //double dot = A * C + B * D; //double len_sq = C * C + D * D; //double param = dot / len_sq; //double xx, yy; //if (param < 0) //{ // xx = Point1.lat; // yy = Point1.lon; //} //else if (param > 1) //{ // xx = Point2.lat; // yy = Point2.lon; //} //else //{ // xx = Point1.lat + param * C; // yy = Point1.lon + param * D; //} //double d = DistanceBetweenOn2DPlane(Point, new Point(xx, yy)); }
internal void Parse(XmlElement trackSegment) { TrackPoint prevPoint = null; foreach (XmlElement trackPoint in trackSegment.GetElementsByTagName("trkpt")) { TrackPoint point = new TrackPoint(); point.Parse(trackPoint); maxEle = Math.Max(point.ele, maxEle); minEle = Math.Min(point.ele, minEle); if (prevPoint != null) { double seg = point - prevPoint; linearDistance += seg; double h = point.ele - prevPoint.ele; if (h > 0) totalClimb += h; distance3D += Math.Sqrt(seg * seg + h * h); } prevPoint = point; points.Add(point); } }
/// <summary> /// The distance of a point from a line made from point1 and point2. /// </summary> /// <param name="pt1">The PT1.</param> /// <param name="pt2">The PT2.</param> /// <param name="p">The p.</param> /// <returns></returns> public static double PerpendicularDistance(TrackPoint Point1, TrackPoint Point2, TrackPoint Point) { //Area = |(1/2)(x1y2 + x2y3 + x3y1 - x2y1 - x3y2 - x1y3)| *Area of triangle //Base = v((x1-x2)²+(x1-x2)²) *Base of Triangle* //Area = .5*Base*H *Solve for height //Height = Area/.5/Base double area = Math.Abs(.5 * (Point1.lat * Point2.lon + Point2.lat * Point.lon + Point.lat * Point1.lon - Point2.lat * Point1.lon - Point.lat * Point2.lon - Point1.lat * Point.lon)); double bottom = Math.Sqrt(Math.Pow(Point1.lat - Point2.lat, 2) + Math.Pow(Point1.lon - Point2.lon, 2)); double height = area / bottom * 2; return height; //Another option //double A = Point.lat - Point1.lat; //double B = Point.lon - Point1.lon; //double C = Point2.lat - Point1.lat; //double D = Point2.lon - Point1.lon; //double dot = A * C + B * D; //double len_sq = C * C + D * D; //double param = dot / len_sq; //double xx, yy; //if (param < 0) //{ // xx = Point1.lat; // yy = Point1.lon; //} //else if (param > 1) //{ // xx = Point2.lat; // yy = Point2.lon; //} //else //{ // xx = Point1.lat + param * C; // yy = Point1.lon + param * D; //} //double d = DistanceBetweenOn2DPlane(Point, new Point(xx, yy)); }