/// <summary> /// Reads NMEA data and creates features and records for each line of data. /// </summary> /// <param name="csvFullPath"></param> public static void NMEAToFeatureClass(string sNMEAFile) { try { XmlDocument oDoc = new XmlDocument(); XmlElement oNode = null; AISWrapper.Wrapper myWrapper = new AISWrapper.Wrapper(); ICursor pVoyageCursor = null; ICursor pVesselCursor = null; ICursor pBaseCursor = null; string[] myFiles = Directory.GetFiles(sNMEAFile, "*.txt"); foreach (string myFile in myFiles) { IWorkspace GDBWorkspace = CreateFileGdbWorkspace(sNMEAFile, System.IO.Path.GetFileNameWithoutExtension(myFile) + ".gdb"); ITable pVoyageTable = CreateTable(GDBWorkspace, createVoyageFields(GDBWorkspace), m_cVoyageTableName); ITable pVesselTable = CreateTable(GDBWorkspace, createVesselFields(GDBWorkspace), m_cVesselTabelName); ITable pBaseTable = CreateTable(GDBWorkspace, createBaseStationFields(GDBWorkspace), m_cBaseStationName); RegisterWithGeodatabase(pVoyageTable, "OID"); RegisterWithGeodatabase(pVesselTable, "OID"); RegisterWithGeodatabase(pBaseTable, "OID"); IFeatureClass pFeatureClass = CreateStandaloneFeatureClass(GDBWorkspace, "Broadcast", createFeatureFields(GDBWorkspace, CreateGeographicSR()), "Shape"); clsSupportTables pSupportTable = new clsSupportTables(GDBWorkspace); ITable pUnitsTable = pSupportTable.AddSupportTables(); RegisterWithGeodatabase(pUnitsTable, "OID"); IFeatureCursor featureCursor = pFeatureClass.Insert(true); IFeatureBuffer featureBuffer = pFeatureClass.CreateFeatureBuffer(); int featureCount = 0; int recordCount = 0; int iCurrentVoyageID = 1; List <Vessel> VesselList = new List <Vessel>(); //Hashtable VoyageList = new Hashtable(); DateTime currTime = new DateTime(1900, 1, 1); Hashtable VoyageTable = new Hashtable(); Hashtable VesselTable = new Hashtable(); //Hashtable VoyageTrack = new Hashtable(); int TimeID = pFeatureClass.FindField("BaseDateTime"); int ReceiverType = pFeatureClass.FindField("ReceiverType"); int ReceiverID = pFeatureClass.FindField("ReceiverID"); int MMSIID = pFeatureClass.FindField("MMSI"); int SOGID = pFeatureClass.FindField("SOG"); int COGID = pFeatureClass.FindField("COG"); int ROTID = pFeatureClass.FindField("ROT"); int HeadingID = pFeatureClass.FindField("Heading"); int StatusID = pFeatureClass.FindField("Status"); int VoyageID = pFeatureClass.FindField("VoyageID"); using (StreamReader readFile = new StreamReader(myFile)) { long FileSize = readFile.BaseStream.Length; m_pApplication.StatusBar.ShowProgressBar("Converting " + System.IO.Path.GetFileNameWithoutExtension(myFile) + " to feature class", 0, 100, 1, true); m_pApplication.StatusBar.ProgressBar.Position = 0; //int currentPercent = 0; while (!(readFile.EndOfStream)) //for (int i = 0; i < 500000; i++) { //if (readFile.BaseStream.Position >= 44945408) // MessageBox.Show("here"); //m_pApplication.StatusBar.StepProgressBar(); string myLine1 = readFile.ReadLine(); string myLine2 = ""; int msgType = 0; try { msgType = myWrapper.GetMessageType(myLine1); if (msgType == 5) { string[] sSplit = myLine1.Split(new string[] { "!AIVDM" }, StringSplitOptions.RemoveEmptyEntries); myLine1 = "!AIVDM" + sSplit[0]; myLine2 = "!AIVDM" + sSplit[1]; } else if (msgType == -1) { MessageBox.Show("ere"); } } catch { } switch (msgType) { case 1: case 2: case 3: case 18: case 19: { string myMessage = myWrapper.ParseMessage(myLine1, myLine2); if (myMessage != "") { oDoc.LoadXml(myMessage); PositionMessage pMessage = new PositionMessage(); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Longitude"); if (oNode != null) { pMessage.Longitude = double.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Latitude"); if (oNode != null) { pMessage.Latitude = double.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); if (oNode != null) { pMessage.MMSI = int.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/SOG"); if (oNode != null) { pMessage.SOG = double.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/COG"); if (oNode != null) { pMessage.COG = double.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/ROT"); if (oNode != null) { pMessage.ROT = double.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Heading"); if (oNode != null) { pMessage.Heading = int.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Status"); if (oNode != null) { pMessage.Status = int.Parse(oNode.InnerText); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Time"); pMessage.MessageTime = DateTime.ParseExact(oNode.InnerText, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US")); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/ReceiverID"); if (oNode != null) { pMessage.ReceiverType = oNode.InnerText.Substring(0, 1); pMessage.ReceiverID = oNode.InnerText.Substring(1); } featureCount++; IPoint point = new PointClass(); point.PutCoords(pMessage.Longitude, pMessage.Latitude); point.SpatialReference = CreateGeographicSR(); featureBuffer.Shape = (IGeometry)point; featureBuffer.set_Value(TimeID, pMessage.MessageTime.ToString("yyyy-MM-dd HH:mm")); featureBuffer.set_Value(MMSIID, pMessage.MMSI); featureBuffer.set_Value(SOGID, pMessage.SOG); featureBuffer.set_Value(COGID, pMessage.COG); featureBuffer.set_Value(ROTID, pMessage.ROT); featureBuffer.set_Value(HeadingID, pMessage.Heading); featureBuffer.set_Value(StatusID, pMessage.Status); featureBuffer.set_Value(ReceiverType, pMessage.ReceiverType); featureBuffer.set_Value(ReceiverID, pMessage.ReceiverID); if (!(VoyageTable.ContainsKey(pMessage.MMSI.ToString()))) { Voyage myVoyage = new Voyage(); myVoyage.VoyageID = iCurrentVoyageID++; myVoyage.Destination = ""; VoyageTable.Add(pMessage.MMSI.ToString(), myVoyage); } Voyage thisVoyage = (Voyage)VoyageTable[pMessage.MMSI.ToString()]; featureBuffer.set_Value(VoyageID, thisVoyage.VoyageID); featureCursor.InsertFeature(featureBuffer); /*if (!(VoyageTrack.ContainsKey((int)VoyageTable[pMessage.MMSI.ToString()]))) * VoyageTrack.Add((int)VoyageTable[pMessage.MMSI.ToString()], new List<PointD>()); * * List<PointD> myList = (List<PointD>)VoyageTrack[(int)VoyageTable[pMessage.MMSI.ToString()]]; * myList.Add(new PointD(pMessage.Longitude, pMessage.Latitude)); */ if (featureCount % 1000 == 0) { featureCursor.Flush(); } } } break; case 4: { double dTemp = 0; string myMessage = myWrapper.ParseMessage(myLine1, myLine2); if (myMessage != "") { oDoc.LoadXml(myMessage); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); pBaseCursor = pBaseTable.Insert(false); IRowBuffer pRowBuffer = pBaseTable.CreateRowBuffer(); pRowBuffer.set_Value(pRowBuffer.Fields.FindField("MMSI"), int.Parse(oNode.InnerText)); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Longitude"); if (double.TryParse(oNode.InnerText, out dTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Longitude"), dTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Latitude"); if (double.TryParse(oNode.InnerText, out dTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Latitude"), dTemp); } pBaseCursor.InsertRow(pRowBuffer); } } break; case 5: { string myMessage = myWrapper.ParseMessage(myLine1, myLine2); if (myMessage != "") { oDoc.LoadXml(myMessage); IRowBuffer pRowBuffer = null; int iTemp = 0; oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); string sMMSI = oNode.InnerText; oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Time"); if (oNode != null) { currTime = DateTime.ParseExact(oNode.InnerText, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US")); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Destination"); bool bAddRow = false; if (VoyageTable.ContainsKey(sMMSI)) { Voyage myVoyage = (Voyage)VoyageTable[sMMSI]; if (myVoyage.Destination != oNode.InnerText.Replace("@", "")) { if (myVoyage.Destination != "") { myVoyage.VoyageID = iCurrentVoyageID++; } myVoyage.Destination = oNode.InnerText.Replace("@", ""); VoyageTable[sMMSI] = myVoyage; bAddRow = true; } } if (bAddRow) { IQueryFilter pQueryFilter = new QueryFilterClass(); pQueryFilter.WhereClause = "MMSI = " + sMMSI; ICursor pCursor = pVoyageTable.Search(pQueryFilter, false); IRow pRow = pCursor.NextRow(); if (pRow != null) { pRow.set_Value(pRow.Fields.FindField("EndTime"), currTime); pRow.Store(); } recordCount++; pVoyageCursor = pVoyageTable.Insert(false); pRowBuffer = pVoyageTable.CreateRowBuffer(); if (!(VesselTable.ContainsKey(sMMSI))) { VesselTable.Add(sMMSI, VesselTable.Count + 1); //store the Vessel IDs, according to MMSI } Voyage thisVoyage = (Voyage)VoyageTable[sMMSI]; pRowBuffer.set_Value(pRowBuffer.Fields.FindField("VoyageID"), thisVoyage.VoyageID); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("MMSI"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Destination"); pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Destination"), oNode.InnerText.Replace("@", "").Trim()); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/ETA"); if (int.TryParse(oNode.InnerText, out iTemp)) { string myBinary = ToBinary(iTemp); if (myBinary.Length < 20) { myBinary = myBinary.PadLeft(20, '0'); } int iMinute = Convert.ToInt32(myBinary.Substring(14, 6), 2); int iHour = Convert.ToInt32(myBinary.Substring(9, 5), 2); int iDay = Convert.ToInt32(myBinary.Substring(4, 5), 2); int iMonth = Convert.ToInt32(myBinary.Substring(0, 4), 2); DateTime myDate; if (DateTime.TryParseExact(currTime.Year.ToString("0000-") + iMonth.ToString("00-") + iDay.ToString("00 ") + iHour.ToString("00:") + iMinute.ToString("00:") + "00", "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US"), DateTimeStyles.None, out myDate)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("ETA"), myDate); } } pRowBuffer.set_Value(pRowBuffer.Fields.FindField("StartTime"), currTime); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Draught"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Draught"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Cargo"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Cargo"), iTemp); } pVoyageCursor.InsertRow(pRowBuffer); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Name"); Vessel myVessel = new Vessel(); myVessel.MMSI = sMMSI; myVessel.VesselName = oNode.InnerText.Replace("@", "").Trim(); if (!(VesselList.Contains(myVessel))) { VesselList.Add(myVessel); //store the unique MMSIs in a list /*if (!(VesselTable.ContainsKey(sMMSI))) //store the Vessel IDs, according to MMSI * VesselTable.Add(sMMSI, VesselTable.Count + 1);*/ pVesselCursor = pVesselTable.Insert(false); pRowBuffer = pVesselTable.CreateRowBuffer(); iTemp = 0; //pRowBuffer.set_Value(pRowBuffer.Fields.FindField("VesselID"), VesselTable.Count); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("MMSI"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/IMO"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("IMO"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Call_Sign"); pRowBuffer.set_Value(pRowBuffer.Fields.FindField("CallSign"), oNode.InnerText.Replace("@", "").Trim()); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Name"); pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Name"), oNode.InnerText.Replace("@", "").Trim()); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Type"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("VesselType"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Length"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Length"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Width"); if (int.TryParse(oNode.InnerText, out iTemp)) { pRowBuffer.set_Value(pRowBuffer.Fields.FindField("Width"), iTemp); } oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Dimensions"); pRowBuffer.set_Value(pRowBuffer.Fields.FindField("DimensionComponents"), oNode.InnerText); pVesselCursor.InsertRow(pRowBuffer); } if (recordCount % 1000 == 0) { pVesselCursor.Flush(); } } } break; } double iPercent = ((double)readFile.BaseStream.Position / (double)FileSize) * 100; if (iPercent > m_pApplication.StatusBar.ProgressBar.Position + 1) { m_pApplication.StatusBar.StepProgressBar(); } } //end while if (featureCursor != null) { featureCursor.Flush(); } if (pVoyageCursor != null) { pVoyageCursor.Flush(); } if (pVesselCursor != null) { pVesselCursor.Flush(); } if (pBaseCursor != null) { pBaseCursor.Flush(); } } //end using pSupportTable.CreateRelationshipClass(GDBWorkspace); m_pApplication.StatusBar.HideProgressBar(); } //end for each m_pApplication.StatusBar.HideProgressBar(); } catch (Exception ex) { MessageBox.Show(ex.ToString(), "AIS_Menu:Utilities:ReadCSV2FeatureClass"); } }
/// <summary> /// Parses raw NMEA data and filters by UTM Zone and time step. /// </summary> /// <returns>True on success, False on error.</returns> public bool FilterData() { bool Result = false; string myLine1 = ""; string myLine2 = ""; try { Hashtable VoyageList = new Hashtable(); Hashtable BaseList = new Hashtable(); Hashtable aStreamWriters = ParseZoneList(m_sZones, ref VoyageList, ref BaseList); XmlDocument oDoc = new XmlDocument(); XmlElement oNode; AISWrapper.Wrapper myWrapper = new AISWrapper.Wrapper(); string[] sFiles = Directory.GetFiles(m_sInputDirectory, m_sPattern); List <string> currentList = new List <string>(); Hashtable CurrentTimeTable = new Hashtable(); int[,] messageCounts = new int[sFiles.Length, m_cMsgTypeCount]; foreach (string myFile in sFiles) { Console.WriteLine(String.Format("{0} {1}", Path.GetFileName(myFile), DateTime.Now.ToString())); int percentComplete = 0; Console.Write(String.Format("Percent complete: {0}%\r", percentComplete)); using (StreamReader sr = new StreamReader(myFile)) { while (!(sr.EndOfStream)) { try { myLine1 = sr.ReadLine(); } catch (Exception ex1) { Console.WriteLine(ex1.ToString()); myLine1 = ""; } if (myLine1.StartsWith("!AIVDM")) { myLine2 = ""; int msgType = myWrapper.GetMessageType(myLine1); if (msgType == 5) { string[] sSplit = myLine1.Split(new string[] { "!AIVDM" }, StringSplitOptions.RemoveEmptyEntries); if (sSplit.Length > 1) { myLine1 = "!AIVDM" + sSplit[0]; myLine2 = "!AIVDM" + sSplit[1]; } else { msgType = -1; } } switch (msgType) { case 1: case 2: case 3: case 18: case 19: { string myMessage = myWrapper.ParseMessage(myLine1, ""); if (myMessage != "") { oDoc.LoadXml(myMessage); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); int MMSI = int.Parse(oNode.InnerText); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Longitude"); double dLon = double.Parse(oNode.InnerText); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Latitude"); double dLat = double.Parse(oNode.InnerText); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Time"); if (oNode != null) { DateTime messageTime = DateTime.ParseExact(oNode.InnerText, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US")); int iZone = m_pAOI.GetUTMZone(dLon, dLat); if (iZone > 0) { if (!(CurrentTimeTable.ContainsKey(MMSI))) { CurrentTimeTable.Add(MMSI, messageTime); StreamWriter sw = (StreamWriter)aStreamWriters[iZone]; sw.WriteLine(myLine1); } else { DateTime thisTime = (DateTime)CurrentTimeTable[MMSI]; TimeSpan mySpan = messageTime.Subtract(thisTime); if (mySpan.TotalSeconds >= m_iInterval) { CurrentTimeTable[MMSI] = messageTime; StreamWriter sw = (StreamWriter)aStreamWriters[iZone]; sw.WriteLine(myLine1); } } List <string> listMMSI = (List <string>)VoyageList[iZone]; if (!(listMMSI.Contains(MMSI.ToString()))) { listMMSI.Add(MMSI.ToString()); } } } } } break; case 4: { string myMessage = myWrapper.ParseMessage(myLine1, ""); if (myMessage != "") { oDoc.LoadXml(myMessage); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); int MMSI = int.Parse(oNode.InnerText); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Longitude"); double dLon = double.Parse(oNode.InnerText); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Latitude"); double dLat = double.Parse(oNode.InnerText); int iZone = m_pAOI.GetUTMZone(dLon, dLat); if (iZone > 0) { List <string> listMMSI = (List <string>)BaseList[iZone]; if (!(listMMSI.Contains(MMSI.ToString()))) { oNode = (XmlElement)oDoc.SelectSingleNode("//Message/Time"); if (oNode != null) { DateTime currTime; if (DateTime.TryParseExact(oNode.InnerText, "yyyy-MM-dd HH:mm:ss", new CultureInfo("en-US"), DateTimeStyles.None, out currTime)) { StreamWriter sw = (StreamWriter)aStreamWriters[iZone]; sw.WriteLine(myLine1); listMMSI.Add(MMSI.ToString()); } } } } } } break; case 5: { string myMessage = myWrapper.ParseMessage(myLine1, myLine2); if (myMessage != "") { oDoc.LoadXml(myMessage); oNode = (XmlElement)oDoc.SelectSingleNode("//Message/MMSI"); string sMMSI = oNode.InnerText; foreach (int thisZone in VoyageList.Keys) { List <string> myList = (List <string>)VoyageList[thisZone]; if (myList.Contains(sMMSI)) { StreamWriter sw = (StreamWriter)aStreamWriters[thisZone]; sw.WriteLine(myLine1 + myLine2); } } } } break; case 24: { foreach (StreamWriter sw in aStreamWriters.Values) { sw.WriteLine(myLine1 + myLine2); } } break; default: break; } //end switch } //end if if ((((double)sr.BaseStream.Position / (double)sr.BaseStream.Length) * 100) > percentComplete + 1) { percentComplete++; Console.Write(String.Format("Percent complete: {0}%\r", percentComplete)); } } //end while } //end using input Console.WriteLine(DateTime.Now.ToString()); } //end for Result = true; foreach (StreamWriter sw in aStreamWriters.Values) { sw.Close(); } Console.Read(); } //end try catch (Exception ex) { Console.WriteLine(ex.ToString() + "\r\n"); Console.WriteLine(myLine1); Console.WriteLine(myLine2); Console.Read(); Result = false; } return(Result); }