mirror of
https://github.com/dotMorten/NmeaParser.git
synced 2026-02-04 06:44:27 +01:00
Added satellite view to desktop sample
This commit is contained in:
parent
aa05f87b2e
commit
4bbd7fa54c
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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">
|
||||
|
|
|
|||
54
src/SampleApp.WinDesktop/SatelliteSnr.xaml
Normal file
54
src/SampleApp.WinDesktop/SatelliteSnr.xaml
Normal 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>
|
||||
49
src/SampleApp.WinDesktop/SatelliteSnr.xaml.cs
Normal file
49
src/SampleApp.WinDesktop/SatelliteSnr.xaml.cs
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
72
src/SampleApp.WinDesktop/SatelliteView.xaml
Normal file
72
src/SampleApp.WinDesktop/SatelliteView.xaml
Normal 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>
|
||||
97
src/SampleApp.WinDesktop/SatelliteView.xaml.cs
Normal file
97
src/SampleApp.WinDesktop/SatelliteView.xaml.cs
Normal 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();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue