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.