// Return the symbol id in column D for a control, or null if none. private string SymbolOfControl(ControlPoint control) { string symbol = null; if (control.symbolIds != null && control.symbolIds.Length >= 2) symbol = control.symbolIds[1]; if (symbol == "") symbol = null; return symbol; }
protected override void WriteControlPoint(ControlPointKind controlKind, ControlPoint control, string code) { string elementName; switch (controlKind) { case ControlPointKind.Start: case ControlPointKind.MapExchange: elementName = "StartPoint"; break; case ControlPointKind.Normal: elementName = "Control"; break; case ControlPointKind.Finish: elementName = "FinishPoint"; break; default: return; } // Write the XML. xmlWriter.WriteStartElement(elementName); xmlWriter.WriteElementString(elementName + "Code", code); if (coordinateMapper != null && coordinateMapper.HasRealWorldCoords) { double realX, realY; coordinateMapper.GetRealWorld(control.location, out realX, out realY); xmlWriter.WriteStartElement("ControlPosition"); xmlWriter.WriteAttributeString("x", XmlConvert.ToString(Math.Round(realX))); xmlWriter.WriteAttributeString("y", XmlConvert.ToString(Math.Round(realY))); xmlWriter.WriteEndElement(); } xmlWriter.WriteStartElement("MapPosition"); xmlWriter.WriteAttributeString("x", XmlConvert.ToString(Math.Round(control.location.X, 2))); xmlWriter.WriteAttributeString("y", XmlConvert.ToString(Math.Round(control.location.Y, 2))); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); }
protected override void WriteControlPoint(ControlPointKind controlKind, ControlPoint control, string code) { string controlType; switch (controlKind) { case ControlPointKind.Normal: controlType = "Control"; break; case ControlPointKind.Start: case ControlPointKind.MapExchange: controlType = "Start"; break; case ControlPointKind.Finish: controlType = "Finish"; break; case ControlPointKind.CrossingPoint: controlType = "CrossingPoint"; break; default: return; } // Write the XML. xmlWriter.WriteStartElement("Control"); xmlWriter.WriteAttributeString("type", controlType); xmlWriter.WriteElementString("Id", code); if (coordinateMapper != null && coordinateMapper.HasRealWorldCoords && coordinateMapper.MapProjectionType == MapModel.MapProjectionType.Known) { double lat, lng; coordinateMapper.GetLatLong(control.location, out lat, out lng); xmlWriter.WriteStartElement("Position"); xmlWriter.WriteAttributeString("lng", XmlConvert.ToString(lng)); xmlWriter.WriteAttributeString("lat", XmlConvert.ToString(lat)); xmlWriter.WriteEndElement(); } xmlWriter.WriteStartElement("MapPosition"); xmlWriter.WriteAttributeString("x", XmlConvert.ToString(Math.Round(control.location.X, 2))); xmlWriter.WriteAttributeString("y", XmlConvert.ToString(Math.Round(control.location.Y, 2))); xmlWriter.WriteEndElement(); xmlWriter.WriteEndElement(); }
// Return true if this leg should be included, false if not. private bool FilterLeg(CourseView.CourseViewKind kind, ControlPoint from, ControlPoint to, Leg leg) { if (leg == null) return false; if (leg.flagging == FlaggingKind.None || leg.flagging == FlaggingKind.End) return false; // Flagged legs that end at the finish or a map exchange are // included in the finish control. if (to.kind == ControlPointKind.Finish || to.kind == ControlPointKind.MapExchange) return false; return true; }
protected abstract void WriteControlPoint(ControlPointKind controlKind, ControlPoint control, string code);
// Add a new control point to the all controls collection. Doesn't add it to any courses, even for a start/finish control. public static Id<ControlPoint> AddControlPoint(EventDB eventDB, ControlPointKind kind, string code, PointF location, float orientation) { ControlPoint newControlPoint = new ControlPoint(kind, code, location); newControlPoint.orientation = orientation; return eventDB.AddControlPoint(newControlPoint); }
// Return true if this control should be included, false if not. private bool FilterControl(CourseView.CourseViewKind kind, ControlPoint control, ControlPoint controlPrev, ControlPoint controlNext) { switch (kind) { case CourseView.CourseViewKind.AllControls: // All controls list shows all kinds. return true; case CourseView.CourseViewKind.Normal: case CourseView.CourseViewKind.AllVariations: // Normal list shows all control kinds. // filter out duplicate crossing points. if (control.kind == ControlPointKind.CrossingPoint && controlPrev != null && controlPrev.kind == ControlPointKind.CrossingPoint) return false; // Don't show map exchange that is the last control being shown. if (control.kind == ControlPointKind.MapExchange && controlNext == null) return false; return true; case CourseView.CourseViewKind.Score: // Score course shows start, normal controls. return (control.kind == ControlPointKind.Normal || control.kind == ControlPointKind.Start); default: Debug.Fail("bad course view kind"); return false; } }
// Get the case of a noun by looking at modifiers. Options allow ignoring the between or cross/junction modifiers string GetNounCase(ControlPoint controlPoint, bool ignoreBetween, bool ignoreCrossJunction, bool ignoreColumnE) { // We check modifiers in the following order, "out to in", so that inner-most modifiers override outermost. // Column H, column G (except "between"), column C, column F (except "cross/junction"), between, cross or junction, column E string nounCase = ""; Symbol[] symbols = GetSymbols(controlPoint); // Column H if (symbols[5] != null) nounCase = ApplyNounCase(symbols[5], nounCase); // Column G except "between" if (symbols[4] != null && symbols[4].Id != "11.15") nounCase = ApplyNounCase(symbols[4], nounCase); // Column C if (symbols[0] != null) nounCase = ApplyNounCase(symbols[0], nounCase); // Column F if (!string.IsNullOrEmpty(controlPoint.columnFText)) { Symbol symbolControllingNounCase; GetTextFromColumnF(controlPoint.columnFText, symbols, out symbolControllingNounCase); if (symbolControllingNounCase != null) nounCase = ApplyNounCase(symbolControllingNounCase, nounCase); } // Between if (!ignoreBetween && symbols[4] != null && symbols[4].Id == "11.15") { Symbol s = symbols[4]; if (!IsDualMainSymbol(symbols)) { s = GetSingleVersionOfComboSymbol(s); } nounCase = ApplyNounCase(s, nounCase); } // Cross or junction if (!ignoreCrossJunction && symbols[3] != null) { Symbol s = symbols[3]; if (!IsDualMainSymbol(symbols)) { s = GetSingleVersionOfComboSymbol(s); } nounCase = ApplyNounCase(s, nounCase); } // Column E if (!ignoreColumnE && symbols[2] != null && symbols[2].Kind == 'E') { nounCase = ApplyNounCase(symbols[2], nounCase); } return nounCase; }
Symbol[] GetSymbols(ControlPoint controlPoint) { string[] ids = controlPoint.symbolIds; Symbol[] symbols = new Symbol[ids.Length]; for (int i = 0; i < ids.Length; ++i) { if (ids[i] != null) symbols[i] = symbolDB[ids[i]]; } return symbols; }
// Get the text associated with the main feature. Normally this is just the symbol in column D. But, // there could be a second main feature in column E. Also handles crossing/junction in column F and between in column G. string GetMainFeatureText(ControlPoint controlPoint, Symbol[] symbols, out string mainFeatureGender) { string mainFeature, mainFeaturePlural, mainFeatureCase, secondaryFeature = null; bool comboUsed = false; mainFeatureGender = ""; if (symbols[1] == null) return ""; // no main symbol. // Get the main feature (column D) and secondary feature (column E, if a column D symbol is there) mainFeatureCase = GetNounCase(controlPoint, false, false, false); mainFeature = GetSymbolText(symbols[1], "", mainFeatureCase); mainFeatureGender = GetSymbolGender(symbols[1]); mainFeaturePlural = GetSymbolPluralText(symbols[1], "", mainFeatureCase); if (symbols[2] != null) { if (symbols[2].Kind == 'D') { // Additional feature used for combination. secondaryFeature = GetSymbolText(symbols[2], "", mainFeatureCase); if (secondaryFeature == mainFeature) secondaryFeature = null; // we treate "road/road/crossing" the same as "road/ /crossing" ==> "road crossing". } else if (symbols[2].Kind == 'E') { // Modifier to the main feature. string modifier = GetSymbolText(symbols[2], mainFeatureGender); mainFeature = string.Format(modifier, mainFeature); if (mainFeaturePlural != null) { string pluralModifier; pluralModifier = GetSymbolPluralText(symbols[2], mainFeatureGender); mainFeaturePlural = string.Format(pluralModifier, mainFeaturePlural); } } } // Do we have crossing/junction combo? if (symbols[3] != null) { mainFeature = CombineSymbols(symbols[3], mainFeature, mainFeaturePlural, secondaryFeature, out mainFeaturePlural, out mainFeatureGender); secondaryFeature = null; comboUsed = true; } // Do have have a between combo? (Note that we can have BOTH a between and a crossing combo.) if (symbols[4] != null && symbols[4].Id == "11.15") { mainFeature = CombineSymbols(symbols[4], mainFeature, mainFeaturePlural, secondaryFeature, out mainFeaturePlural, out mainFeatureGender); comboUsed = true; } if (!comboUsed && secondaryFeature != null) { // No combo symbol present, but a secondary regular symbol present in column E. This is non-standard. mainFeature = CombineSymbols(symbolDB["basic_combo"], mainFeature, mainFeaturePlural, secondaryFeature, out mainFeaturePlural, out mainFeatureGender); } return mainFeature; }
string CreateTextForStartControl(ControlPoint controlPoint) { // Add "Start: " to the description for a regular control. return GetSymbolText(symbolDB["start"], "") + ": " + CreateTextForNormalControl(controlPoint); }
string CreateTextForNormalControl(ControlPoint controlPoint) { Symbol[] symbols = GetSymbols(controlPoint); // Get the main feature, including modifiers and between/crossing/junction modifiers. string fullTextGender; string fullText = GetMainFeatureText(controlPoint, symbols, out fullTextGender); // Add size from coumn F. if (!string.IsNullOrEmpty(controlPoint.columnFText)) { Symbol symbolControllingNounCase; // not used. fullText = fullText + ", " + GetTextFromColumnF(controlPoint.columnFText, symbols, out symbolControllingNounCase); } // Which of many, column C fullText = AddSymbolToCurrent(fullText, fullTextGender, symbols[0]); // Flag location, column G if (symbols[4] != null && symbols[4].Id != "11.15") // "between" is handled elsewhere. fullText = AddSymbolToCurrent(fullText, fullTextGender, symbols[4]); // Extra info (column H) fullText = AddColumnHString(fullText, symbols[5]); // We're done. return fullText; }
public void ReplaceControlPoint(Id<ControlPoint> id, ControlPoint control) { controlPointStore.Replace(id, control); }
public Id<ControlPoint> AddControlPoint(ControlPoint control) { return controlPointStore.Add(control); }