Last active
December 27, 2015 05:09
-
-
Save dotMorten/7272239 to your computer and use it in GitHub Desktop.
A custom location provider that randomly accelerates and changes heading for simple in-house testing of location
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using Esri.ArcGISRuntime.Geometry; | |
using Esri.ArcGISRuntime.Location; | |
using System; | |
using System.Linq; | |
using System.Threading.Tasks; | |
#if NETFX_CORE | |
using Windows.Foundation; | |
using Windows.UI.Xaml; | |
#else | |
using System.Windows.Threading; | |
using System.Windows; | |
#endif | |
namespace MortensGists | |
{ | |
/// <summary> | |
/// A custom location provider that randomly accelerates and changes heading for | |
/// simple in-house testing of location | |
/// </summary> | |
public class RandomLocationProvider : ILocationProvider | |
{ | |
private static Random randomizer = new Random(); | |
private DispatcherTimer timer; | |
LocationInfo oldPosition; | |
public RandomLocationProvider() | |
{ | |
timer = new DispatcherTimer() { Interval = TimeSpan.FromSeconds(1) }; | |
timer.Tick += timer_Tick; | |
// Default start location | |
StartLatitude = 34.057104; | |
StartLongitude = -117.196816; | |
} | |
/// <summary> | |
/// Called when the position timer triggers, and calculates the next position based on current speed and heading, | |
/// and adds a little randomization to current heading, speed and accuracy. | |
/// </summary> | |
/// <param name="sender"></param> | |
/// <param name="e"></param> | |
private void timer_Tick(object sender, object e) | |
{ | |
if (oldPosition == null) | |
{ | |
oldPosition = new LocationInfo() | |
{ | |
Location = new MapPoint(StartLongitude, StartLatitude, SpatialReferences.Wgs84), | |
Speed = 0, | |
Course = 0, | |
HorizontalAccuracy = 20, | |
}; | |
} | |
var now = DateTime.Now; | |
TimeSpan timeParsed = timer.Interval; | |
double acceleration = randomizer.NextDouble() * 5 - 2.5; | |
double deltaSpeed = acceleration * timeParsed.TotalSeconds; | |
double newSpeed = Math.Max(0, deltaSpeed + oldPosition.Speed); | |
double deltaCourse = randomizer.NextDouble() * 30 - 15; | |
double newCourse = deltaCourse + oldPosition.Course; | |
while (newCourse < 0) newCourse += 360; | |
while (newCourse >= 360) newCourse -= 360; | |
double distanceTravelled = (newSpeed + oldPosition.Speed) * .5 * timeParsed.TotalSeconds; | |
double accuracy = Math.Min(500, Math.Max(20, oldPosition.HorizontalAccuracy + (randomizer.NextDouble() * 100 - 50))); | |
var pos = GeometryEngine.GeodesicMove(new MapPoint[] { oldPosition.Location }, distanceTravelled, Units.Meters, newCourse).First(); | |
var newPosition = new LocationInfo() | |
{ | |
Location = pos, | |
Speed = newSpeed, | |
Course = newCourse, | |
HorizontalAccuracy = accuracy, | |
}; | |
oldPosition = newPosition; | |
if (LocationChanged != null) | |
LocationChanged(this, oldPosition); | |
} | |
/// <summary> | |
/// Gets or sets the start latitude. | |
/// </summary> | |
/// <value> | |
/// The start latitude. | |
/// </value> | |
public double StartLatitude { get; set; } | |
/// <summary> | |
/// Gets or sets the start longitude. | |
/// </summary> | |
/// <value> | |
/// The start longitude. | |
/// </value> | |
public double StartLongitude { get; set; } | |
public System.Threading.Tasks.Task StartAsync() | |
{ | |
timer.Start(); | |
return Task.FromResult<bool>(true); | |
} | |
public System.Threading.Tasks.Task StopAsync() | |
{ | |
timer.Stop(); | |
return Task.FromResult<bool>(true); | |
} | |
public event EventHandler<LocationInfo> LocationChanged; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment