public double CartesianDistance(GPSPoint p)
        {
            double deltaX = this.X - p.X;
            double deltaY = this.Y - p.Y;
            double deltaZ = this.Z - p.Z;

            return Math.Sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
        }
 public double HaversineDistance(GPSPoint p)
 {
     double dLat = (p.Latitude - this.Latitude).ToRadian();
     double dLon = (p.Longitude - this.Longitude).ToRadian();
     double lat1 = this.Latitude.ToRadian();
     double lat2 = p.Latitude.ToRadian();
     double a = Math.Sin(dLat / 2) * Math.Sin(dLat / 2) +
                 Math.Sin(dLon / 2) * Math.Sin(dLon / 2) * Math.Cos(lat1) * Math.Cos(lat2);
     double c = 2 * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1 - a));
     double d = Radius * c;
     return d;
 }
        private void chart_SeriesCursorMouseMove_1(object sender, ChartCursorEventArgs e)
        {
            var sv = e.SeriesViewer;
            var c = sv.CrosshairPoint;

            if (double.IsNaN(c.X) || double.IsNaN(c.Y))
            {
                return;
            }

            overlay.Children.Clear();


            var items = (IList<Model.SubTypes.Path>)DefaultViewModel["Path"];
            var count = items.Count;

            var index = (int)Math.Round(c.X * (items.Count - 1));

            if (index < 0 || index > items.Count - 1)
            {
                return;
            }

            var xVal = sv.CrosshairPoint.X;

            var item = items[index];

            var lat = item.Latitude;
            var lon = item.Longitude;

            var pois = (ObservableCollection<GPSPoint>)DefaultViewModel["PointsOfInterest"];

            pois[0] = new GPSPoint(item);

            foreach (var series in sv.Series)
            {
                if (series is HorizontalAnchoredCategorySeries)
                {
                    var acs = (HorizontalAnchoredCategorySeries)series;
                    var il = series.ItemsSource as IList;
                    var ie = series.ItemsSource.OfType<object>();
                    int itemCount;

                    if (il != null)
                    {
                        itemCount = il.Count;
                    }
                    else
                    {
                        itemCount = ie.Count();
                    }

                    var itemIndex = xVal * (itemCount - 1);
                    var previousIndex = (int)Math.Floor(itemIndex);
                    var nextIndex = (int)Math.Ceiling(itemIndex);
                    if (previousIndex < 0)
                    {
                        previousIndex = 0;
                    }
                    if (nextIndex < 0)
                    {
                        nextIndex = 0;
                    }

                    if (nextIndex > itemCount - 1)
                    {
                        nextIndex = itemCount - 1;
                    }
                    if (previousIndex > itemCount - 1)
                    {
                        previousIndex = itemCount - 1;
                    }

                    object previousItem;
                    object nextItem;

                    if (il != null)
                    {
                        previousItem = il[previousIndex];
                        nextItem = il[nextIndex];
                    }
                    else
                    {
                        previousItem = ie.Skip(previousIndex).Take(1).First();
                        nextItem = ie.Skip(nextIndex).Take(1).First();
                    }

                    _frh.PropertyName = acs.ValueMemberPath;
                    var previousValue = Convert.ToDouble(_frh.GetPropertyValue(previousItem));
                    var nextValue = Convert.ToDouble(_frh.GetPropertyValue(nextItem));

                    var interpolatedValue = previousValue + (nextValue - previousValue) * (itemIndex - previousIndex);

                    if (series is LineSeries && interpolatedValue > (double)this.DefaultViewModel["MaxPaceRange"])
                        return;

                    var displayY = acs.YAxis.ScaleValue(interpolatedValue);
                    var displayX = acs.XAxis.ScaleValue(itemIndex);

                    var pos = series.TransformToVisual(overlay).TransformPoint(new Point(displayX, displayY));

                    var el = new Ellipse()
                    {
                        Fill = new SolidColorBrush(Colors.Blue),
                        Stroke = new SolidColorBrush(Colors.White),
                        StrokeThickness = 1,
                        Width = 14,
                        Height = 14
                    };

                    Canvas.SetTop(el, pos.Y - 7.0);
                    Canvas.SetLeft(el, pos.X - 7.0);

                    overlay.Children.Add(el);

                    var tb = new TextBlock();
                    tb.FontSize = 14;
                    if (series is AreaSeries)
                        tb.Text = Math.Round(interpolatedValue, 2).ToString() + " ft.";
                    else
                        tb.Text = Math.Round(interpolatedValue, 2).ToString() + " min/mi";

                    Canvas.SetTop(tb, pos.Y - 10.0);
                    Canvas.SetLeft(tb, pos.X + 10.0);

                   overlay.Children.Add(tb);
                }
            }

        }