/// <summary> /// Parses KML-based flight data /// </summary> /// <param name="flightData">The string of flight data</param> /// <returns>True for success</returns> public override bool Parse(string szData) { DataTable m_dt = ParsedData; m_dt.Clear(); Boolean fResult = true; byte[] bytes = Encoding.UTF8.GetBytes(szData); KMLElements k = null; MemoryStream stream = null; try { stream = new MemoryStream(bytes); using (StreamReader sr = new StreamReader(stream)) { stream = null; k = new KMLElements(XDocument.Load(sr)); if (k.ele22 != null) { fResult = ParseKMLv2(k); } else if (k.ele != null || k.eleArray != null) { fResult = ParseKMLv1(k); } else { throw new MyFlightbookException(Resources.FlightData.errNoKMLTrack); } } } catch (XmlException ex) { ErrorString = String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errGeneric, ex.Message); fResult = false; } catch (MyFlightbookException ex) { k.sbErr.Append(String.Format(CultureInfo.CurrentCulture, Resources.FlightData.errGeneric, ex.Message)); fResult = false; } finally { stream?.Dispose(); } ErrorString = (k == null) ? string.Empty : k.sbErr.ToString(); return(fResult); }
private bool ParseKMLv2(KMLElements k) { var timeStamps = k.ele22.Descendants(k.ns + "when"); var coords = k.ele22.Descendants(k.ns22 + "coord"); int cCoords = coords.Count(); List <Position> lstSamples = new List <Position>(); for (int iRow = 0; iRow < cCoords; iRow++) { var coord = coords.ElementAt(iRow); string[] rgRow = coord.Value.Split(new char[] { ' ', ',' }, StringSplitOptions.RemoveEmptyEntries); Position sample = new Position(rgRow); if (iRow < timeStamps.Count()) { sample.TypeOfSpeed = Position.SpeedType.Derived; string szTimeStamp = timeStamps.ElementAt(iRow).Value; if (!String.IsNullOrEmpty(szTimeStamp)) { sample.Timestamp = szTimeStamp.ParseUTCDate(); } } lstSamples.Add(sample); } // Derive speed or see if it is available in extended data. bool fHasSpeed = false; var extendedData = k.xmlDoc.Descendants(k.ns22 + "SimpleArrayData"); if (extendedData != null) { // Go through the items to find speed foreach (XElement e in extendedData) { var attr = e.Attribute("name"); if (attr != null && (String.Compare(attr.Value, "speedKts", StringComparison.OrdinalIgnoreCase) == 0 || String.Compare(attr.Value, "speed_kts", StringComparison.OrdinalIgnoreCase) == 0)) { int i = 0; int maxSample = lstSamples.Count; foreach (XElement speedval in e.Descendants()) { string szVal = speedval.Value; if (i < maxSample && double.TryParse(szVal, out double sp)) { Position p = lstSamples[i++]; p.Speed = sp; p.TypeOfSpeed = Position.SpeedType.Reported; fHasSpeed = true; } else { break; } } break; // no need to go through any other elements in extended data } } } // derive speed if we didn't find it above if (!fHasSpeed) { Position.DeriveSpeed(lstSamples); } // And put it into a data table ToDataTable(lstSamples); return(true); }
private bool ParseKMLv1(KMLElements k) { bool fResult = true; Regex r = new Regex("(-?[0-9.]+) *, *(-?[0-9.]+)(?: *, *(-?[0-9]+))? *", RegexOptions.Compiled); string coords; if (k.eleArray != null) { StringBuilder sb = new StringBuilder(); foreach (XElement e in k.eleArray) { sb.Append(e.Value.Replace("\r", " ").Replace("\n", " ")); } coords = sb.ToString(); } else if (k.eleCoords != null) { StringBuilder sb = new StringBuilder(); for (int i = 0; i < k.eleCoords.Count(); i++) { sb.AppendFormat(CultureInfo.InvariantCulture, "{0} ", (k.eleCoords.ElementAt(i).Value.Replace("\r", " ").Replace("\n", " "))); } coords = sb.ToString(); } else { coords = k.ele.Value.Replace("\r", " ").Replace("\n", " "); } MatchCollection mc = r.Matches(coords); if (mc.Count > 0) { List <Position> lstSamples = new List <Position>(); ArrayList al = new ArrayList(); for (int i = 1; i < mc[0].Groups.Count; i++) { if (mc[0].Groups[i].Value.Trim().Length > 0) { al.Add(mc[0].Groups[i].Value); } } for (int iRow = 0; iRow < mc.Count; iRow++) { al.Clear(); GroupCollection gc = mc[iRow].Groups; for (int i = 1; i < gc.Count; i++) { al.Add(gc[i].Value); } try { lstSamples.Add(new Position((string[])al.ToArray(typeof(string)))); } catch (MyFlightbookException ex) { fResult = false; k.sbErr.AppendFormat(CultureInfo.CurrentCulture, "{0}\r\n", ex.Message); } } ToDataTable(lstSamples); } return(fResult); }