Files
MsAddIns/ZYJSCSMsAddins/ZYJSCSHelpers.cs
2026-02-28 21:01:57 +08:00

440 lines
18 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
}
}