public static PdfWaypoint ToPdfWaypoint(this GeoWaypoint gwp, string datumName, string utmZone, AltitudeUnits units) { var utmCoords = gwp.Coordinates.ToUtm(Datum.GetInstance(datumName), utmZone); var altitude = utmCoords.Altitude; var wp = new AXWaypoint(gwp.Name, gwp.Time, utmCoords.Easting, utmCoords.Northing, altitude); return new PdfWaypoint() { Name = wp.Name, CompetitionCoords = wp.ToString(AXPointInfo.CompetitionCoords8).Replace("/", " / "), Altitude = wp.ToString(units == AltitudeUnits.Meters ? AXPointInfo.AltitudeInMeters : AXPointInfo.AltitudeInFeet) }; }
public override void Process() { base.Process(); // parse and resolve pilot dependent values // the static values are already defined // syntax is already checked switch (Definition.ObjectType) { case "LNP": //nearest to point from list //LNP(<desiredPoint>, <listPoint1>, <listPoint2>, ..., <altitudeThreshold>) //TODO: what kind of distance should be used? d2d, d3d or drad? { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length - 1); var referencePoint = list[0].Point; if (referencePoint == null) { Point = null; AddNote(list[0].GetFirstNoteText(), true); //inherit notes from ref point } else { for (var i = 1; i < list.Length; i++) { var nextPoint = list[i].Point; if (nextPoint == null) { continue; } else if (Point == null || Physics.DistanceRad(referencePoint, nextPoint, altitudeThreshold) < Physics.DistanceRad(referencePoint, Point, altitudeThreshold)) { Point = nextPoint; } } if (Point == null) { //all points are null AddNote(list[1].GetFirstNoteText(), true); //inherit notes from first point } } } break; case "LFT": //first in time from list //LFT(<listPoint1>, <listPoint2>, …) { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length); foreach (var p in list) { var nextPoint = p.Point; if (nextPoint == null) { continue; } else if (Point == null || nextPoint.Time < Point.Time) { Point = nextPoint; } } if (Point == null) { //all points are null AddNote(list[0].GetFirstNoteText(), true); //inherit notes from first point } } break; case "LLT": //last in time from list //LLT(<listPoint1>, <listPoint2>) { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length); foreach (var p in list) { var nextPoint = p.Point; if (nextPoint == null) { continue; } else if (Point == null || nextPoint.Time > Point.Time) { Point = nextPoint; } } if (Point == null) { //all points are null AddNote(list[0].GetFirstNoteText(), true);; //inherit notes from first point } } break; case "LFNN": //first not null from list //LFNN(<listPoint1>, <listPoint2>, …) { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length); foreach (var p in list) { var nextPoint = p.Point; if (nextPoint != null) { Point = nextPoint; break; } } if (Point == null) { //all points are null AddNote(list[0].GetFirstNoteText(), true); //inherit notes from first point } } break; case "LLNN": //last not null from list //LLNN(<listPoint1>, <listPoint2>, …) { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length); foreach (var p in list.Reverse()) { var nextPoint = p.Point; if (nextPoint != null) { Point = nextPoint; break; } } if (Point == null) { //all points are null AddNote(list[0].GetFirstNoteText(), true); //inherit notes from first point } } break; case "MVMD": //MVMD: virtual marker drop //MVMD(<number>) /* * algorithm: * if exists marker with the same number * if the marker is valid * point = marker * else * point = null * else * if the contest landing is valid * point = landing * else * point = null */ { var marks = from mark in Engine.Report.Markers where int.Parse(mark.Name) == number select "M" + mark.ToString(AXPointInfo.CustomReport); Task.LoggerMarks.AddRange(marks); var marker = Engine.Report.Markers.FirstOrDefault(m => int.Parse(m.Name) == number); if (marker != null) { var nearestPoint = Engine.TaskValidTrack.Points.FirstOrDefault(p => Math.Abs((p.Time - marker.Time).TotalSeconds) == 0); if (nearestPoint != null) { Point = new AXWaypoint("M" + marker.Name, marker); } else { AddNote(string.Format("R12.21.1: invalid marker drop #{0}", number), true); } } else { if (Engine.Settings.ContestLanding && Engine.Report.Markers.FirstOrDefault(m => int.Parse(m.Name) > number) != null) { var validLanding = Engine.TaskValidTrack.Points.FirstOrDefault(p => Math.Abs((p.Time - Engine.Report.LandingPoint.Time).TotalSeconds) == 0); if (validLanding != null) { Point = new AXWaypoint("Landing", Engine.Report.LandingPoint); AddNote(string.Format("no marker #{0}: assuming contest landing", number), true); } } else { AddNote(string.Format("RII.17.d: no marker drop #{0}", number), true); } } } break; case "MPDGD": //pilot declared goal with default altitude //MPDGD(<number>, <defaultAltitude>) { var marks = from mark in Engine.Report.DeclaredGoals where mark.Number == number select "D" + mark.ToString(AXPointInfo.CustomReport); Task.LoggerMarks.AddRange(marks); // look for declarations var goals = Engine.Report.DeclaredGoals.Where(g => g.Number == number); if (goals.Count() == 0) { AddNote("no goal declaration #" + number.ToString(), true); } else { //look for last declaration var goal = goals.Last(); try { Point = TryResolveGoalDeclaration(goal, true); } catch (InvalidOperationException) { AddNote("R12.3: invalid goal declaration #" + number.ToString(), true); } } } break; case "MPDGF": //pilot declared goal with forced altitude //MPDGF(<number>, <defaultAltitude>) { var marks = from mark in Engine.Report.DeclaredGoals where mark.Number == number select "D" + mark.ToString(AXPointInfo.CustomReport); Task.LoggerMarks.AddRange(marks); // look for declarations var goals = Engine.Report.DeclaredGoals.Where(g => g.Number == number); if (goals.Count() == 0) { AddNote("no goal declaration #" + number.ToString(), true); } else { //look for last declaration var goal = goals.Last(); try { Point = TryResolveGoalDeclaration(goal, false); } catch (InvalidOperationException) { AddNote("R12.3: invalid goal declaration #" + number.ToString(), true); } } } break; case "TLCH": //TLCH: take off //TLCH() if (Engine.Report != null) { Point = new AXWaypoint(Definition.ObjectName, Engine.Report.TakeOffPoint); } break; case "TLND": //TLND: landing //TLND() if (Engine.Report != null) { Point = new AXWaypoint(Definition.ObjectName, Engine.Report.LandingPoint); } break; case "TPT": //TPT at point time //TPT(<pointName>) try { var referenceScriptingPoint = Resolve <ScriptingPoint>(0); var referencePoint = referenceScriptingPoint.Point; if (referencePoint == null) { Point = null; AddNote(referenceScriptingPoint.GetFirstNoteText(), true); // inherit ref point notes } else { Point = new AXWaypoint(Definition.ObjectName, Engine.Report.CleanTrack.First(p => p.Time == referencePoint.Time)); } } catch (InvalidOperationException) { AddNote("no valid track point at specified time", true); } //none found break; case "TNP": //nearest to point //TNP(<pointName>, <altitudeThreshold>) //TODO: what kind of distance should be used? d2d, d3d or drad? { var referenceScriptingPoint = Resolve <ScriptingPoint>(0); var referencePoint = referenceScriptingPoint.Point; if (referencePoint == null) { Point = null; AddNote(referenceScriptingPoint.GetFirstNoteText(), true); // inherit ref point notes } else { foreach (var nextTrackPoint in Engine.TaskValidTrack.Points) { if (Point == null || Physics.DistanceRad(referencePoint, nextTrackPoint, altitudeThreshold) < Physics.DistanceRad(referencePoint, Point, altitudeThreshold)) { Point = new AXWaypoint(Definition.ObjectName, nextTrackPoint); } } if (Point == null) { AddNote("no remaining valid track points", true); } } } break; case "TFP": //farthest from point //TFP(<pointName>, <altitudeThreshold>) { var referenceScriptingPoint = Resolve <ScriptingPoint>(0); var referencePoint = referenceScriptingPoint.Point; if (referencePoint == null) { Point = null; AddNote(referenceScriptingPoint.GetFirstNoteText(), true); // inherit ref point notes } else { foreach (var nextTrackPoint in Engine.TaskValidTrack.Points) { if (Point == null || Physics.DistanceRad(referencePoint, nextTrackPoint, altitudeThreshold) > Physics.DistanceRad(referencePoint, Point, altitudeThreshold)) { Point = new AXWaypoint(Definition.ObjectName, nextTrackPoint); } } if (Point == null) { AddNote("no remaining valid track points", true); } } } break; case "TNL": //nearest to point list //TNL(<listPoint1>, <listPoint2>, ..., <altitudeThreshold>) { var list = ResolveN <ScriptingPoint>(0, Definition.ObjectParameters.Length - 1); var bestDistance = double.PositiveInfinity; var nnull = 0; foreach (var p in list) { var listPoint = p.Point; if (listPoint == null) { nnull++; continue; } foreach (var trackPoint in Engine.TaskValidTrack.Points) { var dist = Physics.DistanceRad(listPoint, trackPoint, altitudeThreshold); if (Point == null || dist < bestDistance) { Point = new AXWaypoint(Definition.ObjectName, trackPoint); bestDistance = dist; } } } if (nnull == list.Length) { //all points are null AddNote(list[0].GetFirstNoteText(), true); //inherit notes from first point } else if (Point == null) { AddNote("no remaining valid track points", true); } } break; case "TDT": //delayed in time //TDT(<pointName>, <timeDelay>[, <maxTime>]) { var referencePoint = Resolve <ScriptingPoint>(0).Point; if (referencePoint == null) { AddNote("the reference point is null", true); } else { AXPoint point_tmp; if (maxTime.HasValue) { point_tmp = Engine.TaskValidTrack.Points.FirstOrDefault(p => p.Time >= referencePoint.Time + timeDelay && p.Time <= maxTime); } else { point_tmp = Engine.TaskValidTrack.Points.FirstOrDefault(p => p.Time >= referencePoint.Time + timeDelay); } if (point_tmp != null) { Point = new AXWaypoint(Definition.ObjectName, point_tmp); } else { AddNote("no valid track point within time limits", true); } } } break; case "TDD": //delayed in distance //TDD(<pointName>, <distanceDelay>[, <maxTime>]) { var referencePoint = Resolve <ScriptingPoint>(0).Point; if (referencePoint == null) { AddNote("the reference point is null", true); } else { AXPoint point_tmp; if (maxTime.HasValue) { point_tmp = Engine.TaskValidTrack.Points.FirstOrDefault(p => Physics.Distance2D(p, referencePoint) >= distanceDelay && p.Time <= maxTime); } else { point_tmp = Engine.TaskValidTrack.Points.FirstOrDefault(p => Physics.Distance2D(p, referencePoint) >= distanceDelay); } if (point_tmp != null) { Point = new AXWaypoint(Definition.ObjectName, point_tmp); } else { AddNote("no valid track point within distance limits", true); } } } break; case "TAFI": //area first in //TAFI(<areaName>) { var area = Resolve <ScriptingArea>(0); try { var tafi = Engine.TaskValidTrack.Points.First(p => area.Contains(p)); Point = new AXWaypoint(Definition.ObjectName, tafi); } catch { AddNote("no valid track point inside the area", true); } } break; case "TAFO": //area first out //TAFO(<areaName>) { var area = Resolve <ScriptingArea>(0); try { var tafi = Engine.TaskValidTrack.Points.First(p => area.Contains(p)); var tafi_no = Engine.TaskValidTrack.Points.FirstOrDefault(p => p.Time > tafi.Time && !area.Contains(p)); //next out AXPoint tafo; if (tafi_no != null) { tafo = Engine.TaskValidTrack.Points.Last(p => p.Time < tafi_no.Time && area.Contains(p)); } else { //last valid track point is inside the area and no exits tafo = Engine.TaskValidTrack.Points.Last(p => area.Contains(p)); // == TALO } Point = new AXWaypoint(Definition.ObjectName, tafo); } catch { AddNote("no valid track point inside the area", true); } } break; case "TALI": //area last in //TALI(<areaName>) { var area = Resolve <ScriptingArea>(0); try { var talo = Engine.TaskValidTrack.Points.Last(p => area.Contains(p)); var talo_po = Engine.TaskValidTrack.Points.LastOrDefault(p => p.Time < talo.Time && !area.Contains(p)); //previous out AXPoint tali; if (talo_po != null) { tali = Engine.TaskValidTrack.Points.First(p => p.Time > talo_po.Time && area.Contains(p)); } else { //first valid track point is inside the area and no exits tali = Engine.TaskValidTrack.Points.First(p => area.Contains(p)); // == TAFI } Point = new AXWaypoint(Definition.ObjectName, tali); } catch { AddNote("no valid track point inside the area", true); } } break; case "TALO": //area last out //TALO(<areaName>) { var area = Resolve <ScriptingArea>(0); try { var talo = Engine.TaskValidTrack.Points.Last(p => area.Contains(p)); Point = new AXWaypoint(Definition.ObjectName, talo); } catch { AddNote("no valid track point inside the area", true); } } break; } if (Point != null) { AddNote("resolved to " + Point.ToString()); } else { AddNote("could not be resolved"); } //if (!string.IsNullOrEmpty(Log)) // Notes = ObjectName + ":" + Notes; }