Add project files.
This commit is contained in:
66
BaseGpsClient.cs
Normal file
66
BaseGpsClient.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using GpsClient2.Model;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public abstract class BaseGpsClient {
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public GpsType GpsType { get; }
|
||||||
|
public bool IsRunning { get; set; }
|
||||||
|
|
||||||
|
protected BaseGpsInfo GpsInfo { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Event handlers
|
||||||
|
|
||||||
|
public event EventHandler<GpsDataEventArgs> GpsCallbackEvent;
|
||||||
|
public event EventHandler<string> RawGpsCallbackEvent;
|
||||||
|
public event EventHandler<GpsStatus> GpsStatusEvent;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
protected BaseGpsClient(GpsType gpsType, BaseGpsInfo gpsInfo) {
|
||||||
|
GpsType = gpsType;
|
||||||
|
GpsInfo = gpsInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Connect and Disconnect
|
||||||
|
|
||||||
|
public abstract bool Connect();
|
||||||
|
|
||||||
|
public abstract bool Disconnect();
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Events Triggers
|
||||||
|
|
||||||
|
protected virtual void OnGpsDataReceived(GpsDataEventArgs e) {
|
||||||
|
if (GpsInfo.CoordinateSystem == GpsCoordinateSystem.Lambert72) {
|
||||||
|
var x = 0.0d;
|
||||||
|
var y = 0.0d;
|
||||||
|
var h = 0.0d;
|
||||||
|
CoordinateConverterUtilities.GeoETRS89ToLambert72(e.Latitude, e.Longitude, 0, ref x, ref y, ref h);
|
||||||
|
e.CoordinateSystem = GpsCoordinateSystem.Lambert72;
|
||||||
|
e.Latitude = x;
|
||||||
|
e.Longitude = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
GpsCallbackEvent?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnRawGpsDataReceived(string e) {
|
||||||
|
RawGpsCallbackEvent?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void OnGpsStatusChanged(GpsStatus e) {
|
||||||
|
GpsStatusEvent?.Invoke(this, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
89
ComPortGpsClient.cs
Normal file
89
ComPortGpsClient.cs
Normal file
@@ -0,0 +1,89 @@
|
|||||||
|
using GpsClient2.Model;
|
||||||
|
using GpsClient2.NmeaMessages;
|
||||||
|
using GpsClient2.Exceptions;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.IO.Ports;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public class ComPortGpsClient : BaseGpsClient {
|
||||||
|
#region Private Properties
|
||||||
|
|
||||||
|
private readonly NmeaParser _parser = new NmeaParser();
|
||||||
|
private SerialPort _serialPort;
|
||||||
|
|
||||||
|
private DateTime? _previousReadTime;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public ComPortGpsClient(ComPortInfo connectionData) : base(GpsType.ComPort, connectionData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComPortGpsClient(BaseGpsInfo connectionData) : base(GpsType.ComPort, connectionData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Connect and Disconnect
|
||||||
|
|
||||||
|
public override bool Connect() {
|
||||||
|
var data = (ComPortInfo)GpsInfo;
|
||||||
|
|
||||||
|
IsRunning = true;
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connecting);
|
||||||
|
_serialPort = new SerialPort(data.ComPort, 9600, Parity.None, 8, StopBits.One);
|
||||||
|
|
||||||
|
// Attach a method to be called when there
|
||||||
|
// is data waiting in the port's buffer
|
||||||
|
_serialPort.DataReceived += port_DataReceived;
|
||||||
|
try {
|
||||||
|
// Begin communications
|
||||||
|
_serialPort.Open();
|
||||||
|
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connected);
|
||||||
|
// Enter an application loop to keep this thread alive
|
||||||
|
while (_serialPort.IsOpen) {
|
||||||
|
Thread.Sleep(data.ReadFrequenty);
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
Disconnect();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Disconnect() {
|
||||||
|
_serialPort.Close();
|
||||||
|
IsRunning = false;
|
||||||
|
OnGpsStatusChanged(GpsStatus.Disabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Location Callbacks
|
||||||
|
|
||||||
|
private void port_DataReceived(object sender, SerialDataReceivedEventArgs e) {
|
||||||
|
try {
|
||||||
|
var readString = _serialPort.ReadExisting();
|
||||||
|
OnRawGpsDataReceived(readString);
|
||||||
|
var result = _parser.Parse(readString);
|
||||||
|
if (typeof(GprmcMessage) != result.GetType()) return;
|
||||||
|
if (_previousReadTime != null && GpsInfo.ReadFrequenty != 0 && ((GprmcMessage)result).UpdateDate.Subtract(new TimeSpan(0, 0, 0, 0, GpsInfo.ReadFrequenty)) <= _previousReadTime) return;
|
||||||
|
OnGpsDataReceived(new GpsDataEventArgs((GprmcMessage)result));
|
||||||
|
} catch (UnknownTypeException ex) {
|
||||||
|
Console.WriteLine(ex.Message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
30
CoordinateConverterUtilities.cs
Normal file
30
CoordinateConverterUtilities.cs
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
internal class CoordinateConverterUtilities {
|
||||||
|
#if WIN64
|
||||||
|
private const string DllImport = @"plugins/ETRS89_LAMBERT_UTM_64bits.dll";
|
||||||
|
#else
|
||||||
|
private const string DllImport = @"plugins/ETRS89_LAMBERT_UTM_32bits.dll";
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#region Coordinate conversion functions using NGI DLL
|
||||||
|
|
||||||
|
//Import the dll with the functions to calculate lambert coordinates
|
||||||
|
[DllImport(DllImport, SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int GeoETRS89ToLambert72(double Xi, double Yi, double Zi, ref double xo, ref double yo, ref double Ho);
|
||||||
|
|
||||||
|
[DllImport(DllImport, SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int Lambert72ToLambert08(double Xi, double Yi, double Zi, ref double xo, ref double yo, ref double Ho);
|
||||||
|
|
||||||
|
[DllImport(DllImport, SetLastError = true, CharSet = CharSet.Auto)]
|
||||||
|
public static extern int Lambert72ToGeoETRS89(double Xi, double Yi, double Zi, ref double xo, ref double yo, ref double Ho);
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
78
Enums.cs
Normal file
78
Enums.cs
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public enum CoordinateType {
|
||||||
|
Latitude,
|
||||||
|
Longitude
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GpsFixQuality {
|
||||||
|
Invalid = 0,
|
||||||
|
/// <summary>
|
||||||
|
/// GPS fix (SPS)
|
||||||
|
/// </summary>
|
||||||
|
GpsFix = 1,
|
||||||
|
/// <summary>
|
||||||
|
/// DGPS fix
|
||||||
|
/// </summary>
|
||||||
|
DgpsFix = 2,
|
||||||
|
/// <summary>
|
||||||
|
/// PPS fix
|
||||||
|
/// </summary>
|
||||||
|
PpsFix = 3,
|
||||||
|
/// <summary>
|
||||||
|
/// Real Time Kinematic
|
||||||
|
/// </summary>
|
||||||
|
Rtk = 4,
|
||||||
|
/// <summary>
|
||||||
|
/// Float RTK
|
||||||
|
/// </summary>
|
||||||
|
FloatRtk = 5,
|
||||||
|
/// <summary>
|
||||||
|
/// estimated (dead reckoning) (2.3 feature)
|
||||||
|
/// </summary>
|
||||||
|
Estimated = 6,
|
||||||
|
/// <summary>
|
||||||
|
/// Manual input mode
|
||||||
|
/// </summary>
|
||||||
|
ManualInput = 7,
|
||||||
|
/// <summary>
|
||||||
|
/// Simulation mode
|
||||||
|
/// </summary>
|
||||||
|
Simulation = 8
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum SatelliteFixType {
|
||||||
|
NoFix,
|
||||||
|
TwoDFix,
|
||||||
|
ThreeDFix
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum FileType {
|
||||||
|
Nmea,
|
||||||
|
Gpsd,
|
||||||
|
LatitudeLongitude,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GpsCoordinateSystem {
|
||||||
|
Lambert72,
|
||||||
|
GeoEtrs89,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GpsStatus {
|
||||||
|
Disabled,
|
||||||
|
Connecting,
|
||||||
|
Connected
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum GpsType {
|
||||||
|
File,
|
||||||
|
ComPort,
|
||||||
|
Gpsd,
|
||||||
|
WindowsLocationApi
|
||||||
|
}
|
||||||
|
}
|
||||||
21
Exceptions/UnknownTypeException.cs
Normal file
21
Exceptions/UnknownTypeException.cs
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.Exceptions {
|
||||||
|
public class UnknownTypeException : Exception {
|
||||||
|
public UnknownTypeException(Type type) : base($"Unknown Class Type: {type}") {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnknownTypeException(string type) : base($"Unknown Class Type: {type}") {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public UnknownTypeException() : base("Unknown Class Type") {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
76
GpsClient2.csproj
Normal file
76
GpsClient2.csproj
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>GpsClient2</RootNamespace>
|
||||||
|
<AssemblyName>GpsClient2</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\Debug\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\Release\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Device" />
|
||||||
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="BaseGpsClient.cs" />
|
||||||
|
<Compile Include="CoordinateConverterUtilities.cs" />
|
||||||
|
<Compile Include="Enums.cs" />
|
||||||
|
<Compile Include="Exceptions\UnknownTypeException.cs" />
|
||||||
|
<Compile Include="Model\BaseGpsInfo.cs" />
|
||||||
|
<Compile Include="Model\ComPortInfo.cs" />
|
||||||
|
<Compile Include="Model\WindowsLocationApiInfo.cs" />
|
||||||
|
<Compile Include="NmeaConstants.cs" />
|
||||||
|
<Compile Include="NmeaMessages\GpggaMessage.cs" />
|
||||||
|
<Compile Include="NmeaMessages\GpgsaMessage.cs" />
|
||||||
|
<Compile Include="NmeaMessages\GpvtgMessage.cs" />
|
||||||
|
<Compile Include="NmeaMessages\NmeaMessage.cs" />
|
||||||
|
<Compile Include="NmeaParser.cs" />
|
||||||
|
<Compile Include="StringExtensions.cs" />
|
||||||
|
<Compile Include="ComPortGpsClient.cs" />
|
||||||
|
<Compile Include="GpsDataEventArgs.cs" />
|
||||||
|
<Compile Include="Model\GpsLocation.cs" />
|
||||||
|
<Compile Include="NmeaMessages\GprmcMessage.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="WindowsLocationApiGpsClient.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Content Include="plugins\ETRS89_LAMBERT_UTM_32bits.dll">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
<Content Include="plugins\ETRS89_LAMBERT_UTM_64bits.dll">
|
||||||
|
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
||||||
|
</Content>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
25
GpsClient2.sln
Normal file
25
GpsClient2.sln
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.6.33801.468
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GpsClient2", "GpsClient2.csproj", "{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C62E7A96-F279-4390-A1AC-8FACDD9E8C14}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {85C8CFC9-7CA5-4D17-B598-653F56226D85}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
47
GpsDataEventArgs.cs
Normal file
47
GpsDataEventArgs.cs
Normal file
@@ -0,0 +1,47 @@
|
|||||||
|
using System;
|
||||||
|
using GpsClient2.Model;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Device.Location;
|
||||||
|
using GpsClient2.NmeaMessages;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public class GpsDataEventArgs : EventArgs {
|
||||||
|
public GpsCoordinateSystem CoordinateSystem { get; set; } = GpsCoordinateSystem.GeoEtrs89;
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
public double Speed { get; set; }
|
||||||
|
|
||||||
|
public GpsDataEventArgs(GpsLocation gpsLocation) {
|
||||||
|
Latitude = gpsLocation.Latitude;
|
||||||
|
Longitude = gpsLocation.Longitude;
|
||||||
|
Speed = gpsLocation.Speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GpsDataEventArgs(GprmcMessage gpsLocation) {
|
||||||
|
Latitude = gpsLocation.Latitude;
|
||||||
|
Longitude = gpsLocation.Longitude;
|
||||||
|
Speed = gpsLocation.Speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GpsDataEventArgs(GeoCoordinate gpsLocation) {
|
||||||
|
Latitude = gpsLocation.Latitude;
|
||||||
|
Longitude = gpsLocation.Longitude;
|
||||||
|
Speed = gpsLocation.Speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public GpsDataEventArgs(double latitude, double longitude, double speed = 0.0d) {
|
||||||
|
Latitude = latitude;
|
||||||
|
Longitude = longitude;
|
||||||
|
Speed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Latitude: {Latitude} - Longitude: {Longitude} - Speed: {Speed}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
Model/BaseGpsInfo.cs
Normal file
13
Model/BaseGpsInfo.cs
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.Model {
|
||||||
|
public abstract class BaseGpsInfo {
|
||||||
|
public GpsCoordinateSystem CoordinateSystem { get; set; } = GpsCoordinateSystem.GeoEtrs89;
|
||||||
|
|
||||||
|
public int ReadFrequenty { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
20
Model/ComPortInfo.cs
Normal file
20
Model/ComPortInfo.cs
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.Model {
|
||||||
|
public class ComPortInfo : BaseGpsInfo {
|
||||||
|
public string ComPort { get; set; } = "ComPort1";
|
||||||
|
|
||||||
|
public ComPortInfo() {
|
||||||
|
ReadFrequenty = 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ComPortInfo(string comPort, int readFrequenty = 1000) {
|
||||||
|
ComPort = comPort;
|
||||||
|
ReadFrequenty = readFrequenty;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
45
Model/GpsLocation.cs
Normal file
45
Model/GpsLocation.cs
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Runtime.Serialization;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
namespace GpsClient2.Model {
|
||||||
|
[DataContract]
|
||||||
|
public class GpsLocation {
|
||||||
|
[DataMember(Name = "tag")]
|
||||||
|
public string Tag { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "device")]
|
||||||
|
public string Device { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "mode")]
|
||||||
|
public int Mode { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "time")]
|
||||||
|
public DateTime Time { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "ept")]
|
||||||
|
public float Ept { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "lat")]
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "lon")]
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "track")]
|
||||||
|
public float Track { get; set; }
|
||||||
|
|
||||||
|
[DataMember(Name = "speed")]
|
||||||
|
public float SpeedKnots { get; set; }
|
||||||
|
|
||||||
|
public double Speed => SpeedKnots * 1.852;
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Tag: {Tag} - Device: {Device} - Mode: {Mode} - Time: {Time} - Latitude: {Latitude} - Longitude: {Longitude} - Track: {Track} - Speed: {Speed}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
15
Model/WindowsLocationApiInfo.cs
Normal file
15
Model/WindowsLocationApiInfo.cs
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.Model {
|
||||||
|
public class WindowsLocationApiInfo : BaseGpsInfo {
|
||||||
|
public int Timeout { get; set; } = 1000;
|
||||||
|
|
||||||
|
public WindowsLocationApiInfo() {
|
||||||
|
ReadFrequenty = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
NmeaConstants.cs
Normal file
36
NmeaConstants.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using GpsClient2.Exceptions;
|
||||||
|
using GpsClient2.NmeaMessages;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public static class NmeaConstants {
|
||||||
|
private static readonly Dictionary<string, Type> TypeDictionary = new Dictionary<string, Type>
|
||||||
|
{
|
||||||
|
{"GPGGA", typeof(GpggaMessage)},
|
||||||
|
{"GPRMC", typeof(GprmcMessage)},
|
||||||
|
{"GPVTG", typeof(GpvtgMessage)},
|
||||||
|
{"GPGSA", typeof(GpgsaMessage)}
|
||||||
|
};
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the correct class type of the message.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="typeName">The type name given.</param>
|
||||||
|
/// <returns>The class type.</returns>
|
||||||
|
/// <exception cref="UnknownTypeException">Given if the type is unkown.</exception>
|
||||||
|
public static Type GetClassType(string typeName) {
|
||||||
|
Type result;
|
||||||
|
TypeDictionary.TryGetValue(typeName, out result);
|
||||||
|
|
||||||
|
if (result == null) {
|
||||||
|
throw new UnknownTypeException();
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
113
NmeaMessages/GpggaMessage.cs
Normal file
113
NmeaMessages/GpggaMessage.cs
Normal file
@@ -0,0 +1,113 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.NmeaMessages {
|
||||||
|
public class GpggaMessage : NmeaMessage {
|
||||||
|
#region Description
|
||||||
|
|
||||||
|
// $GPGGA,123519,4807.038,N,01131.000,E,1,08,0.9,545.4,M,46.9,M,,*47
|
||||||
|
|
||||||
|
// Where:
|
||||||
|
// GGA Global Positioning System Fix Data
|
||||||
|
// 123519 Fix taken at 12:35:19 UTC
|
||||||
|
// 4807.038,N Latitude 48 deg 07.038' N
|
||||||
|
// 01131.000,E Longitude 11 deg 31.000' E
|
||||||
|
// 1 Fix quality: 0 = invalid
|
||||||
|
// 1 = GPS fix(SPS)
|
||||||
|
// 2 = DGPS fix
|
||||||
|
// 3 = PPS fix
|
||||||
|
// 4 = Real Time Kinematic
|
||||||
|
// 5 = Float RTK
|
||||||
|
// 6 = estimated(dead reckoning) (2.3 feature)
|
||||||
|
// 7 = Manual input mode
|
||||||
|
// 8 = Simulation mode
|
||||||
|
// 08 Number of satellites being tracked
|
||||||
|
// 0.9 Horizontal dilution of position
|
||||||
|
// 545.4, M Altitude, Meters, above mean sea level
|
||||||
|
// 46.9, M Height of geoid(mean sea level) above WGS84
|
||||||
|
// ellipsoid
|
||||||
|
// (empty field) time in seconds since last DGPS update
|
||||||
|
// (empty field) DGPS station ID number
|
||||||
|
// *47 the checksum data, always begins with*
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fix taken
|
||||||
|
/// </summary>
|
||||||
|
public TimeSpan FixTime { get; set; }
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
public GpsFixQuality FixQuality { get; set; }
|
||||||
|
|
||||||
|
public int NumberOfSatellites { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Horizontal dilution of position
|
||||||
|
/// </summary>
|
||||||
|
public float Hdop { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Altitude, Meters, above mean sea level
|
||||||
|
/// </summary>
|
||||||
|
public float Altitude { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Altitude units ('M' for Meters)
|
||||||
|
/// </summary>
|
||||||
|
public string AltitudeUnits { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Height of geoid (mean sea level) above WGS84
|
||||||
|
/// </summary>
|
||||||
|
public float HeightOfGeoId { get; set; }
|
||||||
|
|
||||||
|
public string HeightOfGeoIdUnits { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Time in seconds since last DGPS update
|
||||||
|
/// </summary>
|
||||||
|
public int TimeSpanSinceDgpsUpdate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// DGPS station ID number
|
||||||
|
/// </summary>
|
||||||
|
public int? DgpsStationId { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Message parsing
|
||||||
|
|
||||||
|
public override void Parse(string[] messageParts) {
|
||||||
|
if (messageParts == null || messageParts.Length < 14) {
|
||||||
|
throw new ArgumentException("Invalid GPGGA message");
|
||||||
|
}
|
||||||
|
FixTime = messageParts[1].ToTimeSpan();
|
||||||
|
Latitude = messageParts[2].ToCoordinates(messageParts[3], CoordinateType.Latitude);
|
||||||
|
Longitude = messageParts[4].ToCoordinates(messageParts[5], CoordinateType.Longitude);
|
||||||
|
FixQuality = (GpsFixQuality)Enum.Parse(typeof(GpsFixQuality), messageParts[6]);
|
||||||
|
NumberOfSatellites = messageParts[7].ToInteger();
|
||||||
|
Hdop = messageParts[8].ToFloat();
|
||||||
|
Altitude = messageParts[9].ToFloat();
|
||||||
|
AltitudeUnits = messageParts[10];
|
||||||
|
HeightOfGeoId = messageParts[11].ToFloat();
|
||||||
|
HeightOfGeoIdUnits = messageParts[12];
|
||||||
|
TimeSpanSinceDgpsUpdate = messageParts[13].ToInteger();
|
||||||
|
DgpsStationId = messageParts[14].ToInteger();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Latitude {Latitude} - Longitude {Longitude} - Hoogte {Altitude}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
87
NmeaMessages/GpgsaMessage.cs
Normal file
87
NmeaMessages/GpgsaMessage.cs
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.NmeaMessages {
|
||||||
|
public class GpgsaMessage : NmeaMessage {
|
||||||
|
#region Description
|
||||||
|
|
||||||
|
// $GPGSA,A,3,04,05,,09,12,,,24,,,,,2.5,1.3,2.1*39
|
||||||
|
|
||||||
|
// Where:
|
||||||
|
// GSA Satellite status
|
||||||
|
// A Auto selection of 2D or 3D fix(M = manual)
|
||||||
|
// 3 3D fix - values include: 1 = no fix
|
||||||
|
// 2 = 2D fix
|
||||||
|
// 3 = 3D fix
|
||||||
|
// 04,05... PRNs of satellites used for fix(space for 12)
|
||||||
|
// 2.5 PDOP(dilution of precision)
|
||||||
|
// 1.3 Horizontal dilution of precision(HDOP)
|
||||||
|
// 2.1 Vertical dilution of precision(VDOP)
|
||||||
|
// *39 the checksum data, always begins with*
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Auto selection of 2D or 3D fix(M = manual)
|
||||||
|
/// </summary>
|
||||||
|
public bool GpsStatusAuto { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 3D fix - values include: 1 = no fix
|
||||||
|
// 2 = 2D fix
|
||||||
|
// 3 = 3D fix
|
||||||
|
/// </summary>
|
||||||
|
public SatelliteFixType SatelliteFix { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PRNs of satellites used for fix(space for 12)
|
||||||
|
/// </summary>
|
||||||
|
public string Pnrs { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// PDOP(dilution of precision)
|
||||||
|
/// </summary>
|
||||||
|
public float Pdop { get; set; }
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Horizontal dilution of precision(HDOP)
|
||||||
|
/// </summary>
|
||||||
|
public float Hdop { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Vertical dilution of precision(VDOP)
|
||||||
|
/// </summary>
|
||||||
|
public float Vdop { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Message parsing
|
||||||
|
|
||||||
|
public override void Parse(string[] messageParts) {
|
||||||
|
if (messageParts == null || messageParts.Length < 9) {
|
||||||
|
throw new ArgumentException("Invalid GPGSA message");
|
||||||
|
}
|
||||||
|
GpsStatusAuto = messageParts[1].ToBoolean("A");
|
||||||
|
SatelliteFix = (SatelliteFixType)Enum.Parse(typeof(SatelliteFixType), messageParts[2]);
|
||||||
|
for (var i = 0 + 3; i < 12 + 3; i++) {
|
||||||
|
Pnrs += $"{messageParts[i]},";
|
||||||
|
}
|
||||||
|
|
||||||
|
Pdop = messageParts[15].ToFloat();
|
||||||
|
Hdop = messageParts[16].ToFloat();
|
||||||
|
Vdop = messageParts[17].ToFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Status {GpsStatusAuto} - Satellite Fix Type {SatelliteFix}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
91
NmeaMessages/GprmcMessage.cs
Normal file
91
NmeaMessages/GprmcMessage.cs
Normal file
@@ -0,0 +1,91 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.NmeaMessages {
|
||||||
|
public class GprmcMessage : NmeaMessage {
|
||||||
|
#region Description
|
||||||
|
|
||||||
|
// $GPRMC,123519,A,4807.038,N,01131.000,E,022.4,084.4,230394,003.1,W*6A
|
||||||
|
//
|
||||||
|
// Where:
|
||||||
|
// RMC Recommended Minimum sentence C
|
||||||
|
// 123519 Fix taken at 12:35:19 UTC
|
||||||
|
// A Status A = active or V = Void.
|
||||||
|
// 4807.038, N Latitude 48 deg 07.038' N
|
||||||
|
// 01131.000,E Longitude 11 deg 31.000' E
|
||||||
|
// 022.4 Speed over the ground in knots
|
||||||
|
// 084.4 Track angle in degrees True
|
||||||
|
// 230394 Date - 23rd of March 1994
|
||||||
|
// 003.1,W Magnetic Variation
|
||||||
|
// *6A The checksum data, always begins with *
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
public TimeSpan FixTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Status A = active or V = Void.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsActive { get; set; }
|
||||||
|
|
||||||
|
public double Latitude { get; set; }
|
||||||
|
|
||||||
|
public double Longitude { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Speed over the ground in knots
|
||||||
|
/// </summary>
|
||||||
|
public float Speed { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Track angle in degrees True
|
||||||
|
/// </summary>
|
||||||
|
public float Course { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Date - 23rd of March 1994
|
||||||
|
/// </summary>
|
||||||
|
public DateTime UpdateDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Magnetic Variation
|
||||||
|
/// </summary>
|
||||||
|
public float MagneticVariation { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Magnetic Variation Unit
|
||||||
|
/// </summary>
|
||||||
|
public string MagneticVariationUnit { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Message parsing
|
||||||
|
|
||||||
|
public override void Parse(string[] messageParts) {
|
||||||
|
if (messageParts == null || messageParts.Length < 11) {
|
||||||
|
throw new ArgumentException("Invalid GPGGA message");
|
||||||
|
}
|
||||||
|
FixTime = messageParts[1].ToTimeSpan();
|
||||||
|
IsActive = messageParts[2].ToBoolean("A");
|
||||||
|
Latitude = messageParts[3].ToCoordinates(messageParts[4], CoordinateType.Latitude);
|
||||||
|
Longitude = messageParts[5].ToCoordinates(messageParts[6], CoordinateType.Longitude);
|
||||||
|
Speed = messageParts[7].ToFloat();
|
||||||
|
Course = messageParts[8].ToFloat();
|
||||||
|
UpdateDate = DateTime.ParseExact(messageParts[9], "ddMMyy", CultureInfo.InvariantCulture);
|
||||||
|
MagneticVariation = messageParts[10].ToFloat();
|
||||||
|
MagneticVariationUnit = messageParts[11];
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Latitude {Latitude} - Longitude {Longitude} - Speed {Speed}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
66
NmeaMessages/GpvtgMessage.cs
Normal file
66
NmeaMessages/GpvtgMessage.cs
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.NmeaMessages {
|
||||||
|
public class GpvtgMessage : NmeaMessage {
|
||||||
|
#region Description
|
||||||
|
|
||||||
|
// $GPVTG,054.7,T,034.4,M,005.5,N,010.2,K*48
|
||||||
|
|
||||||
|
// where:
|
||||||
|
// VTG Track made good and ground speed
|
||||||
|
// 054.7,T True track made good(degrees)
|
||||||
|
// 034.4,M Magnetic track made good
|
||||||
|
// 005.5,N Ground speed, knots
|
||||||
|
// 010.2,K Ground speed, Kilometers per hour
|
||||||
|
// *48 Checksum
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Properties
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True track made good(degrees)
|
||||||
|
/// </summary>
|
||||||
|
public float TrackDegrees { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Magnetic track made good
|
||||||
|
/// </summary>
|
||||||
|
public float MagneticTrack { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ground speed, knots
|
||||||
|
/// </summary>
|
||||||
|
public float GroundSpeetKnots { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Ground speed, Kilometers per hour
|
||||||
|
/// </summary>
|
||||||
|
public float GroundSpeed { get; set; }
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Message parsing
|
||||||
|
|
||||||
|
public override void Parse(string[] messageParts) {
|
||||||
|
//$GPVTG,054.7,T,034.4,M,005.5,N,010.2,K * 48
|
||||||
|
if (messageParts == null || messageParts.Length < 9) {
|
||||||
|
throw new ArgumentException("Invalid GPVTG message");
|
||||||
|
}
|
||||||
|
TrackDegrees = messageParts[1].ToFloat();
|
||||||
|
MagneticTrack = messageParts[3].ToFloat();
|
||||||
|
GroundSpeetKnots = messageParts[5].ToFloat();
|
||||||
|
GroundSpeed = messageParts[7].ToFloat();
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public override string ToString() {
|
||||||
|
return $"Speed {GroundSpeed} - Track level {TrackDegrees}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
11
NmeaMessages/NmeaMessage.cs
Normal file
11
NmeaMessages/NmeaMessage.cs
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2.NmeaMessages {
|
||||||
|
public abstract class NmeaMessage {
|
||||||
|
public abstract void Parse(string[] messageParts);
|
||||||
|
}
|
||||||
|
}
|
||||||
27
NmeaParser.cs
Normal file
27
NmeaParser.cs
Normal file
@@ -0,0 +1,27 @@
|
|||||||
|
using GpsClient2.NmeaMessages;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public class NmeaParser {
|
||||||
|
/// <summary>
|
||||||
|
/// Parses a string to the NmeaMessage class.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The nmea string that need to be parsed.</param>
|
||||||
|
/// <returns>Returns an NmeaMessage class. If it cannot parse it will return null.</returns>
|
||||||
|
public NmeaMessage Parse(string message) {
|
||||||
|
if (!message.StartsWith("$")) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
var messageParts = message.RemoveAfter("*").Split(',');
|
||||||
|
var classType = NmeaConstants.GetClassType(messageParts[0].TrimStart('$'));
|
||||||
|
var newInstance = (NmeaMessage)Activator.CreateInstance(classType);
|
||||||
|
newInstance.Parse(messageParts);
|
||||||
|
return newInstance;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
36
Properties/AssemblyInfo.cs
Normal file
36
Properties/AssemblyInfo.cs
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
using System.Reflection;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
|
||||||
|
// General Information about an assembly is controlled through the following
|
||||||
|
// set of attributes. Change these attribute values to modify the information
|
||||||
|
// associated with an assembly.
|
||||||
|
[assembly: AssemblyTitle("GpsClient2")]
|
||||||
|
[assembly: AssemblyDescription("")]
|
||||||
|
[assembly: AssemblyConfiguration("")]
|
||||||
|
[assembly: AssemblyCompany("")]
|
||||||
|
[assembly: AssemblyProduct("GpsClient2")]
|
||||||
|
[assembly: AssemblyCopyright("Copyright © 2023")]
|
||||||
|
[assembly: AssemblyTrademark("")]
|
||||||
|
[assembly: AssemblyCulture("")]
|
||||||
|
|
||||||
|
// Setting ComVisible to false makes the types in this assembly not visible
|
||||||
|
// to COM components. If you need to access a type in this assembly from
|
||||||
|
// COM, set the ComVisible attribute to true on that type.
|
||||||
|
[assembly: ComVisible(false)]
|
||||||
|
|
||||||
|
// The following GUID is for the ID of the typelib if this project is exposed to COM
|
||||||
|
[assembly: Guid("c62e7a96-f279-4390-a1ac-8facdd9e8c14")]
|
||||||
|
|
||||||
|
// Version information for an assembly consists of the following four values:
|
||||||
|
//
|
||||||
|
// Major Version
|
||||||
|
// Minor Version
|
||||||
|
// Build Number
|
||||||
|
// Revision
|
||||||
|
//
|
||||||
|
// You can specify all the values or you can default the Build and Revision Numbers
|
||||||
|
// by using the '*' as shown below:
|
||||||
|
// [assembly: AssemblyVersion("1.0.*")]
|
||||||
|
[assembly: AssemblyVersion("1.0.0.0")]
|
||||||
|
[assembly: AssemblyFileVersion("1.0.0.0")]
|
||||||
53
StringExtensions.cs
Normal file
53
StringExtensions.cs
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Globalization;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Text.RegularExpressions;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public static class StringExtensions {
|
||||||
|
private const string Pattern = @"(\d{2})(\d{2})(\d{2})[.\d{2}]?";
|
||||||
|
|
||||||
|
public static TimeSpan ToTimeSpan(this string inputString) {
|
||||||
|
var regexMatch = Regex.Match(inputString, Pattern);
|
||||||
|
return regexMatch.Groups.Count == 0 ? TimeSpan.Zero : new TimeSpan(0, int.Parse(regexMatch.Groups[1].Value), int.Parse(regexMatch.Groups[2].Value), int.Parse(regexMatch.Groups[3].Value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double ToCoordinates(this string inputString, string cardinalDirection, CoordinateType coordinateType) {
|
||||||
|
if (string.IsNullOrEmpty(inputString)) return 0.0d;
|
||||||
|
|
||||||
|
var degreeCharacters = coordinateType == CoordinateType.Latitude ? 2 : 3;
|
||||||
|
|
||||||
|
var degree = inputString.Substring(0, degreeCharacters).ToDouble();
|
||||||
|
degree += inputString.Substring(degreeCharacters).ToDouble() / 60;
|
||||||
|
|
||||||
|
if (!double.IsNaN(degree) && (cardinalDirection == "S" || cardinalDirection == "W")) {
|
||||||
|
degree *= -1;
|
||||||
|
}
|
||||||
|
return degree;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int ToInteger(this string inputString) {
|
||||||
|
return !string.IsNullOrEmpty(inputString) ? int.Parse(inputString, CultureInfo.InvariantCulture) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static double ToDouble(this string inputString) {
|
||||||
|
return !string.IsNullOrEmpty(inputString) ? double.Parse(inputString, CultureInfo.InvariantCulture) : double.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float ToFloat(this string inputString) {
|
||||||
|
return !string.IsNullOrEmpty(inputString) ? float.Parse(inputString, CultureInfo.InvariantCulture) : float.NaN;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool ToBoolean(this string inputString, string validValue) {
|
||||||
|
return inputString == validValue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static string RemoveAfter(this string inputString, string charValue) {
|
||||||
|
var index = inputString.IndexOf(charValue, StringComparison.Ordinal);
|
||||||
|
return index > 0 ? inputString.Substring(0, index) : inputString;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
85
WindowsLocationApiGpsClient.cs
Normal file
85
WindowsLocationApiGpsClient.cs
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
using GpsClient2.Model;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Device.Location;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace GpsClient2 {
|
||||||
|
public class WindowsLocationApiGpsClient : BaseGpsClient {
|
||||||
|
#region Private Properties
|
||||||
|
|
||||||
|
private GeoCoordinateWatcher _watcher;
|
||||||
|
|
||||||
|
private DateTimeOffset? _previousReadTime;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
public WindowsLocationApiGpsClient(WindowsLocationApiInfo connectionData) : base(GpsType.WindowsLocationApi, connectionData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public WindowsLocationApiGpsClient(BaseGpsInfo connectionData) : base(GpsType.WindowsLocationApi, connectionData) {
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Connect and Disconnect
|
||||||
|
|
||||||
|
public override bool Connect() {
|
||||||
|
var data = (WindowsLocationApiInfo)GpsInfo;
|
||||||
|
|
||||||
|
IsRunning = true;
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connecting);
|
||||||
|
|
||||||
|
_watcher = new GeoCoordinateWatcher();
|
||||||
|
|
||||||
|
_watcher.PositionChanged += WatcherOnPositionChanged;
|
||||||
|
_watcher.StatusChanged += WatcherOnStatusChanged;
|
||||||
|
|
||||||
|
bool result;
|
||||||
|
try {
|
||||||
|
result = _watcher.TryStart(false, TimeSpan.FromMilliseconds(data.Timeout));
|
||||||
|
} catch {
|
||||||
|
Disconnect();
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WatcherOnStatusChanged(object sender, GeoPositionStatusChangedEventArgs e) {
|
||||||
|
switch (e.Status) {
|
||||||
|
case GeoPositionStatus.Ready:
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connected);
|
||||||
|
break;
|
||||||
|
case GeoPositionStatus.Initializing:
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connecting);
|
||||||
|
break;
|
||||||
|
case GeoPositionStatus.NoData:
|
||||||
|
OnGpsStatusChanged(GpsStatus.Connecting);
|
||||||
|
break;
|
||||||
|
case GeoPositionStatus.Disabled:
|
||||||
|
OnGpsStatusChanged(GpsStatus.Disabled);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void WatcherOnPositionChanged(object sender, GeoPositionChangedEventArgs<GeoCoordinate> e) {
|
||||||
|
if (_previousReadTime != null && GpsInfo.ReadFrequenty != 0 && e.Position.Timestamp.Subtract(new TimeSpan(0, 0, 0, 0, GpsInfo.ReadFrequenty)) <= _previousReadTime) return;
|
||||||
|
OnGpsDataReceived(new GpsDataEventArgs(e.Position.Location));
|
||||||
|
_previousReadTime = e.Position.Timestamp;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool Disconnect() {
|
||||||
|
IsRunning = false;
|
||||||
|
_watcher.Stop();
|
||||||
|
_watcher.Dispose();
|
||||||
|
OnGpsStatusChanged(GpsStatus.Disabled);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
}
|
||||||
|
}
|
||||||
BIN
plugins/ETRS89_LAMBERT_UTM_32bits.dll
Normal file
BIN
plugins/ETRS89_LAMBERT_UTM_32bits.dll
Normal file
Binary file not shown.
BIN
plugins/ETRS89_LAMBERT_UTM_64bits.dll
Normal file
BIN
plugins/ETRS89_LAMBERT_UTM_64bits.dll
Normal file
Binary file not shown.
Reference in New Issue
Block a user