using System; using System.ComponentModel; using System.Drawing; using System.Globalization; using System.IO; using System.Net; namespace ArducopterConfigurator.PresentationModels { public class GpsStatusVm : NotifyProperyChangedBase, IPresentationModel { private const string SEND_GPS_DATA = "4"; private const string STOP_UPDATES = "X"; public ICommand GetMapCommand { get; private set; } private BackgroundWorker bg; public GpsStatusVm() { bg = new BackgroundWorker(); bg.DoWork += DownloadGoogleMap; bg.RunWorkerCompleted += DownloadGoogleMapComplete; GetMapCommand = new DelegateCommand(_ => GetMap(), _=> HasFix && !bg.IsBusy); } private void GetMap() { var urlTemplate = "http://maps.google.com/maps/api/staticmap?&markers=color:blue|label:A|{0:0.00000},{1:0.00000}&zoom=13&size=250x200&maptype=roadmap&sensor=false"; var url = string.Format(CultureInfo.InvariantCulture, urlTemplate, GpsLatitude, GpsLongitude); bg.RunWorkerAsync(url); } private void DownloadGoogleMapComplete(object sender, RunWorkerCompletedEventArgs e) { MapImage = e.Result as Image; } private void DownloadGoogleMap(object sender, DoWorkEventArgs e) { var url = e.Argument as string; var Client = new WebClient(); using (var strm = Client.OpenRead(url)) { var png = Image.FromStream(strm); e.Result = png; } } private void sendString(string str) { if (sendTextToApm != null) sendTextToApm(this, new sendTextToApmEventArgs(str)); } public void Activate() { sendString(SEND_GPS_DATA); } public void DeActivate() { sendString(STOP_UPDATES); } public event EventHandler updatedByApm; public string Name { get { return "GPS Status"; } } public void handleLineOfText(string strRx) { // We don't bother with the automatic property population, as the received string is // tab delimeted and the values have crazy scale factors anyway. // hack for testing with no GPS // strRx = "73410000\t407021470\t-740157940\t9242\t0\t19831\t1"; var parts = strRx.Split('\t'); try { GpsTime = int.Parse(parts[0].Trim(), CultureInfo.InvariantCulture); GpsLatitude = (float)(int.Parse(parts[1].Trim(), CultureInfo.InvariantCulture)) / 10000000; GpsLongitude = (float)(int.Parse(parts[2].Trim(), CultureInfo.InvariantCulture)) / 10000000; GpsAltitude = int.Parse(parts[3].Trim(), CultureInfo.InvariantCulture) / 100; GpsGroundSpeed = (float)(int.Parse(parts[4].Trim(), CultureInfo.InvariantCulture)) / 100; GpsGroundCourse = int.Parse(parts[5].Trim(), CultureInfo.InvariantCulture) / 100; HasFix = parts[6].Trim() == "1"; // Todo: the number of sats is actually a raw char, not an ascii char like '3' } catch (FormatException) { Console.WriteLine("Format Exception in GPS VM, string: " + strRx); } } public event EventHandler sendTextToApm; #region bindables private Image _mapImage; public Image MapImage { get { return _mapImage; } set { if (_mapImage == value) return; _mapImage = value; FirePropertyChanged("MapImage"); } } private int _gpsTime; public int GpsTime { get { return _gpsTime; } set { if (_gpsTime == value) return; _gpsTime = value; FirePropertyChanged("GpsTime"); } } private float _gpsLatitude; public float GpsLatitude { get { return _gpsLatitude; } set { if (_gpsLatitude == value) return; _gpsLatitude = value; FirePropertyChanged("GpsLatitude"); } } private float _gpsLongitude; public float GpsLongitude { get { return _gpsLongitude; } set { if (_gpsLongitude == value) return; _gpsLongitude = value; FirePropertyChanged("GpsLongitude"); } } private float _gpsGroundSpeed; public float GpsGroundSpeed { get { return _gpsGroundSpeed; } set { if (_gpsGroundSpeed == value) return; _gpsGroundSpeed = value; FirePropertyChanged("GpsGroundSpeed"); } } private int _gpsGroundCourse; public int GpsGroundCourse { get { return _gpsGroundCourse; } set { if (_gpsGroundCourse == value) return; _gpsGroundCourse = value; FirePropertyChanged("GpsGroundCourse"); } } private int _gpsAltitude; public int GpsAltitude { get { return _gpsAltitude; } set { if (_gpsAltitude == value) return; _gpsAltitude = value; FirePropertyChanged("GpsAltitude"); } } private bool _hasFix; public bool HasFix { get { return _hasFix; } set { if (_hasFix == value) return; _hasFix = value; FirePropertyChanged("HasFix"); } } #endregion } }