using System.Text; using System.Text.RegularExpressions; using System.Windows; using Autodesk.Revit.Attributes; using Autodesk.Revit.DB; using Autodesk.Revit.DB.Structure; using CommunityToolkit.Mvvm.DependencyInjection; using FuzzySharp; using JiebaNet.Segmenter; using Nice3point.Revit.Toolkit.External; using Szmedi.RevitToolkit.Approval.Controls.ProgressWrapper; using Szmedi.RevitToolkit.Approval.Extensions; namespace Szmedi.RevitToolkit.Approval.Commands { /// /// 自动处理标识和编码 /// [Transaction(TransactionMode.Manual)] [Regeneration(RegenerationOption.Manual)] public class ProcessMetroSignCmd : ExternalCommand { const string sign = "深圳构件标识"; const string code = "AM-100-EAM分类编码"; //private StringBuilder sb = new StringBuilder(); public override void Execute() { var categories = GlobalAssists.GetMetroClassificationModels(); // var UiApplication = commandData.Application; // var Document = UiApplication.ActiveUIDocument.Document; //sb.AppendLine($"标识,优化标识,匹配,比率,"); Document.InvokeGroup( _ => { var confirmSign = NeedRemoveParameter(sign); if (!confirmSign) { return; } var codeSign = NeedRemoveParameter(code); if (!codeSign) { return; } //var isSignParamExist = SharedParameterAssists.IsExistProjectParam( // Document, // SignParamName, // out var signdef, // out var signbinding); //var isCodeParamExist = SharedParameterAssists.IsExistProjectParam( // Document, // code, // out var codedef, // out var codebinding); var set = UiApplication.Application.Create.NewCategorySet(); //StringBuilder sb = new(); var builtInCategories = Enum.GetValues(typeof(BuiltInCategory)); foreach (BuiltInCategory cate in builtInCategories) { try { //有的类别不支持这个方法获取 var category = Category.GetCategory(Document, cate); if (category is { CategoryType: CategoryType.Model, AllowsBoundParameters: true }) { set.Insert(category); } } catch (Exception ex) { //sb.AppendLine($"{ex.Message}:{cate}"); } } //if (isSignParamExist) //{ // Document.Invoke( // _ => // { // signbinding.Categories = set; // //signdef.ParameterGroup // // }, // "重新绑定标识参数类别"); //} //else //{ // Document.AddSharedParameter(SignParamName, set, BuiltInParameterGroup.PG_IFC); //} //if (isCodeParamExist) //{ // Document.Invoke( // _ => // { // codebinding.Categories = set; // Document.ParameterBindings.ReInsert(codedef, codebinding); // }, // "重新绑定编码参数类别"); //} //else //{ // Document.AddSharedParameter(code, set, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES); //} Document.AddSharedParameter(sign, set, BuiltInParameterGroup.PG_IFC); Document.AddSharedParameter(code, set, BuiltInParameterGroup.PG_ADSK_MODEL_PROPERTIES); var allElements = Document.OfAllModelCollector().ToElements().GroupBy(e => e.GetTypeId()); try { Document.Invoke( _ => { var signs = GlobalAssists.GetMetroSigns(); foreach (var group in allElements) { var categoryName = GetMapperSign(group, signs); foreach (var elem in group) { var signParam = elem.LookupParameter(sign); var codeParam = elem.LookupParameter(code); //获取元素类别名称 signParam?.SetValue(categoryName); Document.Regenerate(); var classification = categories.FirstOrDefault(d => d.CategoryName == categoryName); codeParam?.SetValue(classification?.Code); } } }); } catch (Exception ex) { MessageBox.Show(ex.Message); } }, "填写轨道交通标识和编码"); MessageBox.Show("处理完成", "完成", MessageBoxButton.OK, MessageBoxImage.Information); //File.WriteAllText(Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\匹配结果" + ".csv", // sb.ToString(), Encoding.UTF8); } private string GetMapperSign(IGrouping elementGroup, List signs) { if (elementGroup.Key == ElementId.InvalidElementId) { return string.Empty; } var categoryName = elementGroup.FirstOrDefault().Category?.Name; //如果没有匹配到,使用类型名进行匹配 var type = Document.GetElement(elementGroup.Key) as ElementType; var famName = type.FamilyName; ConfigManager.ConfigFileBaseDir = Path.Combine(RvApp.AddInDirectory, "configs"); var segmenter = new JiebaSegmenter(); var subText = $"{type.Name} {famName} {categoryName}"; var replaceText = subText.ExtractChinese(); var segments = segmenter.Cut(replaceText).Distinct(); var combinedText = string.Join(" ", segments); string resultName = string.Empty; double minRatio = 30; foreach (var sign in signs) { //var defText = SignParamName.Replace(majorName, ""); var segmentsDef = segmenter.Cut(sign); var defText = string.Join(" ", segmentsDef); var tempRatio = Fuzz.TokenSetRatio(defText, combinedText); //var tempRatio = Fuzz.Ratio(SignParamName, segment); if (tempRatio >= minRatio) { //sb.AppendLine($"{sign},{defText},{combinedText},{tempRatio},"); //Mappers.Add(new(replaceText, SignParamName, tempRatio)); minRatio = tempRatio; resultName = sign; } } return resultName; } private bool NeedRemoveParameter(string paramName) { var dict = SharedParameterAssists.GetParameterElementBindings(Document) .Where(d => d.Key.Name == paramName); if (dict.Any()) { var result = MessageBox.Show( $"已存在一个或多个{paramName}的参数定义,将全部进行删除,并重新添加,是否继续?", "警告", MessageBoxButton.YesNo, MessageBoxImage.Warning); if (result == MessageBoxResult.Yes) { Document.Invoke( _ => { Document.Delete([.. dict.Select(d => d.Key).Select(p => p.Id)]); }, $"删除现有{paramName}参数"); } else { return false; } } return true; } } }