仮にUSBのGPS受信機を購入して、仮想COMポートから信号を取り出せるとする。
次は、具体的な処理方法や、もっと言っちゃえば、他人の仕事が気になってくる。
・・と調べていたら、やっぱりちゃんと記事にしている人がいる。
処理手順の参考
1.行頭の'$'を待つ
GGA(Global Positioning System Fix Data)
RMC(RMC - Recommended Minimum Specific GNSS Data)センテンスのみを取得
2.文字数チェック GGAの場合 1行64〜74文字の場合のみ有効データとする。
3.1行のデータを構造体に入れてそれぞれパラメータをチェック
4.データを計算用に整形
5.GPSから吸い出したウエィポイントと突き合わせ
/***
GpsConnectorLib.cs
GPSを動かすライブラリ
for C#2.0(VisualStudio2005)
Date: 2007/12/21
Author: Sho Hashimoto
WebSite: http://shokai.org
***/
using System;
using System.Collections.Generic;
using System.Text;
using System.IO.Ports;
namespace Org.Shokai.Gis.Gps
{
///
/// 北半球/南半球を表す列挙体
///
public enum HemiSpheriumNS
{
///
/// 北半球
///
North,
///
/// 南半球
///
South
}
///
/// 東半球/西半球を表す列挙体
///
public enum HemiSpheriumEW
{
///
/// 東半球
///
East,
///
/// 西半球
///
West
}
///
/// GPS Information Data
///
class GpsData
{
///
/// 経度
///
public double lon = Int32.MinValue; // 緯度
///
/// 緯度
///
public double lat = Int32.MinValue; // 経度
///
/// 北半球/南半球を表す列挙体
///
public HemiSpheriumNS NS;
///
/// 東半球/西半球を表す列挙体
///
public HemiSpheriumEW EW;
public GpsData()
{
NS = HemiSpheriumNS.North; // 北半球
EW = HemiSpheriumEW.East; // 東半球
}
}
class GpsConnector
{
public GpsData gpsData = new GpsData();
public GpsConnector()
{
serialPort = new SerialPort();
PortName = "COM1";
BaudRate = 4800;
serialPort.DataReceived += serialPort_DataReceived;
hasError = true;
}
#region Property and Accessor
public Boolean hasError;
private SerialPort serialPort;
public String PortName
{
set
{
this.serialPort.PortName = value;
}
get
{
return this.serialPort.PortName;
}
}
public int BaudRate
{
set
{
this.serialPort.BaudRate = value;
}
get
{
return this.serialPort.BaudRate;
}
}
public Boolean IsOpen
{
get
{
return this.serialPort.IsOpen;
}
}
#endregion
#region Method
public Boolean Open()
{
if (IsOpen) return false; // 既に開いている
try
{
serialPort.Open();
}
catch
{
}
return serialPort.IsOpen;
}
public Boolean Close()
{
if (!IsOpen) return false; // 既に閉じている
try
{
serialPort.Close();
}
catch
{
}
return serialPort.IsOpen;
}
override public String ToString()
{
String gpsStat = "";
if (hasError) gpsStat += "エラー有り\r\n";
else gpsStat += "エラー無し\r\n";
gpsStat += "経度:" + gpsData.lon + " 緯度:" + gpsData.lat;
if (gpsData.EW == HemiSpheriumEW.East)
{
gpsStat += ",東半球";
}
else if (gpsData.EW == HemiSpheriumEW.West)
{
gpsStat += ",西半球";
}
if (gpsData.NS == HemiSpheriumNS.North)
{
gpsStat += ",北半球";
}
else if (gpsData.NS == HemiSpheriumNS.South)
{
gpsStat += ",南半球";
}
gpsStat += "\r\n";
gpsStat += "Port:" + PortName + ",BaudRate:" + BaudRate;
return gpsStat;
}
#endregion
#region Event
private void serialPort_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
{
String recvData = serialPort.ReadLine();
// parse Data from GPS
String[] data = recvData.Split(',');
switch (data[0])
{
#region case "$CPGGA":
case "$GPGGA":
hasError = false; // reset error flag
if (data[2] != "") // 緯度
{
Double value = Double.Parse(data[2]);
gpsData.lat = (value % 100)/60 + (int)value / 100;
}
else
{
//gpsData.lat = Int32.MinValue;
hasError = true;
}
if (data[3] == "N") // 北半球
{
gpsData.NS = HemiSpheriumNS.North;
}
else if (data[3] == "S") // 南半球
{
gpsData.lat *= -1; // 南緯
gpsData.NS = HemiSpheriumNS.South;
}
else hasError = true;
if (data[4] != "") // 経度
{
Double value = Double.Parse(data[4]);
gpsData.lon = (value%100)/60 + (int)value / 100;
}
else
{
//gpsData.lon = Int32.MinValue;
hasError = true;
}
if (data[5] == "E") // 東半球
{
gpsData.EW = HemiSpheriumEW.East;
}
else if (data[5] == "W") // 西半球
{
gpsData.lon *= -1; // 西経
gpsData.EW = HemiSpheriumEW.West;
}
else hasError = true;
break;
#endregion
case "$GPRMC":
break;
case "$GPGSA":
break;
}
#if DEBUG
Console.WriteLine(recvData);
#endif
}
#endregion
}
}