Files
MsAddIns/ZYJSCSMsAddins/ZYJSCSHelpers.cs

440 lines
18 KiB
C#
Raw Permalink Normal View History

2026-02-28 21:01:57 +08:00
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using Bentley.DgnPlatformNET;
using Bentley.DgnPlatformNET.DgnEC;
using Bentley.DgnPlatformNET.Elements;
using Bentley.ECObjects.Instance;
using Bentley.ECObjects.Schema;
using Bentley.MstnPlatformNET;
namespace ZYJSCSMsAddins
{
/// <summary>
/// 专业技术措施,面积:平方米,体积:立方米,长度:米,个数:个
/// </summary>
/// <example>var models = ZYJSCSHelpers.GetDataByLevelName("JG_ZYJSCS");</example>
public class ZYJSCSHelpers
{
/// <summary>
/// 获取元素的图层,如果是一般单元,则按第一个子元素来获取
/// </summary>
/// <param name="element"></param>
/// <returns></returns>
private static LevelHandle GetLevel(Element element)
{
ElementPropertiesGetter getter = new ElementPropertiesGetter(element);
var lvlcache = Session.Instance.GetActiveDgnFile().GetLevelCache();
//一般单元
if (element.GetChildren().Count() > 0)
{
foreach (var elem in element.GetChildren())
{
if (elem is DisplayableElement && !elem.IsInvisible)
{
return GetLevel(elem);
}
}
}
return lvlcache.GetLevel(getter.Level, true);
}
/// <summary>
/// 按图层获取数据
/// </summary>
/// <param name="levelName"></param>
/// <returns>数据集合</returns>
public static List<JSCSModel> GetDataByLevelName(string levelName)
{
//获取当前激活的模型
DgnModel dgnModel = Session.Instance.GetActiveDgnModel();
//获取图层
var layer = dgnModel.GetLevelCache().GetLevelByName(levelName);
if (layer == null)
{
Debug.WriteLine("图层为空");
return new List<JSCSModel>();
}
//拿到图层上的元素
var groups = dgnModel.GetGraphicElements()
.Where(e => e.LevelId == layer.LevelId || GetLevel(e).LevelId == layer.LevelId)
.GroupBy(e => GetJSCSPropertyValue(e, "ID-100-名称")?.ToString());
List<JSCSModel> models = new List<JSCSModel>();
foreach (var group in groups)
{
var li = group.ToList();
var first = GetJSCSPropertyValue(li.FirstOrDefault(), "ID-100-计量方式")?.ToString();
//计量方式都一致
//var b = li.TrueForAll(e => GetJSCSPropertyValue(e, "ID-100-计量方式") == first);
JSCSModel model = new JSCSModel(first, li);
models.Add(model);
}
return models;
}
/// <summary>
/// 通过属性名获取钢筋的属性值
/// </summary>
/// <param name="elem">元素</param>
/// <param name="propName">属性名</param>
/// <returns>属性值,可根据情况进行转换数据类型</returns>
public static object GetJSCSPropertyValue(Element elem, string propName)
{
var instances = new CustomItemHost(elem, false).CustomItems;
object value = default;
foreach (var instance in instances)
{
if (instance.ClassDefinition.DisplayLabel == "专业技术措施" && instance.ContainsValues)
{
foreach (var propValue in instance)
{
if (propValue.Property.DisplayLabel == propName && propValue.TryGetNativeValue(out value))
{
break;
}
}
}
}
return value;
}
/// <summary>
/// 获取元素的长度
/// </summary>
/// <param name="elem">元素</param>
/// <returns>长度值单位m</returns>
public static double GetLength(Element elem)
{
var uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;
double length = default;
if (elem is LineElement line)
{
length = line.GetCurveVector().SumOfLengths();
}
if (elem is ComplexStringElement complexString)
{
length = complexString.GetCurveVector().SumOfLengths();
}
if (elem is LineStringBaseElement lineStringBase)
{
length = lineStringBase.GetCurveVector().SumOfLengths();
}
if (elem is EllipseElement ellipseElement)
{
length = ellipseElement.GetCurveVector().SumOfLengths();
}
if (elem is ComplexShapeElement complexShape)
{
length = complexShape.GetCurveVector().SumOfLengths();
}
if (elem is BSplineCurveElement bSplineCurve)
{
length = bSplineCurve.GetCurveVector().SumOfLengths();
}
return length / uorMeter;
}
/// <summary>
/// 获取属性
/// </summary>
/// <param name="element"></param>
public static List<IECPropertyValue> GetProperties(Element element, string propName)
{
if (null == element)
{
throw new ArgumentNullException(nameof(element), "所提供ElemId无效");
}
List<IECPropertyValue> eCProperties = new List<IECPropertyValue>();
DgnECManager ecManager = DgnECManager.Manager;
int count = 0;
DgnECInstanceCollection instCol = ecManager.GetElementProperties(element, ECQueryProcessFlags.SearchAllClasses);
foreach (IDgnECInstance inst in instCol)
{
count++;
IEnumerator<IECProperty> propertyEnum = inst.ClassDefinition.GetEnumerator();
while (propertyEnum.MoveNext())
{
IECPropertyValue propertyValue = inst.GetPropertyValue(propertyEnum.Current.Name);
if (propertyValue.IsArray)
{
IECArrayValue arrayVal = propertyValue as IECArrayValue;
if (arrayVal.Count >= 1)
propertyValue = arrayVal[0];
}
var prop = propertyEnum.Current.Name;
ECNameValidation.DecodeFromValidName(ref prop);
if (propName == prop)
{
eCProperties.Add(propertyValue);
}
}
}
return eCProperties;
}
}
public class JSCSModel
{
private readonly double uorMeter = Session.Instance.GetActiveDgnModel().GetModelInfo().UorPerMeter;
public JSCSModel(string measure, List<Element> elements)
{
Measurement = GetMeasurement(measure);
AssociateElements = elements;
Name = ZYJSCSHelpers.GetJSCSPropertyValue(elements.FirstOrDefault(), "ID-100-名称")?.ToString();
}
public StringBuilder Message { get; private set; }
private double GetArea()
{
//StringBuilder sb = new StringBuilder();
double area = default;
foreach (var elem in AssociateElements)
{
var prop = ZYJSCSHelpers.GetProperties(elem, "SurfaceArea").FirstOrDefault();
if (prop != null)
{
prop.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description};面积:{d}");
area += d;
}
if (elem is CellHeaderElement cellElem)
{
foreach (var child in cellElem.GetChildren())
{
var childProp = ZYJSCSHelpers.GetProperties(child, "SurfaceArea").FirstOrDefault();
if (childProp != null)
{
childProp.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description}中的子元素{child.ElementId}{child.Description};面积:{d}");
area += d;
}
}
}
if (elem is SharedCellElement sharedCell)
{
var definition = sharedCell.GetDefinition(Session.Instance.GetActiveDgnFile());
foreach (var child in definition.GetChildren())
{
var childProp = ZYJSCSHelpers.GetProperties(child, "SurfaceArea").FirstOrDefault();
if (childProp != null)
{
childProp.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description}中的子元素{child.ElementId}{child.Description};面积:{d}");
area += d;
}
}
}
}
//Message = sb;
return Math.Round(area, 3, MidpointRounding.AwayFromZero);
}
private double GetLength()
{
double length = default;
//StringBuilder sb = new StringBuilder();
foreach (var elem in AssociateElements)
{
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description};长度:{ZYJSCSHelpers.GetLength(elem)}");
length += ZYJSCSHelpers.GetLength(elem);
}
//Message = sb;
return Math.Round(length, 3, MidpointRounding.AwayFromZero);
}
private Measurement GetMeasurement(string measure)
{
if (string.IsNullOrEmpty(measure))
{
return Measurement.Unknow;
}
if (measure == "个数" || measure == "个" || measure == "数量")
{
return Measurement.Count;
}
else if (measure == "长度" || measure == "长" || measure == "毫米" || measure == "米" || measure == "厘米")
{
return Measurement.Length;
}
else if (measure == "面积" || measure.StartsWith("平方"))
{
return Measurement.Area;
}
else if (measure == "体积" || measure.StartsWith("立方"))
{
return Measurement.Volume;
}
return Measurement.Unknow;
}
private double GetVolume()
{
double volume = default;
//StringBuilder sb = new StringBuilder();
foreach (var elem in AssociateElements)
{
//直接可以读取
var prop = ZYJSCSHelpers.GetProperties(elem, "Volume").FirstOrDefault();
if (prop != null)
{
prop.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description};体积:{d}");
volume += d;
}
//一般单元,能看到子元素
if (elem.GetChildren().Count() > 0)
{
foreach (var child in elem.GetChildren())
{
var childProp = ZYJSCSHelpers.GetProperties(child, "Volume").FirstOrDefault();
if (childProp != null)
{
childProp.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description}中的子元素{child.ElementId}{child.Description};体积:{d}");
volume += d;
}
}
}
//共享单元看不到子元素
if (elem is SharedCellElement sharedCell)
{
//var definition = sharedCell.GetDefinition(Session.Instance.GetActiveDgnFile());
DropGeometry geom = new DropGeometry();
geom.SetOptions(DropGeometry.Options.OPTION_SharedCells);
geom.SetSharedCellOptions(DropGeometry.SharedCells.SHAREDCELL_Geometry);
var status = MstnMixedAssistant.ElementOperation.DropElement(sharedCell, out var agenda, geom);
if (status == StatusInt.Success)
{
for (uint i = 0; i < agenda.GetCount(); i++)
{
var child = agenda.GetEntry(i);
var childProp = ZYJSCSHelpers.GetProperties(child, "Volume").FirstOrDefault();
//第一次打散后,但是还是找不到体积属性,需要二次打散
if (childProp == null)
{
DropGeometry geomSub = new DropGeometry();
geomSub.SetOptions(DropGeometry.Options.OPTION_AppData);
geomSub.SetSolidsOptions(DropGeometry.Solids.SOLID_Surfaces);
var statusSub = MstnMixedAssistant.ElementOperation.DropElement(child, out var agendaSub, geomSub);
if (statusSub == StatusInt.Success)
{
for (uint j = 0; j < agendaSub.GetCount(); j++)
{
var childSub = agendaSub.GetEntry(j);
var childPropSub = ZYJSCSHelpers.GetProperties(childSub, "Volume").FirstOrDefault();
if (childPropSub != null)
{
childPropSub.TryGetNativeValue(out var valueSub);
var d = Convert.ToDouble(valueSub) / (uorMeter * uorMeter * uorMeter);
volume += d;
}
}
}
}
else
{
childProp.TryGetNativeValue(out var value);
double d = Convert.ToDouble(value) / (uorMeter * uorMeter * uorMeter);
//sb.AppendLine($"父元素{elem.ElementId}{elem.Description}中的子元素{child.ElementId}{child.Description};体积:{d}");
volume += d;
}
}
}
}
}
//Message = sb;
return Math.Round(volume, 3, MidpointRounding.AwayFromZero);
}
//private int GetCount()
//{
// StringBuilder sb = new StringBuilder();
// foreach (var elem in AssociateElements)
// {
// sb.AppendLine($"父元素{elem.ElementId}{elem.Description}个数1");
// }
// Message = sb;
// return 1;
//}
public List<Element> AssociateElements { get; }
/// <summary>
/// 计量方式
/// </summary>
public Measurement Measurement
{
get; private set;
}
public string Unit { get; private set; }
public string Name { get; }
public double Result
{
get
{
double result = 0.0;
switch (Measurement)
{
case Measurement.Count:
result = AssociateElements.Count;
//result = GetCount();
break;
case Measurement.Length:
result = GetLength();
Unit = "m";
break;
case Measurement.Area:
result = GetArea();
Unit = "㎡";
break;
case Measurement.Volume:
result = GetVolume();
Unit = "m³";
break;
case Measurement.Unknow:
break;
}
return result;
}
}
}
/// <summary>
/// 计量方式
/// </summary>
public enum Measurement
{
Unknow,
/// <summary>
/// 个数
/// </summary>
Count,
/// <summary>
/// 长度
/// </summary>
Length,
/// <summary>
/// 面积
/// </summary>
Area,
/// <summary>
/// 体积
/// </summary>
Volume
}
}