// Determine the type of flagging private static string FlaggingType(EventDB eventDB, Id <ControlPoint> controlId1, Id <ControlPoint> controlId2, Id <Leg> legId) { string flaggingType = SelectionDescriptionText.None; FlaggingKind kind = QueryEvent.GetLegFlagging(eventDB, controlId1, controlId2, legId); switch (kind) { case FlaggingKind.All: flaggingType = SelectionDescriptionText.EntireLeg; break; case FlaggingKind.Begin: flaggingType = SelectionDescriptionText.AwayFromControl; break; case FlaggingKind.End: flaggingType = SelectionDescriptionText.IntoControl; break; } // We use slightly different wording based on the finish control. ControlPoint ending = eventDB.GetControl(controlId2); if (ending.kind == ControlPointKind.Finish) { // finish control can influence flagging! if (ending.symbolIds[0] == "14.2" && kind == FlaggingKind.None) { flaggingType = SelectionDescriptionText.FinishFunnel; } else if (ending.symbolIds[0] == "14.2" && kind == FlaggingKind.End) { flaggingType = SelectionDescriptionText.IntoFinishFunnel; } } return(flaggingType); }
// Get a directive line for a finish or crossingpoint. private DescriptionLine GetDirectiveLine(CourseView.CourseViewKind kind, CourseView.ControlView controlView, CourseView.ControlView controlViewPrev) { ControlPoint control = eventDB.GetControl(controlView.controlId); CourseControl courseControl; if (controlView.courseControlIds[0].IsNone) { courseControl = null; } else { courseControl = eventDB.GetCourseControl(controlView.courseControlIds[0]); } Debug.Assert(control.kind == ControlPointKind.Finish || control.kind == ControlPointKind.CrossingPoint || control.kind == ControlPointKind.MapIssue); DescriptionLine line = new DescriptionLine(); line.kind = DescriptionLineKind.Directive; line.boxes = new object[2]; // Figure out the distance in the directive, rounded to nearest 10m. float distance = float.NaN; string distanceText; if (control.kind == ControlPointKind.MapIssue) { if (controlView.legLength != null) { distance = controlView.legLength[0]; } } else { if (controlViewPrev != null && controlViewPrev.legLength != null) { distance = controlViewPrev.legLength[0]; } } if (!float.IsNaN(distance)) { distance = (float)(Math.Round(distance / 10.0) * 10.0); // round to nearest 10 m. distanceText = string.Format("{0} m", distance); } else { distanceText = ""; } // Box 1: directive graphics. string directiveId = control.symbolIds[0]; // Based on the leg flagging, we may modify the finish directive symbol. if (control.kind == ControlPointKind.Finish && (kind == CourseView.CourseViewKind.Normal || kind == CourseView.CourseViewKind.AllVariations)) { FlaggingKind flagging = FlaggingKind.None; if (controlView != null && controlViewPrev != null) { flagging = QueryEvent.GetLegFlagging(eventDB, controlViewPrev.controlId, controlView.controlId); } if (flagging == FlaggingKind.All) { directiveId = "14.1"; // If flagging is All, then finish id must be flagging to finish. } else if (flagging == FlaggingKind.End) { directiveId = "14.2"; // If flagging is Partial, then finish id must be flagging to funnel. } } line.boxes[0] = symbolDB[directiveId]; // Box 2: distance for the control, if any. if (control.kind == ControlPointKind.Finish || control.kind == ControlPointKind.MapIssue) { line.boxes[1] = distanceText; } // Get the text version of the control using the Textifier. Textifier textifier = new Textifier(eventDB, symbolDB, language); line.textual = textifier.CreateTextForDirective(directiveId, distanceText); // The course control ID, for use in coordinating the selection line.controlId = controlView.controlId; line.courseControlId = controlView.courseControlIds[0]; return(line); }
// Change the flagging associated with a leg. If changing to Begin/End flagging, then a bend will be introduced if no bends currently exist // in the leg. If the leg ends in the finish, the finish symbol may be changed to match if appropriate. public static void ChangeFlagging(EventDB eventDB, Id<ControlPoint> controlId1, Id<ControlPoint> controlId2, FlaggingKind flagging) { ControlPoint control1 = eventDB.GetControl(controlId1); ControlPoint control2 = eventDB.GetControl(controlId2); if (control2.kind == ControlPointKind.Finish && flagging == FlaggingKind.All) { // If the leg ends in the finish control, we can set all flagging by just changing the finish control symbol. ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.1"); return; } // We need a leg object. Create a new one or get the existing one. Id<Leg> legId = QueryEvent.FindLeg(eventDB, controlId1, controlId2); Leg leg; if (legId.IsNone) leg = new Leg(controlId1, controlId2); else leg = (Leg) eventDB.GetLeg(legId).Clone(); // Set the flagging kind. leg.flagging = flagging; if (flagging == FlaggingKind.Begin || flagging == FlaggingKind.End) { // These kinds of flagging require a bend in the flaggingStartStop field. if (leg.bends != null && leg.bends.Length > 0) { // Already have a bend we can use. leg.flagStartStop = (flagging == FlaggingKind.Begin) ? leg.bends[leg.bends.Length - 1] : leg.bends[0]; } else { // Create a bend half-way along the leg. leg.flagStartStop = new PointF((control1.location.X + control2.location.X) / 2, (control1.location.Y + control2.location.Y) / 2); leg.bends = new PointF[] { leg.flagStartStop }; } } // Update the leg object. if (legId.IsNone) eventDB.AddLeg(leg); else { if (leg.IsVacuous()) eventDB.RemoveLeg(legId); else eventDB.ReplaceLeg(legId, leg); } // Update the finish control symbol if reasonable. if (control2.kind == ControlPointKind.Finish) { // Update the finish control symbol. if ((flagging == FlaggingKind.None || flagging == FlaggingKind.Begin) && control2.symbolIds[0] == "14.1") { // Remove the "flagged from last control symbol" and change it to "no flagging". ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.3"); } else if (flagging == FlaggingKind.End) { // If partial flagging on the end part of the leg, change the symbol to finish funnel. ChangeDescriptionSymbol(eventDB, controlId2, 0, "14.2"); } } }
public override void ReadAttributesAndContent(XmlInput xmlinput) { controlId1 = new Id<ControlPoint>(xmlinput.GetAttributeInt("start-control")); controlId2 = new Id<ControlPoint>(xmlinput.GetAttributeInt("end-control")); bool first = true; while (xmlinput.FindSubElement(first, "flagging", "bends", "gaps")) { switch (xmlinput.Name) { case "flagging": string flagKind = xmlinput.GetAttributeString("kind"); switch (flagKind) { case "none": flagging = FlaggingKind.None; break; case "beginning-part": flagging = FlaggingKind.Begin; break; case "end-part": flagging = FlaggingKind.End; break; case "all": flagging = FlaggingKind.All; break; default: xmlinput.BadXml("Invalid flagging kind '{0}'", flagKind); break; } if (flagging == FlaggingKind.Begin || flagging == FlaggingKind.End) { float x = xmlinput.GetAttributeFloat("x"); float y = xmlinput.GetAttributeFloat("y"); flagStartStop = new PointF(x, y); } xmlinput.Skip(); break; case "bends": bool firstBend = true; List<PointF> locationList = new List<PointF>(); while (xmlinput.FindSubElement(firstBend, "location")) { float x = xmlinput.GetAttributeFloat("x"); float y = xmlinput.GetAttributeFloat("y"); locationList.Add(new PointF(x, y)); xmlinput.Skip(); firstBend = false; } bends = locationList.ToArray(); break; case "gaps": bool firstGap = true; List<LegGap> gapsList = new List<LegGap>(); while (xmlinput.FindSubElement(firstGap, "gap")) { float start = xmlinput.GetAttributeFloat("start"); float length = xmlinput.GetAttributeFloat("length"); gapsList.Add(new LegGap(start, length)); xmlinput.Skip(); firstGap = false; } gaps = gapsList.ToArray(); break; } first = false; } }