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;
}
}
}