Added satellite view to desktop sample

This commit is contained in:
mort5161 2014-07-28 16:38:45 -07:00
parent aa05f87b2e
commit 4bbd7fa54c
7 changed files with 335 additions and 4 deletions

View file

@ -1,10 +1,40 @@
<Window x:Class="SampleApp.WinDesktop.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBox x:Name="output"
xmlns:local="clr-namespace:SampleApp.WinDesktop"
Title="Sample App" Height="450" Width="525">
<Grid>
<TabControl>
<TabItem Header="Messages">
<TextBox x:Name="output"
AcceptsReturn="True"
IsReadOnly="True"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Visible"
/>
</TabItem>
<TabItem Header="GPS Satellite view">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<local:SatelliteView MaxWidth="{Binding ActualHeight, ElementName=satView}"
Grid.Column="1" x:Name="satView" />
<local:SatelliteSnr Grid.Row="1"
GpgsvMessages="{Binding GpgsvMessages, ElementName=satView}" />
</Grid>
</TabItem>
</TabControl>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
</Grid>
</Window>

View file

@ -25,14 +25,29 @@ namespace SampleApp.WinDesktop
InitializeComponent();
var device = new NmeaParser.NmeaFileDevice("NmeaSampleData.txt");
device.MessageReceived += device_MessageReceived;
device.OpenAsync();
var _ = device.OpenAsync();
}
Dictionary<int, NmeaParser.Nmea.Gps.Gpgsv> gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>();
private void device_MessageReceived(NmeaParser.NmeaDevice sender, NmeaParser.Nmea.NmeaMessage args)
{
Dispatcher.BeginInvoke((Action) delegate()
{
output.Text += args.MessageType + ": " + args.ToString() + '\n';
output.Select(output.Text.Length - 1, 0); //scroll to bottom
//Merge all gpgsv satellite messages
if(args is NmeaParser.Nmea.Gps.Gpgsv)
{
var gpgsv = (NmeaParser.Nmea.Gps.Gpgsv)args;
if(gpgsv.MessageNumber == 1)
{
gpgsvList = new Dictionary<int,NmeaParser.Nmea.Gps.Gpgsv>(); //first one. Replace list
}
gpgsvList[gpgsv.MessageNumber] = gpgsv;
if(gpgsv.MessageNumber == gpgsv.TotalMessages)
satView.GpgsvMessages = gpgsvList.Values;
}
});
}
}

View file

@ -53,6 +53,12 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</ApplicationDefinition>
<Compile Include="SatelliteSnr.xaml.cs">
<DependentUpon>SatelliteSnr.xaml</DependentUpon>
</Compile>
<Compile Include="SatelliteView.xaml.cs">
<DependentUpon>SatelliteView.xaml</DependentUpon>
</Compile>
<Page Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
@ -65,6 +71,14 @@
<DependentUpon>MainWindow.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Page Include="SatelliteSnr.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="SatelliteView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs">

View file

@ -0,0 +1,54 @@
<UserControl x:Class="SampleApp.WinDesktop.SatelliteSnr"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SampleApp.WinDesktop"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid Height="100">
<Grid >
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Path Stroke="Black" StrokeThickness="1"
Grid.RowSpan="4" Grid.ColumnSpan="4"
Stretch="Fill"
Data="M0,0 L 1,0 M 0,1 L 1,1 M 0,2 L 1,2 M 0,3 L 1,3 M 0,4 L 1,4" />
</Grid>
<ItemsControl x:Name="satellites"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Height="{Binding SignalToNoiseRatio}"
Background="LightGray"
BorderBrush="Black"
Margin="0,0,10,0" Width="20"
BorderThickness="1"
ToolTip="{Binding SignalToNoiseRatio}"
VerticalAlignment="Bottom">
<TextBlock Text="{Binding PrnNumber}"
HorizontalAlignment="Center" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>

View file

@ -0,0 +1,49 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SampleApp.WinDesktop
{
/// <summary>
/// Interaction logic for SatelliteView.xaml
/// </summary>
public partial class SatelliteSnr : UserControl
{
public SatelliteSnr()
{
InitializeComponent();
}
public IEnumerable<NmeaParser.Nmea.Gps.Gpgsv> GpgsvMessages
{
get { return (IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>)GetValue(GpgsvMessagesProperty); }
set { SetValue(GpgsvMessagesProperty, value); }
}
// Using a DependencyProperty as the backing store for GpgsvMessages. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GpgsvMessagesProperty =
DependencyProperty.Register("GpgsvMessages", typeof(IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>), typeof(SatelliteSnr), new PropertyMetadata(null, OnGpgsvMessagesChanged));
private static void OnGpgsvMessagesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var sats = e.NewValue as IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>;
if (sats == null)
(d as SatelliteSnr).satellites.ItemsSource = null;
else
(d as SatelliteSnr).satellites.ItemsSource = sats.SelectMany(s => s.SVs);
}
}
}

