// 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);
        }
Exemple #3
0
        // 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");
                }
            }
        }
Exemple #4
0
        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;
            }
        }