/// <summary> /// 检查异常漂移 /// </summary> /// <param name="aGPSInfo"></param> /// <param name="aPreviousValidGPSData"></param> /// <param name="MaxSpeedMeterPerSecond"></param> private void ComputeMileAgeAndVerifyData( ref KaiYanData aGPSInfo, GPSDataEntity aPreviousValidGPSData, double MaxSpeedMeterPerSecond) { if (aGPSInfo.BaseData.IsLocatedData) { bool blnIsFirstGPSData = false; if (aPreviousValidGPSData == null) { blnIsFirstGPSData = true; } System.TimeSpan dtSpan; double dclMileage = 0; bool blnIsGPSOverflow = false; bool blnShoudBeStillness = false; //是否要记录里程 bool blnIsArrivalDelayed = false; //是否前条时间超过后一条时间 if (!blnIsFirstGPSData) { if (DateTime.Compare(aGPSInfo.BaseData.ReportTime, aPreviousValidGPSData.ReportTime) <= 0) { blnIsArrivalDelayed = true; } double CurrentLatitude = Convert.ToDouble(aGPSInfo.BaseData.Latitude); double CurrentLongitude = Convert.ToDouble(aGPSInfo.BaseData.Longitude); double LastLatitude = Convert.ToDouble(aPreviousValidGPSData.Latitude); double LastLongitude = Convert.ToDouble(aPreviousValidGPSData.Longitude); if ((CurrentLatitude != LastLatitude) || (CurrentLongitude != LastLongitude)) { dclMileage = Transfer.GetDistance(LastLatitude, LastLongitude, CurrentLatitude, CurrentLongitude); } dtSpan = aGPSInfo.BaseData.ReportTime - aPreviousValidGPSData.ReportTime; double dclMaxMileage = Math.Abs(Convert.ToDouble(MaxSpeedMeterPerSecond * dtSpan.TotalSeconds)); if (dclMileage > dclMaxMileage) { //异常:GPS漂移数据 blnIsGPSOverflow = true; aGPSInfo.BaseData.IsOverflowGPSData = blnIsGPSOverflow; } //对速度的判断 if (aGPSInfo.BaseData.Speed > (decimal)(MaxSpeedMeterPerSecond * 3.6)) { blnIsGPSOverflow = true; aGPSInfo.BaseData.IsOverflowGPSData = blnIsGPSOverflow; } //是否要记录里程 if ((aGPSInfo.BaseData.Speed == 0) && (aPreviousValidGPSData.Speed == 0) && (dtSpan.TotalMinutes < 30)) { blnShoudBeStillness = true; } aGPSInfo.BaseData.ControlTime = aPreviousValidGPSData.ControlTime; } if (((!blnIsGPSOverflow) && (!blnIsFirstGPSData) && (!blnShoudBeStillness)) && (!blnIsArrivalDelayed)) { aGPSInfo.BaseData.Mileage = (decimal)dclMileage; //aGPSInfo.AbsoluteMileage = aGPSInfo.AbsoluteMileage + aGPSInfo.Mileage; } } }
/// <summary> /// 分析GPS数据包 /// </summary> /// <param name="buf"></param> /// <param name="aDataStorage"></param> /// <param name="blnShouldResponse"></param> /// <param name="aResponseList"></param> /// <returns></returns> private List<GPSDataEntity> Parse(byte[] buf, out List<byte[]> aResponseList, out string fullGpsCode, string sessionID) { List<GPSDataEntity> ObjectList = new List<GPSDataEntity>(); object result = null; KaiYanData aKaiYanData = new KaiYanData(); KaiYanDecodeData decodeData = new KaiYanDecodeData(); byte[] byteGPSCode = null; string ReplyInstructionMode = ""; decodeData.Decode(buf, base.CodePrefix, ref ReplyInstructionMode, ref aKaiYanData, ref byteGPSCode, out aResponseList); if (base.TransfersType == TransfersType.IsTcp) { if (!String.IsNullOrEmpty(aKaiYanData.FullGpsCode)) { OnAddConnectionEvent(aKaiYanData.FullGpsCode, sessionID); } //更新上一次数据 if (TCPConnList.Instance().IsFirstDataOfConn(sessionID)) { //更改记录状态,标明以后的数据已不是第一点数据 TCPConnList.Instance().UpdateFirstDataRela(sessionID, 0); } } else { if (!String.IsNullOrEmpty(aKaiYanData.FullGpsCode)) { OnAddConnectionEvent(aKaiYanData.FullGpsCode, sessionID); } if (UDPConnList.Instance().IsFirstDataOfConn(sessionID)) { if (string.IsNullOrEmpty(aKaiYanData.FullGpsCode)) { Logger.Error("gpsData.FullGpsCode为空:" + aKaiYanData.BaseData.GPSCode, null); } //更改记录状态,标明以后的数据已不是第一点数据 UDPConnList.Instance().UpdateFirstDataRela(sessionID, 0); } } fullGpsCode = aKaiYanData.FullGpsCode; result = aKaiYanData; ObjectList.Add(aKaiYanData.BaseData); //if (aKaiYanData != null) //{ // if (IsSendRsgsMessage(aKaiYanData, DicIsGPSLocaated, RestartTimeByUnGPSLocaated)) // { // if (aResponseList != null) // { // aResponseList.Add(decodeData.GetRestartDeviceInstruction()); // } // else // { // aResponseList = new System.Collections.Generic.List<byte[]>(); // aResponseList.Add(decodeData.GetRestartDeviceInstruction()); // } // Logger.Trace("UnGPSLocaatedRestart--" + aKaiYanData.FullGpsCode + "--" + DateTime.Now.ToString()); // } //} return ObjectList; }
/// <summary> /// 解析GPS数据 /// </summary> /// <param name="data"></param> /// <param name="kaiyanGPSData"></param> private void DecodeGPSData(byte[] data, ref KaiYanData kaiyanGPSData) { List<byte> lstData = new List<byte>(); try { int _Pos = KAIYAN_GpsDataDateTimeLen; ChangeBytesToList(data, 0, _Pos, ref lstData); kaiyanGPSData.BaseData.ReportTime = DecodeGPSData_DateTime(lstData.ToArray()); lstData = new List<byte>(); ChangeBytesToList(data, _Pos, _Pos + KAIYAN_GpsDataLatitudeLen, ref lstData); kaiyanGPSData.BaseData.Latitude = (decimal)DecodeGPSData_Latitude(lstData.ToArray()); lstData = new List<byte>(); _Pos = KAIYAN_GpsDataDateTimeLen + KAIYAN_GpsDataLatitudeLen + KAIYAN_GpsDataLongitudeLen; ChangeBytesToList(data, KAIYAN_GpsDataDateTimeLen + KAIYAN_GpsDataLatitudeLen, _Pos, ref lstData); kaiyanGPSData.BaseData.Longitude = (decimal)DecodeGPSData_Longitude(lstData.ToArray()); kaiyanGPSData.BaseData.Speed = data[_Pos] & 0x7F; _Pos++; kaiyanGPSData.BaseData.Direction = data[_Pos] & 0x3F; _Pos++; if (((data[_Pos] & 0x0C) >> 2) == 1) { kaiyanGPSData.BaseData.IsLocatedData = false; } else { kaiyanGPSData.BaseData.IsLocatedData = true; } switch ((data[_Pos] & 0x30) >> 4) { case 1: kaiyanGPSData.BaseData.AntennaState = 2;//天线开路 break; case 2: kaiyanGPSData.BaseData.AntennaState = 1;//天线短路 break; case 3: kaiyanGPSData.BaseData.AntennaState = 4;//非适合天线 break; } _Pos++; //GPS的里程是总里程,不能添加到相对里程中(2009-05-28 Liuhh) //kaiyanGPSData.Mileage = GetMileage(data, _Pos + 2, _Pos - 1); //kaiyanGPSData.AbsoluteMileage = GetMileage(data, _Pos + 2, _Pos - 1); kaiyanGPSData.BaseData.StarkMileage = (decimal)GetMileage(data, 17, 15); _Pos += 3; if ((data[_Pos] & 0x01) > 0) { kaiyanGPSData.BaseData.ACCState = 1; } _Pos += 3; if ((data[_Pos] & 0x01) > 0) { kaiyanGPSData.BaseData.PlunderState = 0;//劫警 } if ((data[_Pos] & 0x04) > 0) { kaiyanGPSData.BaseData.AntennaState = 3;//非法断线或者故障 } if ((data[_Pos] & 0x08) > 0) { kaiyanGPSData.BaseData.PowerState = 1;//掉电 } } catch (Exception ex) { Logger.Error("KaiYanDecodeData.DecodeGPSData--[KaiYanDecodeData.DecodeGPSData] " + ex.Message); } }
//判断持续未定位状态时发送重启GPS指令 public bool IsSendRsgsMessage(KaiYanData aKaiYanData, Dictionary<string, DateTime> aDicIsGPSLocaated, double Time) { if (aKaiYanData.BaseData.IsLocatedData) { if (aDicIsGPSLocaated.ContainsKey(aKaiYanData.FullGpsCode)) { aDicIsGPSLocaated[aKaiYanData.FullGpsCode] = aKaiYanData.BaseData.ReceiveTime; } } else { if (!aDicIsGPSLocaated.ContainsKey(aKaiYanData.FullGpsCode)) aDicIsGPSLocaated.Add(aKaiYanData.FullGpsCode, aKaiYanData.BaseData.ReceiveTime); } if (aDicIsGPSLocaated.ContainsKey(aKaiYanData.FullGpsCode)) { TimeSpan ts = aKaiYanData.BaseData.ReceiveTime - aDicIsGPSLocaated[aKaiYanData.FullGpsCode]; if (ts.TotalMinutes > Time) { aDicIsGPSLocaated[aKaiYanData.FullGpsCode] = aKaiYanData.BaseData.ReceiveTime; return true; } } return false; }
/// <summary> /// 解析GPS数据头 /// </summary> /// <param name="data"></param> /// <param name="kaiyanGPSData"></param> private void DecodeGPSHeadData(byte[] data, ref KaiYanData kaiyanGPSData) { string str = ""; string oneByte = ""; for (int i = (data.Length - 1); i > -1; i--) { oneByte=Convert.ToString(data[i], 16); if(oneByte.Length==1) { oneByte="0"+oneByte; } str += oneByte; } kaiyanGPSData.BaseData.GPSCode = str; }
/// <summary> /// 解析其它的GPS数据 /// </summary> /// <param name="data"></param> /// <param name="kaiyanGPSData"></param> private void GetOtherGPSData(byte[] data, ref KaiYanData kaiyanGPSData) { List<byte> lstData = new List<byte>(); try { ChangeBytesToList(data, 0, -1, ref lstData); DecodeGPSData(lstData.ToArray(), ref kaiyanGPSData); } catch (Exception ex) { Logger.Error("KaiYanDecodeData.GetOtherGPSData--[KaiYanDecodeData.GetOtherGPSData] " + ex.Message); } kaiyanGPSData.BaseData.ReceiveTime = DateTime.Now; }
/// <summary> /// 获取GPSCode /// </summary> /// <param name="data"></param> /// <param name="kaiyanGPSData"></param> /// <param name="byteGPSCode"></param> private void GetGPSCode(byte[] data, ref KaiYanData kaiyanGPSData, ref byte[] byteGPSCode) { List<byte> lstData = new List<byte>(); try { ChangeBytesToList(data, 1, 5, ref lstData); byteGPSCode = lstData.ToArray(); DecodeGPSHeadData(lstData.ToArray(), ref kaiyanGPSData); } catch (Exception ex) { Logger.Error("KaiYanDecodeData.GetGPSCode--[KaiYanDecodeData.GetGPSCode] " + ex.Message); } }
/// <summary> /// 解析设备回传停车时间统计信息 /// </summary> /// <param name="data"></param> /// <param name="startPos"></param> /// <param name="GPSSubFunctionDataNum"></param> /// <param name="GPSReplyDataSign"></param> /// <param name="kaiyanGPSData"></param> /// <param name="aResponseList"></param> private void ParseStopInfo(byte[] data, int startPos, byte GPSSubFunctionDataNum, byte GPSReplyDataSign, ref KaiYanData kaiyanGPSData, ref List<byte[]> aResponseList) { List<byte> lstData = new List<byte>(); //因为这种数据会传输比当前时间更早的数据,所以暂时不存储这种数据,等开研公司解决了这种问题后,再行存储 //ChangeBytesToList(data, startPos, -1, ref lstData); //GetOtherGPSData(lstData.ToArray(), ref kaiyanGPSData); if (aResponseList == null) { aResponseList = new List<byte[]>(); } if ((GPSSubFunctionDataNum == 0x04) && (GPSReplyDataSign == 0x03)) { byte[] instruction = GetReplyInstruction(data[data.Length - 5], data[data.Length - 4], data[data.Length - 3]); aResponseList.Add(instruction); } }
/// <summary> /// 解析数据 /// </summary> /// <param name="data"></param> /// <param name="aStrCodePrefix"></param> /// <param name="aConnection"></param> /// <param name="kaiyanGPSData"></param> /// <param name="ReplyInstructionMode">如果是通过TCP回复,该值为TCP,否则为UDP</param> /// <param name="byteGPSCode"></param> /// <param name="aResponseList"></param> public void Decode(byte[] data, string aStrCodePrefix, ref string ReplyInstructionMode, ref KaiYanData kaiyanGPSData, ref byte[] byteGPSCode, out List<byte[]> aResponseList) { GetGPSCode(data, ref kaiyanGPSData, ref byteGPSCode); kaiyanGPSData.FullGpsCode = aStrCodePrefix + kaiyanGPSData.BaseData.GPSCode; aResponseList = null; int _startPos = (KAIYAN_GpsCodeLen + 1); int _endPos = 0; List<byte> lstData = new List<byte>(); ReplyInstructionMode = "TCP"; byte GPSAddress = data[_startPos]; byte GPSFunctionCode = data[_startPos + 1]; //登录 if ((GPSAddress == 0x07) && (GPSFunctionCode == 0x01)) { for (int i = 0; i < data.Length - 1; i++) { lstData.Add(data[i]); if (data[i] == KAIYAN_DataEndSign) { data = lstData.ToArray(); break; } } } byte GPSSubFunctionDataNum = data[_startPos + 2]; byte GPSReplyDataSign = data[data.Length - 6]; //登录 if ((GPSAddress == 0x07) && (GPSFunctionCode == 0x01)) { lstData = new List<byte>(); _startPos += KAIYAN_GpsDataDateTimeLen; ChangeBytesToList(data, _startPos, -1, ref lstData); GetOtherGPSData(lstData.ToArray(), ref kaiyanGPSData); } //点名查询回复 //临时监控查询回复 //基本监控查询回复 //定距查询回复 if ((GPSAddress == 0x03) && ((GPSFunctionCode == 0x01) || (GPSFunctionCode == 0x02) || (GPSFunctionCode == 0x03) || (GPSFunctionCode == 0x04))) { lstData = new List<byte>(); _startPos += KAIYAN_GpsDataDateTimeLen; ChangeBytesToList(data, _startPos, -1, ref lstData); GetOtherGPSData(lstData.ToArray(), ref kaiyanGPSData); } //设备回传停车时间统计信息 if ((GPSAddress == 0x03) && (GPSFunctionCode == 0x46)) { _startPos += 9; ParseStopInfo(data, _startPos, GPSSubFunctionDataNum, GPSReplyDataSign, ref kaiyanGPSData, ref aResponseList); //kaiyanGPSData.IsFetchData = true; //string strHex = ""; //for (int i = 0; i < data.Length - 1; i++) //{ // strHex += ChangeHexDataToString(data[i], true); //} } //终端上传信息 if ((GPSAddress == 0x03) && (GPSFunctionCode == 0x10)) { _startPos += 4; _endPos = data.Length - 6; ParseDeviceUploadInfo(data, _startPos, _endPos, kaiyanGPSData.BaseData.GPSCode, GPSSubFunctionDataNum, GPSReplyDataSign, aStrCodePrefix, ref aResponseList); } //少量盲区补点主动上传 if ((GPSAddress == 0x03) && (GPSFunctionCode == 0x2B)) { kaiyanGPSData.BaseData.IsFetchData = true; lstData = new List<byte>(); _startPos += KAIYAN_GpsDataDateTimeLen; ChangeBytesToList(data, _startPos, -1, ref lstData); GetOtherGPSData(lstData.ToArray(), ref kaiyanGPSData); } //报警信息 if ((GPSAddress == 0x03) && (GPSFunctionCode == 0x0D)) { lstData = new List<byte>(); _startPos += KAIYAN_GpsDataDateTimeLen; _endPos = data.Length - 7; ChangeBytesToList(data, _startPos, _endPos, ref lstData); GetOtherGPSData(lstData.ToArray(), ref kaiyanGPSData); GetAlarmReplyInstruction(ref aResponseList); GetClearStealAlarInstruction(ref aResponseList); GetClearAlarmInstruction(ref aResponseList); } }