View file

@ -0,0 +1,72 @@
<UserControl x:Class="SampleApp.WinDesktop.SatelliteView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:SampleApp.WinDesktop"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid Opacity=".5" Margin="10">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Ellipse Stroke="Black" StrokeThickness="1"
Grid.RowSpan="4" Grid.ColumnSpan="4"
Fill="White"
>
</Ellipse>
<Ellipse Stroke="Black" StrokeThickness="1"
Grid.Row="1" Grid.Column="1"
Grid.RowSpan="2" Grid.ColumnSpan="2">
</Ellipse>
<Path Stroke="Black" StrokeThickness="1"
Grid.RowSpan="4" Grid.ColumnSpan="4"
Stretch="Fill"
Data="M0,1 L 2,1 M 1,0 L 1,2" />
</Grid>
<ItemsControl x:Name="satellites" Margin="10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Grid />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:PolarPlacementItem
Azimuth="{Binding Azimuth}"
Elevation="{Binding Elevation}" >
<Canvas Width="5" Height="5">
<Ellipse Fill="Black"
Width="5" Height="5" >
<Ellipse.ToolTip>
<StackPanel>
<TextBlock Text="{Binding Azimuth, StringFormat=Azimuth: {0}}" />
<TextBlock Text="{Binding Elevation, StringFormat=Elevation: {0}}" />
<TextBlock Text="{Binding SignalToNoiseRatio, StringFormat=SNR: {0}}" />
</StackPanel>
</Ellipse.ToolTip>
</Ellipse>
<TextBlock Text="{Binding PrnNumber}" Margin="8,-8" />
</Canvas>
</local:PolarPlacementItem>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</UserControl>

View file

@ -0,0 +1,97 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace SampleApp.WinDesktop
{
/// <summary>
/// Interaction logic for SatelliteView.xaml
/// </summary>
public partial class SatelliteView : UserControl
{
public SatelliteView()
{
InitializeComponent();
}
public IEnumerable<NmeaParser.Nmea.Gps.Gpgsv> GpgsvMessages
{
get { return (IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>)GetValue(GpgsvMessagesProperty); }
set { SetValue(GpgsvMessagesProperty, value); }
}
// Using a DependencyProperty as the backing store for GpgsvMessages. This enables animation, styling, binding, etc...
public static readonly DependencyProperty GpgsvMessagesProperty =
DependencyProperty.Register("GpgsvMessages", typeof(IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>), typeof(SatelliteView), new PropertyMetadata(null, OnGpgsvMessagesChanged));
private static void OnGpgsvMessagesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var sats = e.NewValue as IEnumerable<NmeaParser.Nmea.Gps.Gpgsv>;
if (sats == null)
(d as SatelliteView).satellites.ItemsSource = null;
else
(d as SatelliteView).satellites.ItemsSource = sats.SelectMany(s => s.SVs);
}
}
public class PolarPlacementItem : ContentControl
{
public PolarPlacementItem()
{
HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch;
VerticalAlignment = System.Windows.VerticalAlignment.Stretch;
}
protected override Size ArrangeOverride(Size arrangeBounds)
{
double az = (Azimuth - 90) / 180 * Math.PI;
double e = (90 - Elevation) / 90;
double X = Math.Cos(az) * e;
double Y = Math.Sin(az) * e;
X = arrangeBounds.Width * .5 * X;
Y = arrangeBounds.Height * .5 * Y;
RenderTransform = new TranslateTransform(X, Y);
return base.ArrangeOverride(arrangeBounds);
}
public double Azimuth
{
get { return (double)GetValue(AzimuthProperty); }
set { SetValue(AzimuthProperty, value); }
}
public static readonly DependencyProperty AzimuthProperty =
DependencyProperty.Register("Azimuth", typeof(double), typeof(PolarPlacementItem), new PropertyMetadata(0d, OnAzimuthPropertyChanged));
private static void OnAzimuthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as PolarPlacementItem).InvalidateArrange();
}
public double Elevation
{
get { return (double)GetValue(ElevationProperty); }
set { SetValue(ElevationProperty, value); }
}
public static readonly DependencyProperty ElevationProperty =
DependencyProperty.Register("Elevation", typeof(double), typeof(PolarPlacementItem), new PropertyMetadata(0d, OnElevationPropertyChanged));
private static void OnElevationPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
(d as PolarPlacementItem).InvalidateArrange();
}
}
}