0

I'm writing an app that calculates covered distance in real time. I'm doing this by comparing my actual postion to the previous one and count the distance between them (using the Haversine formula) and sum everything up. This gives me some result, the distance is growing everything seems to be working. BUT the problem is with the accuracy. I tested this app on a route that is ~15km long many times and the covered distance is always bigger than my car's counter says. The difference is ALWAYS different - from 500m to even 2km.

This is my Geolocator object:

Geolocator gl = new Geolocator() {
    DesiredAccuracy = PositionAccuracy.High, MovementThreshold = 20, ReportInterval = 50
};

In the constructor I declare that when the position is changed, "OnPositionChanged" method should be fired and also the method to find my actual location:

gl.PositionChanged += OnPositionChanged;
setMyLocation();

This is the "OnPositionChanged()" method:

async private void OnPositionChanged(Geolocator sender, PositionChangedEventArgs e)
{
    await Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () =>
    {       
        setMyLocation();
    });
}

This is the setMyLocation() method:

private async void setMyLocation()
{
    try
    {
        p = new Position();

        location = await gl.GetGeopositionAsync(TimeSpan.FromMinutes(5), TimeSpan.FromSeconds(5));

        p.Latitude = location.Coordinate.Point.Position.Latitude;
        p.Longitude = location.Coordinate.Point.Position.Longitude;

        obla = location.Coordinate.Point.Position.Latitude;
        oblo = location.Coordinate.Point.Position.Longitude;

        if (prev_location.Latitude == 0)
        {
            prev_location = p;    
        }

        positions.Add(new BasicGeoposition() {
            Latitude = location.Coordinate.Latitude, 
            Longitude = location.Coordinate.Longitude
        });

        myMap.Children.Remove(myCircle);
        myCircle = new Ellipse();
        myCircle.Fill = new SolidColorBrush(Colors.Green);
        myCircle.Height = 17;
        myCircle.Width = 17;
        myCircle.Opacity = 50;
        myMap.Children.Add(myCircle);

        MapControl.SetLocation(myCircle, location.Coordinate.Point);
        MapControl.SetNormalizedAnchorPoint(myCircle, new Point(0, 0));

        routeKM += (Distance(p, prev_location));

        Distance_txt.Text = routeKM.ToString("f2") + " km";

        prev_location = p;                    
    }
    catch
    {        
    }   
}

This is my double (routeKM) counted with the Haversine formula:

public double Distance(Position pos1, Position pos2)
{
    var R = 6371d; // Radius of the earth in km
    var dLat = Deg2Rad(pos2.Latitude - pos1.Latitude);  // deg2rad below
    var dLon = Deg2Rad(pos2.Longitude - pos1.Longitude);
    var a = Math.Sin(dLat / 2d) * Math.Sin(dLat / 2d) +
            Math.Cos(Deg2Rad(pos1.Latitude)) * Math.Cos(Deg2Rad(pos2.Latitude)) *
            Math.Sin(dLon / 2d) * Math.Sin(dLon / 2d);
    var c = 2d * Math.Atan2(Math.Sqrt(a), Math.Sqrt(1d - a));
    var d = R * c; // Distance in km

    return d;
}

double Deg2Rad(double deg)
{
    return deg * (Math.PI / 180d);
}

So my question is: how to improve the accuracy? I'm not happy that my car's counter shows even 2km less than my app.

krlzlx
  • 5,476
  • 14
  • 44
  • 51
Michal_Drwal
  • 478
  • 1
  • 9
  • 23

1 Answers1

0

By doing DesiredAccuracy = PositionAccuracy.High you already suggested Windows Phone OS to look for highest accuracy.

I think you should change your distance finding logic and see if it works.

Use GeoCoordinate.GetDistanceTo as suggested in following answer.

https://stackoverflow.com/a/6366657/744616

Community
  • 1
  • 1
Pranit Kothari
  • 8,997
  • 10
  • 55
  • 128
  • Unfortunately I can't use the GeoCoordinate class in Windows Phone 8.1. But I'll try with the method that is in one of the answers there. Thanks for the link. – Michal_Drwal May 19 '15 at 04:05
  • @Michal_Drwal Why you cannot use GeoCoordinate.GetDistanceTo? – Pranit Kothari May 19 '15 at 04:07
  • I don't know - when I type this class the only thing I can do is "Generate class for GeoCoordinate". I suppose it's not available for the WP 8.1 RT apps. – Michal_Drwal May 19 '15 at 04:13
  • Have you used `System.Device.Location` namespace. It is defined under suggested namespace. – Pranit Kothari May 19 '15 at 04:14
  • "The type or namespace name 'Device' does not exist in the namespace 'System' (are you missing an assembly reference?)" This is what I'm getting. – Michal_Drwal May 19 '15 at 04:17
  • @Michal_Drwal Oh, can you try using `CurrentLocation.GetDistanceTo(DestLocation);` – Pranit Kothari May 19 '15 at 04:19
  • Unfortunately I can't. But I think someone gave the code for the "GetDistanceTo" method in the link that you provided. So I'll try with this first. – Michal_Drwal May 19 '15 at 04:27
  • @Michal_Drwal Just one thing to say. Year back I worked on Windows Phone location based services, and accuracy mostly was pretty good. You should be missing something, otherwise precision should be good. – Pranit Kothari May 19 '15 at 04:29