public PublishMapForm(Document document, WaypointAttribute colorCodingAttribute, WaypointAttribute?secondaryColorCodingAttribute, ColorRangeProperties colorRangeProperties) { InitializeComponent(); this.document = document; this.colorCodingAttribute = colorCodingAttribute; this.secondaryColorCodingAttribute = secondaryColorCodingAttribute; this.colorRangeProperties = colorRangeProperties; foreach (var setting in Util.ApplicationSettings.PublishMapSettings) { if (!webServiceURL.Items.Contains(setting.WebServiceURL)) { webServiceURL.Items.Add(setting.WebServiceURL); } } if (webServiceURL.Items.Count > 0) { webServiceURL.SelectedIndex = 0; } var defaultTime = DateTime.Now.ToLocalTime().Date; if (document.Sessions.Count > 0 && document.Sessions[0].Route.FirstWaypoint != null) { defaultTime = document.Sessions[0].Route.FirstWaypoint.Time.ToLocalTime(); } date.Value = defaultTime; SetControlEnabledState(false); imageFormat.SelectedIndex = 0; }
public PublishMapForm(Document document, WaypointAttribute colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, ColorRangeProperties colorRangeProperties) { InitializeComponent(); this.document = document; this.colorCodingAttribute = colorCodingAttribute; this.secondaryColorCodingAttribute = secondaryColorCodingAttribute; this.colorRangeProperties = colorRangeProperties; foreach (var setting in Util.ApplicationSettings.PublishMapSettings) { if (!webServiceURL.Items.Contains(setting.WebServiceURL)) { webServiceURL.Items.Add(setting.WebServiceURL); } } if (webServiceURL.Items.Count > 0) webServiceURL.SelectedIndex = 0; var defaultTime = DateTime.Now.ToLocalTime().Date; if (document.Sessions.Count > 0 && document.Sessions[0].Route.FirstWaypoint != null) { defaultTime = document.Sessions[0].Route.FirstWaypoint.Time.ToLocalTime(); } date.Value = defaultTime; SetControlEnabledState(false); imageFormat.SelectedIndex = 0; }
public static NumericConverter GetNumericConverterFromWaypointAttribute(WaypointAttribute wa) { switch (wa) { case WaypointAttribute.Pace: case WaypointAttribute.MapReadingDuration: return(new TimeConverter(TimeConverter.TimeConverterType.ElapsedTime)); case WaypointAttribute.Speed: return(new NumericConverter()); case WaypointAttribute.DirectionDeviationToNextLap: return(new NumericConverter { NoOfDecimals = 0 }); default: return(new IntConverter()); } }
private void OpenInGoogleEarth(Document document, WaypointAttribute? colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, ColorRangeProperties colorRangeProperties) { if (document == null) throw new ArgumentNullException("document"); // set default values if (!colorCodingAttribute.HasValue) colorCodingAttribute = SelectedColorCodingAttribute; if (colorRangeProperties == null) colorRangeProperties = GetCurrentColorRangeProperties(); using (var kmlPropertySelector = new KmlPropertySelectorDialog(ApplicationSettings.ExportKmlProperties) { DialogTitle = Strings.OpenInGoogleEarth }) { var result = kmlPropertySelector.ShowDialog(); if (result == DialogResult.OK) { BeginWork(); try { ApplicationSettings.ExportKmlProperties = kmlPropertySelector.Properties; using (var stream = new MemoryStream()) { CreateKmz(document, stream, kmlPropertySelector.Properties, colorCodingAttribute.Value, secondaryColorCodingAttribute, colorRangeProperties); GoogleEarthUtil.OpenInGoogleEarth(stream); stream.Close(); } EndWork(); } catch (Exception ex) { EndWork(); Util.ShowExceptionMessageBox(Strings.Error_GoogleEarthNotInstalledMessage, ex, Strings.Error_GoogleEarthNotInstalledTitle); } } } }
public static NumericConverter GetNumericConverterFromWaypointAttribute(WaypointAttribute wa) { switch (wa) { case WaypointAttribute.Pace: case WaypointAttribute.MapReadingDuration: return new TimeConverter(TimeConverter.TimeConverterType.ElapsedTime); case WaypointAttribute.Speed: return new NumericConverter(); case WaypointAttribute.DirectionDeviationToNextLap: return new NumericConverter { NoOfDecimals = 0 }; default: return new IntConverter(); } }
private void OpenInGoogleEarth(string documentFileName, WaypointAttribute? colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, ColorRangeProperties colorRangeProperties) { var document = Document.Open(documentFileName); try { OpenInGoogleEarth(document, colorCodingAttribute, secondaryColorCodingAttribute, colorRangeProperties); } catch (Exception) { MessageBox.Show(Strings.Error_InvalidQuickRouteFile, Strings.OpenInGoogleEarth, MessageBoxButtons.OK, MessageBoxIcon.Error); } }
// todo: skip showRouteLine parameter, use RouteDrawingMode instead public Bitmap CreateMapAndRouteImage(bool showRouteLine, double zoomValue, Session sessionToDraw, List <int> legsToDraw, double frameWidth, WaypointAttribute colorCodingAttribute, WaypointAttribute?secondaryColorCodingAttribute, RouteDrawingMode mode, SessionSettings sessionSettings) { RectangleD frame = GetFrame(zoomValue, sessionToDraw, legsToDraw, frameWidth, colorCodingAttribute, mode); var sc = new SessionCollection(); sc.Add(sessionToDraw); var wholeImage = CreateMapAndRouteImage(true, zoomValue, sc, colorCodingAttribute, secondaryColorCodingAttribute, mode, sessionSettings); AdjustFrameToImage(frame, wholeImage); var croppedImage = new Bitmap( Convert.ToInt32(Math.Ceiling(frame.Right) - Math.Floor(frame.Left)), Convert.ToInt32(Math.Ceiling(frame.Bottom) - Math.Floor(frame.Top))); var croppedImageGraphics = Graphics.FromImage(croppedImage); croppedImageGraphics.DrawImage( wholeImage, -Convert.ToInt32(Math.Floor(frame.Left)), -Convert.ToInt32(Math.Floor(frame.Top))); croppedImageGraphics.Dispose(); wholeImage.Dispose(); return(croppedImage); }
private static RectangleD GetFrame(double zoomValue, Session sessionToDraw, IList <int> legsToDraw, double frameWidth, WaypointAttribute colorCodingAttribute, RouteDrawingMode mode) { var vertices = sessionToDraw.GetAdjustedWaypointLocations(legsToDraw); var rls = sessionToDraw.Settings.RouteLineSettingsCollection[colorCodingAttribute]; double lineRadius = 0; switch (mode) { case RouteDrawingMode.Simple: lineRadius = rls.MonochromeWidth / 2; break; case RouteDrawingMode.Extended: lineRadius = (rls.Width + (rls.MaskVisible ? 2 * rls.MaskWidth : 0)) / 2; break; case RouteDrawingMode.None: lineRadius = 0; break; } double minX = zoomValue * (vertices[0].X - lineRadius); double maxX = zoomValue * (vertices[0].X + lineRadius); double minY = zoomValue * (vertices[0].Y - lineRadius); double maxY = zoomValue * (vertices[0].Y + lineRadius); for (int i = 0; i < vertices.Count; i++) { minX = Math.Min(minX, zoomValue * (vertices[i].X - lineRadius)); maxX = Math.Max(maxX, zoomValue * (vertices[i].X + lineRadius)); minY = Math.Min(minY, zoomValue * (vertices[i].Y - lineRadius)); maxY = Math.Max(maxY, zoomValue * (vertices[i].Y + lineRadius)); } double maxWidth = Math.Max(maxX - minX, maxY - minY); return(new RectangleD(new PointD(minX - frameWidth * maxWidth, minY - frameWidth * maxWidth), new SizeD(maxX - minX + 2 * frameWidth * maxWidth, maxY - minY + 2 * frameWidth * maxWidth))); }
private void CreateKmz(Document document, Stream stream, KmlProperties kmlProperties, WaypointAttribute colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, ColorRangeProperties colorRangeProperties) { var imageExporterProperties = new ImageExporterProperties() { ColorCodingAttribute = colorCodingAttribute, SecondaryColorCodingAttribute = secondaryColorCodingAttribute, ColorRangeProperties = colorRangeProperties }; var imageExporter = new ImageExporter(document) { Properties = imageExporterProperties }; var kmlExporter = new KmlExporter(document, imageExporter, stream) { KmlProperties = kmlProperties }; kmlExporter.ExportKmz(CommonUtil.GetTempFileName() + @"\"); }
/// <summary> /// Returns the original heart rate or altitude. /// </summary> /// <param name="attribute">Must be WaypointAttribute.HeartRate or WaypointAttribute.Altitude</param> /// <returns></returns> public double? GetOriginalAttribute(WaypointAttribute attribute) { if (attribute != WaypointAttribute.HeartRate && attribute != WaypointAttribute.Altitude) throw new ArgumentException("The 'attribute' parameter must be either WaypointAttribute.HeartRate or WaypointAttribute.Altitude."); switch (attribute) { case WaypointAttribute.HeartRate: return HeartRate; case WaypointAttribute.Altitude: return Altitude; } return null; }
private void CalculateSlidingAverageAttributes(WaypointAttribute attribute, Interval smoothingInterval) { // using optimized but hard-to-understand algorithm if (attribute != WaypointAttribute.HeartRate && attribute != WaypointAttribute.Altitude) throw new ArgumentException("The 'attribute' parameter must be either WaypointAttribute.HeartRate or WaypointAttribute.Altitude"); bool zeroLengthInterval = smoothingInterval.Length == 0; bool containsAttribute = ContainsWaypointAttribute(attribute); ParameterizedLocation siStartPL = null; ParameterizedLocation siEndPL = null; if (!zeroLengthInterval) { siStartPL = GetParameterizedLocationFromTime(FirstWaypoint.Time.AddSeconds(smoothingInterval.Start)); siEndPL = GetParameterizedLocationFromTime(FirstWaypoint.Time.AddSeconds(smoothingInterval.End)); } for (int i = 0; i < segments.Count; i++) { double[] valueSums = null; bool[] valueIsSet = null; DateTime[] valueTimes = null; var nullValueFound = false; if (containsAttribute && !zeroLengthInterval) { valueSums = new double[segments[i].Waypoints.Count]; valueIsSet = new bool[segments[i].Waypoints.Count]; valueTimes = new DateTime[segments[i].Waypoints.Count]; valueSums[0] = 0; if (segments[i].Waypoints.Count > 0) { valueIsSet[0] = segments[i].Waypoints[0].GetOriginalAttribute(attribute).HasValue; valueTimes[0] = segments[i].Waypoints[0].Time; nullValueFound = !valueIsSet[0]; } for (int j = 1; j < segments[i].Waypoints.Count; j++) { var previousWaypoint = segments[i].Waypoints[j - 1]; var thisWaypoint = segments[i].Waypoints[j]; var previousOriginalAttribute = previousWaypoint.GetOriginalAttribute(attribute); var thisOriginalAttribute = thisWaypoint.GetOriginalAttribute(attribute); valueIsSet[j] = thisOriginalAttribute.HasValue; valueTimes[j] = thisWaypoint.Time; nullValueFound = nullValueFound || !valueIsSet[j]; if (valueIsSet[j - 1] && valueIsSet[j]) { valueSums[j] = valueSums[j - 1] + (valueTimes[j] - valueTimes[j - 1]).TotalSeconds * (previousOriginalAttribute.Value + thisOriginalAttribute.Value) / 2; } else { valueSums[j] = valueSums[j - 1]; } } } for (int j = 0; j < segments[i].Waypoints.Count; j++) { Waypoint w = segments[i].Waypoints[j]; if (!containsAttribute) { w.Attributes[attribute] = null; } else if (zeroLengthInterval) { w.Attributes[attribute] = w.GetOriginalAttribute(attribute); } else { // start of sliding interval siStartPL = GetParameterizedLocationFromTime(w.Time.AddSeconds(smoothingInterval.Start), siStartPL, ParameterizedLocation.Direction.Forward); // end of sliding interval siEndPL = GetParameterizedLocationFromTime(w.Time.AddSeconds(smoothingInterval.End), siEndPL, ParameterizedLocation.Direction.Forward); if (siStartPL != null && siEndPL != null) { if (siStartPL.SegmentIndex < i) siStartPL = new ParameterizedLocation(i, 0); if (siEndPL.SegmentIndex > i) siEndPL = new ParameterizedLocation(i, segments[i].Waypoints.Count - 1); double startSum; double endSum; var adjustedIntervalLength = (GetTimeFromParameterizedLocation(siEndPL) - GetTimeFromParameterizedLocation(siStartPL)).TotalSeconds; int startIndex; int endIndex; if (siStartPL.IsNode) { startSum = valueSums[(int)siStartPL.Value]; startIndex = (int)siStartPL.Value; } else { var d = siStartPL.Value - Math.Floor(siStartPL.Value); startSum = (1 - d) * valueSums[(int)siStartPL.Value] + d * valueSums[(int)siStartPL.Value + 1]; startIndex = (int)siStartPL.Value; } if (siEndPL.IsNode) { endSum = valueSums[(int)siEndPL.Value]; endIndex = (int)siEndPL.Value; } else { var d = siEndPL.Value - Math.Floor(siEndPL.Value); endSum = (1 - d) * valueSums[(int)siEndPL.Value] + d * valueSums[(int)siEndPL.Value + 1]; endIndex = (int)siEndPL.Value + 1; } if (adjustedIntervalLength == 0) { w.Attributes[attribute] = w.GetOriginalAttribute(attribute); } else { // check if there are any null values in this interval bool nullValueFoundInInterval; if (!nullValueFound) { // no null value in whole route, don't need to check this interval nullValueFoundInInterval = false; } else { // there is at least one null value in the route, need to check if there exists any in this interval nullValueFoundInInterval = false; for (var k = startIndex; k <= endIndex; k++) { if (!valueIsSet[k]) { nullValueFoundInInterval = true; break; } } } if (!nullValueFoundInInterval) { // no null values in this interval, perform normal calculation w.Attributes[attribute] = (endSum - startSum) / adjustedIntervalLength; } else { // null value found, calculate based on each non-null value waypoint pair adjustedIntervalLength = 0; double sum = 0; for (var k = startIndex; k < endIndex; k++) { if (valueIsSet[k] && valueIsSet[k + 1]) { double start = Math.Max(k, siStartPL.Value); double end = Math.Min(k + 1, siEndPL.Value); adjustedIntervalLength += (end - start) * (valueTimes[k + 1] - valueTimes[k]).TotalSeconds; sum += (end - start) * (valueSums[k + 1] - valueSums[k]); } } w.Attributes[attribute] = (adjustedIntervalLength == 0 ? (double?)null : sum / adjustedIntervalLength); } } } else { w.Attributes[attribute] = null; } } } } }
public Bitmap CreateMapAndRouteImage(bool showMap, double zoomValue, SessionCollection sessionsToDraw, WaypointAttribute colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, RouteDrawingMode mode, SessionSettings sessionSettings) { Bitmap mapImage; if(showMap) { mapImage = CreateMapImage(zoomValue); } else { var size = GetMapImageSize(zoomValue); mapImage = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppPArgb); } if (mode == RouteDrawingMode.None) return mapImage; var mapAndRouteImage = new Bitmap(mapImage.Width, mapImage.Height, PixelFormat.Format32bppPArgb); var mapAndRouteGraphics = Graphics.FromImage(mapAndRouteImage); mapAndRouteGraphics.SmoothingMode = SmoothingMode.AntiAlias; DrawRoutes(sessionsToDraw, zoomValue, mapAndRouteGraphics, mapImage, mode, colorCodingAttribute, secondaryColorCodingAttribute, sessionSettings); mapAndRouteGraphics.Dispose(); mapImage.Dispose(); return mapAndRouteImage; }
/// <summary> /// Gets the values at the specified percentage when the attribute values are sorted. /// </summary> /// <param name="attribute"></param> /// <param name="percentage"></param> /// <param name="samplingInterval"></param> /// <returns></returns> public double? GetOrderedValue(WaypointAttribute attribute, double percentage, TimeSpan samplingInterval) { List<double?> list = GetMomentaneousValueList( attribute, GetParameterizedLocationFromTime(FirstWaypoint.Time), GetParameterizedLocationFromTime(LastWaypoint.Time), samplingInterval); list.Sort(); var i = (int)(percentage * list.Count); return list[Math.Min(i, list.Count - 1)]; }
/// <summary> /// Gets the values at each percentage specified in the percentages list when the attribute values are sorted. /// </summary> /// <param name="attribute"></param> /// <param name="percentages"></param> /// <param name="samplingInterval"></param> /// <returns></returns> public List<double?> GetOrderedValues(WaypointAttribute attribute, List<double> percentages, TimeSpan samplingInterval) { List<double?> list = GetMomentaneousValueList( attribute, GetParameterizedLocationFromTime(FirstWaypoint.Time), GetParameterizedLocationFromTime(LastWaypoint.Time), samplingInterval); list.Sort(); var values = new List<double?>(); foreach (double percentage in percentages) { var i = (int)(percentage * list.Count); int index = Math.Min(i, list.Count - 1); if (index >= 0) values.Add(list[index]); } return values; }
public List<double?> GetMomentaneousValueList(WaypointAttribute attribute, ParameterizedLocation startPL, ParameterizedLocation endPL, TimeSpan samplingInterval) { DateTime time = GetTimeFromParameterizedLocation(startPL); DateTime endTime = GetTimeFromParameterizedLocation(endPL); ParameterizedLocation previousPL = GetParameterizedLocationOfPreviousWaypoint(startPL, false); ParameterizedLocation nextPL = GetParameterizedLocationOfNextWaypoint(startPL, true); Waypoint previousWaypoint = GetClosestWaypointFromParameterizedLocation(previousPL); Waypoint nextWaypoint = GetClosestWaypointFromParameterizedLocation(nextPL); var values = new List<double?>(); while (time < endTime) { double t0 = time.Subtract(previousWaypoint.Time).TotalSeconds; double t1 = nextWaypoint.Time.Subtract(previousWaypoint.Time).TotalSeconds; double t = (t1 > 0 ? t0 / t1 : 0); double? value = GetAttributeValueBetweenWaypoints(previousWaypoint, nextWaypoint, 1 - t, attribute); values.Add(value); // is there a waypoint before next sample time? DateTime nextSampleTime = time.Add(samplingInterval); while (nextWaypoint.Time <= nextSampleTime && nextSampleTime < endTime) { previousPL = nextPL; nextPL = GetParameterizedLocationOfNextWaypoint(nextPL, true); if (previousPL.SegmentIndex != nextPL.SegmentIndex) { // moved to next segment previousPL = nextPL; nextPL = GetParameterizedLocationOfNextWaypoint(nextPL, true); previousWaypoint = GetClosestWaypointFromParameterizedLocation(previousPL); nextWaypoint = GetClosestWaypointFromParameterizedLocation(nextPL); nextSampleTime = previousWaypoint.Time; } else { previousWaypoint = nextWaypoint; nextWaypoint = GetClosestWaypointFromParameterizedLocation(nextPL); } } time = nextSampleTime; } return values; }
public double? GetAttributeFromParameterizedLocation(WaypointAttribute attribute, ParameterizedLocation parameterizedLocation) { List<Waypoint> waypoints = segments[parameterizedLocation.SegmentIndex].Waypoints; if (parameterizedLocation.IsNode) { return waypoints[(int)parameterizedLocation.Value].Attributes.ContainsKey(attribute) ? waypoints[(int)parameterizedLocation.Value].Attributes[attribute] : null; } var i = (int)parameterizedLocation.Floor().Value; if (i >= waypoints.Count - 1) i = waypoints.Count - 2; if (waypoints.Count < 2) return waypoints[0].Attributes[attribute]; double d = parameterizedLocation.Value - i; return GetAttributeValueBetweenWaypoints(waypoints[i], waypoints[i + 1], d, attribute); }
/// <summary> /// Returns true if there are NO null values for the specified attributes in the segments. /// </summary> /// <param name="attribute"></param> /// <returns></returns> public bool ContainsWaypointAttribute(WaypointAttribute attribute) { return waypointAttributeExists[attribute]; }
private void UpdateColorRangeInterval(WaypointAttribute attribute, double minValue, double maxValue, bool setSlidersToMinAndMax) { // prevent too high paces if (attribute == WaypointAttribute.Pace && minValue > 30 * 60) minValue = 30 * 60; if (attribute == WaypointAttribute.Pace && maxValue > 30 * 60) maxValue = 30 * 60; ColorRangeIntervalSliderSettings sliderSettings = canvas.Document.Settings.ColorRangeIntervalSliderSettings[attribute]; RouteLineSettings rls = canvas.CurrentSession.Settings.RouteLineSettingsCollection[attribute]; updatingUINowCounter++; sliderSettings.MinValue = minValue; sliderSettings.MaxValue = maxValue; if (setSlidersToMinAndMax) { rls.ColorRange.StartValue = sliderSettings.MinValue; rls.ColorRange.EndValue = sliderSettings.MaxValue; } else { if (rls.ColorRange.StartValue < sliderSettings.MinValue) rls.ColorRange.StartValue = sliderSettings.MinValue; if (rls.ColorRange.StartValue > sliderSettings.MaxValue) rls.ColorRange.StartValue = sliderSettings.MaxValue; if (rls.ColorRange.EndValue < sliderSettings.MinValue) rls.ColorRange.EndValue = sliderSettings.MinValue; if (rls.ColorRange.EndValue > sliderSettings.MaxValue) rls.ColorRange.EndValue = sliderSettings.MaxValue; } updatingUINowCounter--; }
public void DrawRoutes(IEnumerable<Session> sessionsToDraw, double zoom, Graphics graphics, Image mapImage, RouteDrawingMode mode, WaypointAttribute colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, SessionSettings sessionSettings) { graphics.Clip = new Region(new Rectangle(0, 0, mapImage.Width, mapImage.Height)); // copy map as a background to route graphics.DrawImage(mapImage, new Point(0, 0)); // draw the routes foreach (var s in sessionsToDraw) { s.DrawRoute(zoom, graphics, mode, colorCodingAttribute, secondaryColorCodingAttribute, sessionSettings); } }
private static List<double> GetAutoAdjustColorRangeIntervalPercentages(WaypointAttribute attribute) { // use different start and end percentages for different waypoint attributes switch (attribute) { case WaypointAttribute.Altitude: return new List<double>(new double[] { 0, 1 }); case WaypointAttribute.HeartRate: return new List<double>(new double[] { 0.1, 1 }); case WaypointAttribute.DirectionDeviationToNextLap: return new List<double>(new double[] { 0, 0.9 }); case WaypointAttribute.MapReadingDuration: return new List<double>(new double[] { 0, 1.1 }); default: return new List<double>(new double[] { 0.1, 0.9 }); } }
// w0 and w1 are adjacent, t measured from w0 private static double? GetAttributeValueBetweenWaypoints(Waypoint w0, Waypoint w1, double t, WaypointAttribute attribute) { switch(attribute) { case WaypointAttribute.MapReadingDuration: return w0.MapReadingState == MapReadingState.StartReading || w0.MapReadingState == MapReadingState.Reading ? w0.Attributes[WaypointAttribute.MapReadingDuration] : null; case WaypointAttribute.MapReadingState: return GetAttributeValueBetweenWaypoints(w0, w1, t, WaypointAttribute.MapReadingDuration) != null ? 1 : 0; case WaypointAttribute.PreviousMapReadingEnd: return w1.Attributes[WaypointAttribute.PreviousMapReadingEnd] != null ? (double?)(w1.Attributes[WaypointAttribute.PreviousMapReadingEnd].Value - (1 - t) * (w1.Time - w0.Time).TotalSeconds) : null; case WaypointAttribute.NextMapReadingStart: return w0.Attributes[WaypointAttribute.NextMapReadingStart] != null ? (double?)(w0.Attributes[WaypointAttribute.NextMapReadingStart].Value - t * (w1.Time - w0.Time).TotalSeconds) : null; default: if (w0.Attributes.ContainsKey(attribute) && w1.Attributes.ContainsKey(attribute)) { var d0 = w0.Attributes[attribute]; var d1 = w1.Attributes[attribute]; if (d0.HasValue && d1.HasValue) return d0 + t * (d1 - d0); if (!d0.HasValue && !d1.HasValue) return null; return (t < 0.5 ? d0 : d1); } return null; } }
public void DrawRoutes(IEnumerable <Session> sessionsToDraw, double zoom, Graphics graphics, Image mapImage, RouteDrawingMode mode, WaypointAttribute colorCodingAttribute, WaypointAttribute?secondaryColorCodingAttribute, SessionSettings sessionSettings) { graphics.Clip = new Region(new Rectangle(0, 0, mapImage.Width, mapImage.Height)); // copy map as a background to route graphics.DrawImage(mapImage, new Point(0, 0)); // draw the routes foreach (var s in sessionsToDraw) { s.DrawRoute(zoom, graphics, mode, colorCodingAttribute, secondaryColorCodingAttribute, sessionSettings); } }
private bool CheckIfWaypointAttributeExists(WaypointAttribute attribute) { foreach (RouteSegment segment in Segments) { foreach (Waypoint waypoint in segment.Waypoints) { switch (attribute) { case WaypointAttribute.Altitude: if (waypoint.Altitude != null) return true; break; case WaypointAttribute.HeartRate: if (waypoint.HeartRate != null) return true; break; case WaypointAttribute.MapReadingDuration: if (waypoint.MapReadingState != null) return true; break; case WaypointAttribute.Cadence: if (waypoint.Cadence != null) return true; break; case WaypointAttribute.Power: if (waypoint.Power != null) return true; break; } } } return false; }
// todo: skip showRouteLine parameter, use RouteDrawingMode instead public Bitmap CreateMapAndRouteImage(bool showRouteLine, double zoomValue, Session sessionToDraw, List<int> legsToDraw, double frameWidth, WaypointAttribute colorCodingAttribute, WaypointAttribute? secondaryColorCodingAttribute, RouteDrawingMode mode, SessionSettings sessionSettings) { RectangleD frame = GetFrame(zoomValue, sessionToDraw, legsToDraw, frameWidth, colorCodingAttribute, mode); var sc = new SessionCollection(); sc.Add(sessionToDraw); var wholeImage = CreateMapAndRouteImage(true, zoomValue, sc, colorCodingAttribute, secondaryColorCodingAttribute, mode, sessionSettings); AdjustFrameToImage(frame, wholeImage); var croppedImage = new Bitmap( Convert.ToInt32(Math.Ceiling(frame.Right) - Math.Floor(frame.Left)), Convert.ToInt32(Math.Ceiling(frame.Bottom) - Math.Floor(frame.Top))); var croppedImageGraphics = Graphics.FromImage(croppedImage); croppedImageGraphics.DrawImage( wholeImage, -Convert.ToInt32(Math.Floor(frame.Left)), -Convert.ToInt32(Math.Floor(frame.Top))); croppedImageGraphics.Dispose(); wholeImage.Dispose(); return croppedImage; }
public Bitmap CreateMapAndRouteImage(bool showMap, double zoomValue, SessionCollection sessionsToDraw, WaypointAttribute colorCodingAttribute, WaypointAttribute?secondaryColorCodingAttribute, RouteDrawingMode mode, SessionSettings sessionSettings) { Bitmap mapImage; if (showMap) { mapImage = CreateMapImage(zoomValue); } else { var size = GetMapImageSize(zoomValue); mapImage = new Bitmap(size.Width, size.Height, PixelFormat.Format32bppPArgb); } if (mode == RouteDrawingMode.None) { return(mapImage); } var mapAndRouteImage = new Bitmap(mapImage.Width, mapImage.Height, PixelFormat.Format32bppPArgb); var mapAndRouteGraphics = Graphics.FromImage(mapAndRouteImage); mapAndRouteGraphics.SmoothingMode = SmoothingMode.AntiAlias; DrawRoutes(sessionsToDraw, zoomValue, mapAndRouteGraphics, mapImage, mode, colorCodingAttribute, secondaryColorCodingAttribute, sessionSettings); mapAndRouteGraphics.Dispose(); mapImage.Dispose(); return(mapAndRouteImage); }
private static RectangleD GetFrame(double zoomValue, Session sessionToDraw, IList<int> legsToDraw, double frameWidth, WaypointAttribute colorCodingAttribute, RouteDrawingMode mode) { var vertices = sessionToDraw.GetAdjustedWaypointLocations(legsToDraw); var rls = sessionToDraw.Settings.RouteLineSettingsCollection[colorCodingAttribute]; double lineRadius = 0; switch(mode) { case RouteDrawingMode.Simple: lineRadius = rls.MonochromeWidth/2; break; case RouteDrawingMode.Extended: lineRadius = (rls.Width + (rls.MaskVisible ? 2 * rls.MaskWidth : 0)) / 2; break; case RouteDrawingMode.None: lineRadius = 0; break; } double minX = zoomValue * (vertices[0].X - lineRadius); double maxX = zoomValue * (vertices[0].X + lineRadius); double minY = zoomValue * (vertices[0].Y - lineRadius); double maxY = zoomValue * (vertices[0].Y + lineRadius); for (int i = 0; i < vertices.Count; i++) { minX = Math.Min(minX, zoomValue * (vertices[i].X - lineRadius)); maxX = Math.Max(maxX, zoomValue * (vertices[i].X + lineRadius)); minY = Math.Min(minY, zoomValue * (vertices[i].Y - lineRadius)); maxY = Math.Max(maxY, zoomValue * (vertices[i].Y + lineRadius)); } double maxWidth = Math.Max(maxX - minX, maxY - minY); return new RectangleD(new PointD(minX - frameWidth * maxWidth, minY - frameWidth * maxWidth), new SizeD(maxX - minX + 2 * frameWidth * maxWidth, maxY - minY + 2 * frameWidth * maxWidth)); }
public double? GetOriginalAttributeFromParameterizedLocation(WaypointAttribute attribute, ParameterizedLocation parameterizedLocation) { if (attribute != WaypointAttribute.HeartRate && attribute != WaypointAttribute.Altitude) throw new ArgumentException("The 'attribute' parameter must be either WaypointAttribute.HeartRate or WaypointAttribute.Altitude"); List<Waypoint> waypoints = segments[parameterizedLocation.SegmentIndex].Waypoints; if (parameterizedLocation.IsNode) return waypoints[(int)parameterizedLocation.Value].GetOriginalAttribute(attribute); var i = (int)parameterizedLocation.Floor().Value; if (i >= waypoints.Count - 1) i = waypoints.Count - 2; if (waypoints.Count < 2) return waypoints[0].GetOriginalAttribute(attribute); double d = parameterizedLocation.Value - i; var v0 = waypoints[i].GetOriginalAttribute(attribute); var v1 = waypoints[i + 1].GetOriginalAttribute(attribute); if (v0.HasValue && v1.HasValue) return v0 + d * (v1 - v0); return null; }