qin
2024-09-28 e358beb08f5be49703009b64f058ecfbcfeefbd9
HStation.RevitDev/RevitDataExport/Utility/ParameterOperator.cs
@@ -1,1167 +1,1169 @@
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using HStation.RevitDev.RevitDataExport;
using HStation.RevitDev.RevitDataExport.Common;
using HStation.RevitDev.RevitDataExport.Utility;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Glodon.Revit.Utility
{
    public class ParameterOperator
    {
        public static bool ProcessingManualParameter(Element elem, JObject ret, string paramName)
        {
            if (paramName.ToUpper() == "名称")
            {
                var name = GetParameterValueAsString(elem, "名称");
                if (string.IsNullOrEmpty(name))
                {
                    name = elem.Name;
                }
                ret["名称"] = name;
                return true;
            }
            else if (paramName.ToUpper() == "ID")
            {
                ret["ID"] = elem.Id.IntegerValue.ToString();
                return true;
            }
            else if (paramName == "编码")
            {
                var code = GetParameterValueAsString(elem, "编码");
                if (string.IsNullOrEmpty(code))
                {
                    code = elem.Id.IntegerValue.ToString();
                }
                ret["编码"] = code;
                return true;
            }
            else if (paramName == "位置")
            {
                SetPosition(elem, ret);
                return true;
            }
            else if (paramName == "属性值列表")
            {
                SetParameters(elem, ret);
                return true;
            }
            else if (paramName == "上游节点编码")
            {
                return SetUpperElement(elem, ret);
            }
            else if (paramName == "下游节点编码")
            {
                return SetDownElement(elem, ret);
            }
            else if (paramName == "标签")
            {
                return SetFlag(elem, ret);
            }
            else if (paramName == "标高")
            {
                Level level = elem.GetLevel();
                double offsetValue = 0;
                var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
                if (offset != null)
                {
                    offsetValue = offset.AsDouble();
                }
                ret["标高"] = (level?.Elevation + offsetValue).InnerToMM();
                return true;
            }
            else if (paramName == "池底标高")
            {
                Level level = elem.GetLevel();
                double offsetValue = 0;
                var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
                if (offset != null)
                {
                    offsetValue = offset.AsDouble();
                }
                ret["池底标高"] = (level?.Elevation + offsetValue).InnerToMM();
                return true;
            }
            else
            {
                return false;
            }
        }
        private static bool SetFlag(Element elem, JObject ret)
        {
            string strFlag = GetParameterValueAsString(elem, "标签");
            JArray jArray = new JArray();
            if (!string.IsNullOrEmpty(strFlag))
            {
                var flags = strFlag.Split(',');
                foreach (var flag in flags)
                {
                    jArray.Add(new JValue(flag));
                }
            }
            ret["标签"] = jArray;
            return true;
        }
        private static bool SetDownElement(Element elem, JObject ret)
        {
            var id = elem.Id.IntegerValue.ToString();
            if (elem is FamilyInstance fi)
            {
                var mepModel = (elem as FamilyInstance)?.MEPModel;
                if (mepModel == null)
                {
                    return false;
                }
                var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.Out);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["下游节点编码"] = retStr;
                return true;
            }
            else if (elem is Pipe pipe)
            {
                var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.Out);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["下游节点编码"] = retStr;
                return true;
            }
            return false;
        }
        private static bool SetUpperElement(Element elem, JObject ret)
        {
            var id = elem.Id.IntegerValue.ToString();
            if (elem is FamilyInstance fi)
            {
                var mepModel = (elem as FamilyInstance)?.MEPModel;
                if (mepModel == null)
                {
                    return false;
                }
                var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.In);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["上游节点编码"] = retStr;
                return true;
            }
            else if (elem is Pipe pipe)
            {
                var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.In);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["上游节点编码"] = retStr;
                return true;
            }
            return false;
        }
        private static void SetParameters(Element elem, JObject ret)
        {
            var parameters = elem.Parameters;
            JObject jObj = new JObject();
            foreach (Parameter parameter in parameters)
            {
                ConvertParameter2Jobject(parameter, ref jObj);
            }
            ret["属性值列表"] = jObj;
        }
        private static void SetPosition(Element elem, JObject ret)
        {
            if (elem is Pipe pipe)
            {
                Location location = pipe.Location;
                LocationCurve lCurve = location as LocationCurve;
                Line line = lCurve.Curve as Line;
                XYZ st = line.GetEndPoint(0);
                XYZ end = line.GetEndPoint(1);
                XYZ center = (st + end) / 2;
                var minObj = new JObject();
                minObj["X"] = st.X.InnerToMM();
                minObj["Y"] = st.Y.InnerToMM();
                minObj["Z"] = st.Z.InnerToMM();
                var centerObj = new JObject();
                centerObj["X"] = center.X.InnerToMM();
                centerObj["Y"] = center.Y.InnerToMM();
                centerObj["Z"] = center.Z.InnerToMM();
                var maxObj = new JObject();
                maxObj["X"] = end.X.InnerToMM();
                maxObj["Y"] = end.Y.InnerToMM();
                maxObj["Z"] = end.Z.InnerToMM();
                var outObj = new JObject();
                outObj["Min"] = minObj;
                outObj["Center"] = centerObj;
                outObj["Max"] = maxObj;
                ret["位置"] = outObj;
            }
            else
            {
                var box = elem.get_BoundingBox(null);
                var minObj = new JObject();
                minObj["X"] = box.Min.X.InnerToMM();
                minObj["Y"] = box.Min.Y.InnerToMM();
                minObj["Z"] = box.Min.Z.InnerToMM();
                var centerObj = new JObject();
                if (elem is FamilyInstance fi)
                {
                    if (fi.Location is LocationPoint lp)
                    {
                        var position = lp.Point;
                        centerObj["X"] = position.X.InnerToMM();
                        centerObj["Y"] = position.Y.InnerToMM();
                        centerObj["Z"] = position.Z.InnerToMM();
                    }
                }
                var maxObj = new JObject();
                maxObj["X"] = box.Max.X.InnerToMM();
                maxObj["Y"] = box.Max.Y.InnerToMM();
                maxObj["Z"] = box.Max.Z.InnerToMM();
                var outObj = new JObject();
                outObj["Min"] = minObj;
                outObj["Center"] = centerObj;
                outObj["Max"] = maxObj;
                ret["位置"] = outObj;
            }
        }
        /// <summary>
        /// 构件属性
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static Parameter GetParameterByEnum(Document doc, Element inputElement, string attributeName)
        {
            Parameter useParameter = null;
            try
            {
                var fi = inputElement as FamilyInstance;
                if (null != fi)
                {
                    useParameter = fi.LookupParameter(attributeName);
                    if (useParameter != null)
                    {
                        return useParameter;
                    }
                    useParameter = fi.Symbol.LookupParameter(attributeName);
                    if (null != useParameter) { return useParameter; }
                }
                useParameter = inputElement.LookupParameter(attributeName);
                if (null != useParameter) { return useParameter; }
                Element element = doc.GetElement(inputElement.GetTypeId());
                if (null != element)
                {
                    useParameter = element.LookupParameter(attributeName);
                    if (null != useParameter) { return useParameter; }
                }
            }
            catch (Exception)
            {
            }
            return null;
        }
        public static List<ElementId> GetConnectElements(ConnectorSet connectors, FlowDirectionType direction)
        {
            if (connectors == null || connectors.Size == 0) { return null; }
            var retIds = new List<ElementId>();
            foreach (Connector connector in connectors)
            {
                if (!connector.IsConnected ||
                    (connector.ConnectorType != ConnectorType.End &&
                    connector.ConnectorType != ConnectorType.Curve &&
                    connector.ConnectorType != ConnectorType.Physical))
                {
                    continue;
                }
                if (connector.Direction == direction)
                {
                    var refElems = connector.AllRefs;
                    foreach (Connector item in refElems)
                    {
                        if (!connector.IsConnected ||
                            (connector.ConnectorType != ConnectorType.End &&
                            connector.ConnectorType != ConnectorType.Curve &&
                            connector.ConnectorType != ConnectorType.Physical))
                        {
                            continue;
                        }
                        var owner = item.Owner;
                        if (owner.Id != connector.Owner.Id)
                        {
                            if (owner is PipingSystem)
                            {
                                continue;
                            }
                            else
                            {
                                retIds.Add(item.Owner.Id);
                            }
                        }
                    }
                }
            }
            return retIds;
        }
        public static PipingSystemType GetElementPipingSystemType(Element elem)
        {
            if (elem is Pipe pipe)
            {
                var mepSystem = pipe.MEPSystem;
                if (mepSystem == null) { return null; }
                var typeId = mepSystem.GetTypeId();
                return elem.Document.GetElement(typeId) as PipingSystemType;
            }
            else if (elem is FamilyInstance fi)
            {
                var parameter = fi.LookupParameter("系统类型");
                if (parameter == null) { return null; }
                if (parameter.StorageType == StorageType.String)
                {
                    var name = parameter.AsString();
                    var pst = new FilteredElementCollector(elem.Document).OfClass(typeof(PipingSystemType)).ToElements()?.Cast<PipingSystemType>().ToList()?.Find(x => x.Name == name);
                    return pst;
                }
                else if (parameter.StorageType == StorageType.ElementId)
                {
                    var elemId = parameter.AsElementId();
                    return elem.Document.GetElement(elemId) as PipingSystemType;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static Parameter GetParameter(Document doc, Element inputElement, string attributeName)
        {
            return GetParameterByEnum(doc, inputElement, attributeName);
        }
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="inputParameter"></param>
        /// <returns></returns>
        public static string GetParemeterValue(Parameter parameter)
        {
            if (parameter == null)
            {
                return string.Empty;
            }
            var result = string.Empty;
            if (parameter.StorageType == StorageType.Integer)
            {
                result = parameter.AsInteger().ToString();
            }
            else if (parameter.StorageType == StorageType.Double)
            {
                result = parameter.AsDouble().ToString();
            }
            else if (parameter.StorageType == StorageType.ElementId)
            {
                result = parameter.AsValueString();
            }
            else
            {
                result = string.IsNullOrWhiteSpace(parameter.AsString()) ? parameter.AsValueString() : parameter.AsString();
            }
            if (result == null)
            {
                return string.Empty;
            }
            return result;
        }
        /// <summary>
        /// 获取名称属性值
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static string GetElementName(Element eachElement)
        {
            try
            {
                //获取实例 族与类型 参数值
                Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM);
                string value = GetParemeterValue(param);
                if (!string.IsNullOrEmpty(value))
                {
                    return value;
                }
                return eachElement.Name;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 获取族与类型参数
        /// </summary>
        /// <returns></returns>
        public static string GetElementFamilyAndTypeValue(Element eachElement)
        {
            try
            {
                //获取实例 族与类型 参数值
                Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM);
                string value = GetParemeterValue(param);
                if (!string.IsNullOrEmpty(value))
                {
                    return value;
                }
                //如 族与类型 获取失败,只提取类型名称
                var type = eachElement.Document.GetElement(eachElement.GetTypeId());
                return type == null ? string.Empty : type.Name;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 属性值是否可用
        /// </summary>
        /// <param name="lstParametet"></param>
        /// <param name="paraValue"></param>
        /// <returns></returns>
        private static bool ExtractParameter(IList<Parameter> lstParametet, out string paraValue)
        {
            paraValue = string.Empty;
            foreach (var item in lstParametet)
            {
                var value = GetParemeterValue(item);
                var succeed = value != null
                    && !string.IsNullOrWhiteSpace(value)
                    && value != "0";
                if (succeed)
                {
                    paraValue = value;
                    return succeed;
                }
            }
            return false;
        }
        /// <summary>
        /// 是否为mep构件
        /// </summary>
        /// <returns></returns>
        private static bool IsMEPInstace(BuiltInCategory instanceCategory)
        {
            switch (instanceCategory)
            {
                case BuiltInCategory.OST_DuctSystem:
                case BuiltInCategory.OST_PipingSystem:
                    return true;
                default:
                    return false;
            }
        }
        public static string GetPipeSystemTypeName(Pipe pipe)
        {
            try
            {
                var parameter = pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
                return parameter.AsValueString();
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        public static string GetDuctSystemTypeName(Duct duct)
        {
            try
            {
                var parameter = duct.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM);
                if (parameter == null) { return null; }
                return parameter.AsValueString();
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, BuiltInParameter builtInParameter)
        {
            double? result = null;
            if (elem != null && elem.get_Parameter(builtInParameter) is Parameter para)
            {
                if (para == null || !para.HasValue) { return result; }
                result = para.AsDouble();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="innerTo">单位转换方法</param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string paramName, Func<object, double?> innerTo = null)
        {
            double? result = null;
            if (elem != null)
            {
                try
                {
                    Parameter para = elem.GetParameterByProName(paramName);
                    if (para == null || !para.HasValue) { return result; }
                    switch (para.StorageType)
                    {
                        case StorageType.None:
                            break;
                        case StorageType.Integer:
                            result = para.AsInteger();
                            break;
                        case StorageType.Double:
                            //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General)
                            if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL)
                            {
                                result = innerTo(para.AsDouble());
                            }
                            else
                            {
                                result = para.AsDouble();
                            }
                            break;
                        case StorageType.String:
                            result = StringToDouble(para.AsString());
                            break;
                        case StorageType.ElementId:
                            //不处理
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    return result;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramNames"></param>
        /// <param name="innerTo"></param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string[] paramNames, Func<object, double?> innerTo = null)
        {
            double? result = null;
            foreach (var paramName in paramNames)
            {
                var res = GetParameterValueAsDouble(elem, paramName, innerTo);
                if (res != null)
                {
                    result = res;
                    break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static string GetParameterValueAsString(Element elem, string paramName)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsValueString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static string GetParameterValueAsValueString(Element elem, string paramName)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <param name="innerTo">单位转换方法</param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string paramName, BuiltInParameter builtInParameter, Func<object, double?> innerTo = null)
        {
            double? result = null;
            try
            {
                if (elem != null)
                {
                    Parameter para = elem.GetParameter(paramName, builtInParameter);
                    if (para == null || !para.HasValue) { return result; }
                    switch (para.StorageType)
                    {
                        case StorageType.None:
                            break;
                        case StorageType.Integer:
                            result = para.AsInteger();
                            break;
                        case StorageType.Double:
                            //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General)//传入了单位转换方法 且参数设置了单位
                            if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL)
                            {
                                result = innerTo(para.AsDouble());
                            }
                            else
                            {
                                result = para.AsDouble();
                            }
                            break;
                        case StorageType.String:
                            result = StringToDouble(para.AsString());
                            break;
                        case StorageType.ElementId:
                            //不处理
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static void ConvertParameter2Jobject(Parameter para, ref JObject jObj)
        {
            var name = para.Definition.Name;
            if (para != null)
            {
                switch (para.StorageType)
                {
                    case StorageType.Integer:
                        var intRet = para.AsInteger();
                        jObj[name] = intRet;
                        break;
                    case StorageType.Double:
                        var doubleRet = para.AsDouble();
                        jObj[name] = doubleRet;
                        break;
                    case StorageType.String:
                        var strRet = para.AsString();
                        jObj[name] = strRet;
                        break;
                    case StorageType.ElementId:
                        var elemIdRet = para.AsElementId().IntegerValue;
                        jObj[name] = elemIdRet;
                        break;
                    case StorageType.None:
                    default:
                        jObj[name] = null;
                        break;
                }
            }
            return;
        }
        /// <summary>
        /// 值是字符串,可能是由是数字+单位组成,也可能没有单位
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static double? StringToDouble(string str)
        {
            double? value = null;
            if (string.IsNullOrWhiteSpace(str))
                return value;
            Regex r = new Regex(@"([+-]?(\d*\.\d+([eE]?[+-]?\d+)?|\d+[eE][+-]?\d+))|([+-]?\d*)|([1-9]\d*\.?\d*)|(0\.\d*[1-9])");
            //开始匹配
            Match m = r.Match(str);
            string newStr = "";
            while (m.Success)
            {
                //匹配成功
                newStr += m.Groups[0].Value;
                //从上一个匹配结束的位置开始下一个匹配
                m = m.NextMatch();
            }
            if (newStr == "")
            {
                return value;
            }
            value = Convert.ToDouble(newStr);
            return value;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static string GetParameterValueAsString(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsValueString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static string GetParameterValueAsValueString(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsValueString();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsInt
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static int? GetParameterValueAsInt(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            int? result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger();
                        break;
                    case StorageType.Double:
                        //不处理
                        break;
                    case StorageType.String:
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue;
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsInt
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static int? GetParameterValueAsInt(Element elem, string paramName)
        {
            int? result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger();
                        break;
                    case StorageType.Double:
                        {
                            var ret = para.AsDouble();
                            result = (int)ret;
                            break;
                        }
                    case StorageType.String:
                        {
                            var str = para.AsString();
                            if (int.TryParse(str, out int ret))
                            {
                                return ret;
                            }
                            break;
                        }
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue;
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, BuiltInParameter builtInParameter)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.get_Parameter(builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, string paramName)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取系统类型名称字符串
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtIn"></param>
        /// <returns></returns>
        public static string GetSystemTypeName(Element elem, string paramName, BuiltInParameter builtInParameter = BuiltInParameter.INVALID)
        {
            string res = null;
            try
            {
                if (builtInParameter != BuiltInParameter.INVALID)
                {
                    Parameter para = elem.GetParameter(paramName, builtInParameter);
                    if (para != null)
                    {
                        if (para.StorageType == StorageType.ElementId)
                        {
                            var elemId = para.AsElementId();
                            if (elemId != null && elemId != ElementId.InvalidElementId)
                            {
                                var tempElem = elem.Document.GetElement(elemId);
                                res = tempElem.Name;
                            }
                        }
                        else
                        {
                            res = para.AsValueString();
                        }
                    }
                }
                else
                {
                    Parameter para = elem.GetParameterByProName(paramName);
                    if (para != null)
                    {
                        if (para.StorageType == StorageType.ElementId)
                        {
                            var elemId = para.AsElementId();
                            if (elemId != null && elemId != ElementId.InvalidElementId)
                            {
                                var tempElem = elem.Document.GetElement(elemId);
                                res = tempElem.Name;
                            }
                        }
                        else
                        {
                            res = para.AsValueString();
                        }
                    }
                }
            }
            catch
            {
            }
            return res;
        }
    }
    public static class ParameterUtil
    {
        /// <summary>
        /// 有内置参数的,调用该函数
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName">参数名</param>
        /// <param name="builtInParameter">内置参数</param>
        /// <returns></returns>
        public static Parameter GetParameter(this Element element, string parameterName, BuiltInParameter builtInParameter)
        {
            Parameter para = null;
            try
            {
                if (element is ElementType)
                {
                    para = element.get_Parameter(builtInParameter);
                }
                else
                {
                    para = element.get_Parameter(builtInParameter);
                    if (para == null)
                    {
                        var typeId = element.GetTypeId();
                        if (typeId == null)
                        {
                            return null;
                        }
                        var type = element.Document.GetElement(typeId) as ElementType;
                        para = type.get_Parameter(builtInParameter);
                    }
                }
            }
            catch (Exception ex)
            {
                para = null;
            }
            return para == null ? GetParameterByProName(element, parameterName) : para;
        }
        /// <summary>
        /// 根据参数名获取参数,如果element是类型,获取的就是类型参数,
        /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先
        /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName"></param>
        /// <returns></returns>
        public static Parameter GetParameterByProName(this Element element, string parameterName)
        {
            if (element is ElementType elementType)
            {
                return GetParameterByName(elementType, parameterName);
            }
            else
            {
                var result = GetParameterByName(element, parameterName);
                if (result != null)
                {
                    return result;
                }
                var typeId = element.GetTypeId();
                if (typeId == null || typeId == ElementId.InvalidElementId)
                {
                    return null;
                }
                var type = element.Document.GetElement(typeId) as ElementType;
                return GetParameterByName(type, parameterName);
            }
        }
        /// <summary>
        /// 根据参数名获取参数,如果element是类型,获取的就是类型参数,
        /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先
        /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="paramNames">参数名称列表【有一个匹配则直接返回】</param>
        /// <returns></returns>
        public static Parameter GetParameterByProName(this Element element, List<string> paramNames)
using Autodesk.Revit.DB;
using Autodesk.Revit.DB.Mechanical;
using Autodesk.Revit.DB.Plumbing;
using HStation.RevitDev.RevitDataExport;
using HStation.RevitDev.RevitDataExport.Common;
using HStation.RevitDev.RevitDataExport.Utility;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
namespace Glodon.Revit.Utility
{
    public class ParameterOperator
    {
        public static bool ProcessingManualParameter(Element elem, JObject ret, string paramName)
        {
            if (paramName.ToUpper() == "名称")
            {
                var name = GetParameterValueAsString(elem, "名称");
                if (string.IsNullOrEmpty(name))
                {
                    name = elem.Name;
                }
                ret["名称"] = name;
                return true;
            }
            else if (paramName.ToUpper() == "ID")
            {
                ret["ID"] = elem.Id.IntegerValue.ToString();
                return true;
            }
            else if (paramName == "编码")
            {
                var code = GetParameterValueAsString(elem, "编码");
                if (string.IsNullOrEmpty(code))
                {
                    code = elem.Id.IntegerValue.ToString();
                }
                ret["编码"] = code;
                return true;
            }
            else if (paramName == "位置")
            {
                SetPosition(elem, ret);
                return true;
            }
            else if (paramName == "属性值列表")
            {
                SetParameters(elem, ret);
                return true;
            }
            else if (paramName == "上游节点编码")
            {
                return SetUpperElement(elem, ret);
            }
            else if (paramName == "下游节点编码")
            {
                return SetDownElement(elem, ret);
            }
            else if (paramName == "标签")
            {
                return SetFlag(elem, ret);
            }
            else if (paramName == "标高")
            {
                Level level = elem.GetLevel();
                double offsetValue = 0;
                var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
                if (offset != null)
                {
                    offsetValue = offset.AsDouble();
                }
                ret["标高"] = (level?.Elevation + offsetValue).InnerToMM();
                return true;
            }
            else if (paramName == "池底标高")
            {
                Level level = elem.GetLevel();
                double offsetValue = 0;
                var offset = elem.get_Parameter(BuiltInParameter.INSTANCE_FREE_HOST_OFFSET_PARAM);
                if (offset != null)
                {
                    offsetValue = offset.AsDouble();
                }
                ret["池底标高"] = (level?.Elevation + offsetValue).InnerToMM();
                return true;
            }
            else
            {
                return false;
            }
        }
        private static bool SetFlag(Element elem, JObject ret)
        {
            string strFlag = GetParameterValueAsString(elem, "标签");
            JArray jArray = new JArray();
            if (!string.IsNullOrEmpty(strFlag))
            {
                var flags = strFlag.Split(',');
                foreach (var flag in flags)
                {
                    jArray.Add(new JValue(flag));
                }
            }
            ret["标签"] = jArray;
            return true;
        }
        private static bool SetDownElement(Element elem, JObject ret)
        {
            var id = elem.Id.IntegerValue.ToString();
            if (elem is FamilyInstance fi)
            {
                var mepModel = (elem as FamilyInstance)?.MEPModel;
                if (mepModel == null)
                {
                    return false;
                }
                var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.Out);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["下游节点编码"] = retStr;
                return true;
            }
            else if (elem is Pipe pipe)
            {
                var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.Out);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["下游节点编码"] = retStr;
                return true;
            }
            return false;
        }
        private static bool SetUpperElement(Element elem, JObject ret)
        {
            var id = elem.Id.IntegerValue.ToString();
            if (elem is FamilyInstance fi)
            {
                var mepModel = (elem as FamilyInstance)?.MEPModel;
                if (mepModel == null)
                {
                    return false;
                }
                var ids = GetConnectElements(mepModel.ConnectorManager?.Connectors, FlowDirectionType.In);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["上游节点编码"] = retStr;
                return true;
            }
            else if (elem is Pipe pipe)
            {
                var ids = GetConnectElements(pipe.ConnectorManager?.Connectors, FlowDirectionType.In);
                var strIds = ids.Select(x => x.IntegerValue.ToString()).ToArray();
                var retStr = string.Join(",", strIds);
                ret["上游节点编码"] = retStr;
                return true;
            }
            return false;
        }
        private static void SetParameters(Element elem, JObject ret)
        {
            var parameters = elem.Parameters;
            JObject jObj = new JObject();
            foreach (Parameter parameter in parameters)
            {
                ConvertParameter2Jobject(parameter, ref jObj);
            }
            ret["属性值列表"] = jObj;
        }
        private static void SetPosition(Element elem, JObject ret)
        {
            if (elem is Pipe pipe)
            {
                Location location = pipe.Location;
                LocationCurve lCurve = location as LocationCurve;
                Line line = lCurve.Curve as Line;
                XYZ st = line.GetEndPoint(0);
                XYZ end = line.GetEndPoint(1);
                XYZ center = (st + end) / 2;
                var minObj = new JObject();
                minObj["X"] = st.X.InnerToMM();
                minObj["Y"] = st.Y.InnerToMM();
                minObj["Z"] = st.Z.InnerToMM();
                var centerObj = new JObject();
                centerObj["X"] = center.X.InnerToMM();
                centerObj["Y"] = center.Y.InnerToMM();
                centerObj["Z"] = center.Z.InnerToMM();
                var maxObj = new JObject();
                maxObj["X"] = end.X.InnerToMM();
                maxObj["Y"] = end.Y.InnerToMM();
                maxObj["Z"] = end.Z.InnerToMM();
                var outObj = new JObject();
                outObj["Min"] = minObj;
                outObj["Center"] = centerObj;
                outObj["Max"] = maxObj;
                ret["位置"] = outObj;
            }
            else
            {
                var box = elem.get_BoundingBox(null);
                var minObj = new JObject();
                minObj["X"] = box.Min.X.InnerToMM();
                minObj["Y"] = box.Min.Y.InnerToMM();
                minObj["Z"] = box.Min.Z.InnerToMM();
                var centerObj = new JObject();
                if (elem is FamilyInstance fi)
                {
                    if (fi.Location is LocationPoint lp)
                    {
                        var position = lp.Point;
                        centerObj["X"] = position.X.InnerToMM();
                        centerObj["Y"] = position.Y.InnerToMM();
                        centerObj["Z"] = position.Z.InnerToMM();
                    }
                }
                var maxObj = new JObject();
                maxObj["X"] = box.Max.X.InnerToMM();
                maxObj["Y"] = box.Max.Y.InnerToMM();
                maxObj["Z"] = box.Max.Z.InnerToMM();
                var outObj = new JObject();
                outObj["Min"] = minObj;
                outObj["Center"] = centerObj;
                outObj["Max"] = maxObj;
                ret["位置"] = outObj;
            }
        }
        /// <summary>
        /// 构件属性
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static Parameter GetParameterByEnum(Document doc, Element inputElement, string attributeName)
        {
            Parameter useParameter = null;
            try
            {
                var fi = inputElement as FamilyInstance;
                if (null != fi)
                {
                    useParameter = fi.LookupParameter(attributeName);
                    if (useParameter != null)
                    {
                        return useParameter;
                    }
                    useParameter = fi.Symbol.LookupParameter(attributeName);
                    if (null != useParameter) { return useParameter; }
                }
                useParameter = inputElement.LookupParameter(attributeName);
                if (null != useParameter) { return useParameter; }
                Element element = doc.GetElement(inputElement.GetTypeId());
                if (null != element)
                {
                    useParameter = element.LookupParameter(attributeName);
                    if (null != useParameter) { return useParameter; }
                }
            }
            catch (Exception)
            {
            }
            return null;
        }
        public static List<ElementId> GetConnectElements(ConnectorSet connectors, FlowDirectionType direction)
        {
            if (connectors == null || connectors.Size == 0) { return null; }
            var retIds = new List<ElementId>();
            foreach (Connector connector in connectors)
            {
                if (!connector.IsConnected ||
                    (connector.ConnectorType != ConnectorType.End &&
                    connector.ConnectorType != ConnectorType.Curve &&
                    connector.ConnectorType != ConnectorType.Physical))
                {
                    continue;
                }
                if (connector.Direction == direction)
                {
                    var refElems = connector.AllRefs;
                    foreach (Connector item in refElems)
                    {
                        if (!connector.IsConnected ||
                            (connector.ConnectorType != ConnectorType.End &&
                            connector.ConnectorType != ConnectorType.Curve &&
                            connector.ConnectorType != ConnectorType.Physical))
                        {
                            continue;
                        }
                        var owner = item.Owner;
                        if (owner.Id != connector.Owner.Id)
                        {
                            if (owner is PipingSystem)
                            {
                                continue;
                            }
                            else
                            {
                                retIds.Add(item.Owner.Id);
                            }
                        }
                    }
                }
            }
            return retIds;
        }
        public static PipingSystemType GetElementPipingSystemType(Element elem)
        {
            if (elem is Pipe pipe)
            {
                var mepSystem = pipe.MEPSystem;
                if (mepSystem == null) { return null; }
                var typeId = mepSystem.GetTypeId();
                return elem.Document.GetElement(typeId) as PipingSystemType;
            }
            else if (elem is FamilyInstance fi)
            {
                var parameter = fi.LookupParameter("系统类型");
                if (parameter == null) { return null; }
                if (parameter.StorageType == StorageType.String)
                {
                    var name = parameter.AsString();
                    var pst = new FilteredElementCollector(elem.Document).OfClass(typeof(PipingSystemType)).ToElements()?.Cast<PipingSystemType>().ToList()?.Find(x => x.Name == name);
                    return pst;
                }
                else if (parameter.StorageType == StorageType.ElementId)
                {
                    var elemId = parameter.AsElementId();
                    return elem.Document.GetElement(elemId) as PipingSystemType;
                }
            }
            return null;
        }
        /// <summary>
        /// 获取属性
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static Parameter GetParameter(Document doc, Element inputElement, string attributeName)
        {
            return GetParameterByEnum(doc, inputElement, attributeName);
        }
        /// <summary>
        /// 获取属性值
        /// </summary>
        /// <param name="inputParameter"></param>
        /// <returns></returns>
        public static string GetParemeterValue(Parameter parameter)
        {
            if (parameter == null)
            {
                return string.Empty;
            }
            var result = string.Empty;
            if (parameter.StorageType == StorageType.Integer)
            {
                result = parameter.AsInteger().ToString();
            }
            else if (parameter.StorageType == StorageType.Double)
            {
                result = parameter.AsDouble().ToString();
            }
            else if (parameter.StorageType == StorageType.ElementId)
            {
                result = parameter.AsValueString();
            }
            else
            {
                result = string.IsNullOrWhiteSpace(parameter.AsString()) ? parameter.AsValueString() : parameter.AsString();
            }
            if (result == null)
            {
                return string.Empty;
            }
            return result;
        }
        /// <summary>
        /// 获取名称属性值
        /// </summary>
        /// <param name="doc"></param>
        /// <param name="inputElement"></param>
        /// <param name="attributeName"></param>
        /// <returns></returns>
        public static string GetElementName(Element eachElement)
        {
            try
            {
                //获取实例 族与类型 参数值
                Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM);
                string value = GetParemeterValue(param);
                if (!string.IsNullOrEmpty(value))
                {
                    return value;
                }
                return eachElement.Name;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 获取族与类型参数
        /// </summary>
        /// <returns></returns>
        public static string GetElementFamilyAndTypeValue(Element eachElement)
        {
            try
            {
                //获取实例 族与类型 参数值
                Parameter param = eachElement.get_Parameter(BuiltInParameter.ELEM_FAMILY_AND_TYPE_PARAM);
                string value = GetParemeterValue(param);
                if (!string.IsNullOrEmpty(value))
                {
                    return value;
                }
                //如 族与类型 获取失败,只提取类型名称
                var type = eachElement.Document.GetElement(eachElement.GetTypeId());
                return type == null ? string.Empty : type.Name;
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 属性值是否可用
        /// </summary>
        /// <param name="lstParametet"></param>
        /// <param name="paraValue"></param>
        /// <returns></returns>
        private static bool ExtractParameter(IList<Parameter> lstParametet, out string paraValue)
        {
            paraValue = string.Empty;
            foreach (var item in lstParametet)
            {
                var value = GetParemeterValue(item);
                var succeed = value != null
                    && !string.IsNullOrWhiteSpace(value)
                    && value != "0";
                if (succeed)
                {
                    paraValue = value;
                    return succeed;
                }
            }
            return false;
        }
        /// <summary>
        /// 是否为mep构件
        /// </summary>
        /// <returns></returns>
        private static bool IsMEPInstace(BuiltInCategory instanceCategory)
        {
            switch (instanceCategory)
            {
                case BuiltInCategory.OST_DuctSystem:
                case BuiltInCategory.OST_PipingSystem:
                    return true;
                default:
                    return false;
            }
        }
        public static string GetPipeSystemTypeName(Pipe pipe)
        {
            try
            {
                var parameter = pipe.get_Parameter(BuiltInParameter.RBS_PIPING_SYSTEM_TYPE_PARAM);
                return parameter.AsValueString();
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        public static string GetDuctSystemTypeName(Duct duct)
        {
            try
            {
                var parameter = duct.get_Parameter(BuiltInParameter.RBS_DUCT_SYSTEM_TYPE_PARAM);
                if (parameter == null) { return null; }
                return parameter.AsValueString();
            }
            catch (Exception)
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, BuiltInParameter builtInParameter)
        {
            double? result = null;
            if (elem != null && elem.get_Parameter(builtInParameter) is Parameter para)
            {
                if (para == null || !para.HasValue) { return result; }
                result = para.AsDouble();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="innerTo">单位转换方法</param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string paramName, Func<object, double?> innerTo = null)
        {
            double? result = null;
            if (elem != null)
            {
                try
                {
                    Parameter para = elem.GetParameterByProName(paramName);
                    if (para == null || !para.HasValue) { return result; }
                    switch (para.StorageType)
                    {
                        case StorageType.None:
                            break;
                        case StorageType.Integer:
                            result = para.AsInteger();
                            break;
                        case StorageType.Double:
                            //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General)
                            if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL)
                            {
                                result = innerTo(para.AsDouble());
                            }
                            else
                            {
                                result = para.AsDouble();
                            }
                            break;
                        case StorageType.String:
                            result = StringToDouble(para.AsString());
                            break;
                        case StorageType.ElementId:
                            //不处理
                            break;
                        default:
                            break;
                    }
                }
                catch (Exception ex)
                {
                    return result;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramNames"></param>
        /// <param name="innerTo"></param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string[] paramNames, Func<object, double?> innerTo = null)
        {
            double? result = null;
            foreach (var paramName in paramNames)
            {
                var res = GetParameterValueAsDouble(elem, paramName, innerTo);
                if (res != null)
                {
                    result = res;
                    break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static string GetParameterValueAsString(Element elem, string paramName)
        {
            string result = string.Empty;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsValueString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static string GetParameterValueAsValueString(Element elem, string paramName)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsDouble
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <param name="innerTo">单位转换方法</param>
        /// <returns></returns>
        public static double? GetParameterValueAsDouble(Element elem, string paramName, BuiltInParameter builtInParameter, Func<object, double?> innerTo = null)
        {
            double? result = null;
            try
            {
                if (elem != null)
                {
                    Parameter para = elem.GetParameter(paramName, builtInParameter);
                    if (para == null || !para.HasValue) { return result; }
                    switch (para.StorageType)
                    {
                        case StorageType.None:
                            break;
                        case StorageType.Integer:
                            result = para.AsInteger();
                            break;
                        case StorageType.Double:
                            //if (innerTo != null && para.GetUnitTypeId() != UnitTypeId.General)//传入了单位转换方法 且参数设置了单位
                            if (innerTo != null && para.DisplayUnitType != DisplayUnitType.DUT_GENERAL)
                            {
                                result = innerTo(para.AsDouble());
                            }
                            else
                            {
                                result = para.AsDouble();
                            }
                            break;
                        case StorageType.String:
                            result = StringToDouble(para.AsString());
                            break;
                        case StorageType.ElementId:
                            //不处理
                            break;
                        default:
                            break;
                    }
                }
            }
            catch (Exception ex)
            {
                return null;
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <returns></returns>
        public static void ConvertParameter2Jobject(Parameter para, ref JObject jObj)
        {
            var name = para.Definition.Name;
            if (para != null)
            {
                switch (para.StorageType)
                {
                    case StorageType.Integer:
                        var intRet = para.AsInteger();
                        jObj[name] = intRet;
                        break;
                    case StorageType.Double:
                        var doubleRet = para.AsDouble();
                        jObj[name] = doubleRet;
                        break;
                    case StorageType.String:
                        var strRet = para.AsString();
                        jObj[name] = strRet;
                        break;
                    case StorageType.ElementId:
                        var elemIdRet = para.AsElementId().IntegerValue;
                        jObj[name] = elemIdRet;
                        break;
                    case StorageType.None:
                    default:
                        jObj[name] = null;
                        break;
                }
            }
            return;
        }
        /// <summary>
        /// 值是字符串,可能是由是数字+单位组成,也可能没有单位
        /// </summary>
        /// <param name="str"></param>
        /// <returns></returns>
        private static double? StringToDouble(string str)
        {
            double? value = null;
            if (string.IsNullOrWhiteSpace(str))
                return value;
            Regex r = new Regex(@"([+-]?(\d*\.\d+([eE]?[+-]?\d+)?|\d+[eE][+-]?\d+))|([+-]?\d*)|([1-9]\d*\.?\d*)|(0\.\d*[1-9])");
            //开始匹配
            Match m = r.Match(str);
            string newStr = "";
            while (m.Success)
            {
                //匹配成功
                newStr += m.Groups[0].Value;
                //从上一个匹配结束的位置开始下一个匹配
                m = m.NextMatch();
            }
            if (newStr == "")
            {
                return value;
            }
            value = Convert.ToDouble(newStr);
            return value;
        }
        /// <summary>
        /// 获取参数值 AsString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static string GetParameterValueAsString(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        result = para.AsString();
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger().ToString();
                        break;
                    case StorageType.Double:
                        result = para.AsValueString();
                        break;
                    case StorageType.String:
                        result = para.AsString();
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue.ToString();
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsValueString
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static string GetParameterValueAsValueString(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            string result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsValueString();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsInt
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static int? GetParameterValueAsInt(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            int? result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger();
                        break;
                    case StorageType.Double:
                        //不处理
                        break;
                    case StorageType.String:
                        break;
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue;
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsInt
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static int? GetParameterValueAsInt(Element elem, string paramName)
        {
            int? result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                switch (para.StorageType)
                {
                    case StorageType.None:
                        break;
                    case StorageType.Integer:
                        result = para.AsInteger();
                        break;
                    case StorageType.Double:
                        {
                            var ret = para.AsDouble();
                            result = (int)ret;
                            break;
                        }
                    case StorageType.String:
                        {
                            var str = para.AsString();
                            if (int.TryParse(str, out int ret))
                            {
                                return ret;
                            }
                            break;
                        }
                    case StorageType.ElementId:
                        result = para.AsElementId().IntegerValue;
                        break;
                    default:
                        break;
                }
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, string paramName, BuiltInParameter builtInParameter)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameter(paramName, builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, BuiltInParameter builtInParameter)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.get_Parameter(builtInParameter);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取参数值 AsElementId
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtInParameter"></param>
        /// <returns></returns>
        public static ElementId GetParameterValueAsElementId(Element elem, string paramName)
        {
            ElementId result = null;
            if (elem != null)
            {
                Parameter para = elem.GetParameterByProName(paramName);
                if (para == null || !para.HasValue) { return result; }
                result = para.AsElementId();
            }
            return result;
        }
        /// <summary>
        /// 获取系统类型名称字符串
        /// </summary>
        /// <param name="elem"></param>
        /// <param name="paramName"></param>
        /// <param name="builtIn"></param>
        /// <returns></returns>
        public static string GetSystemTypeName(Element elem, string paramName, BuiltInParameter builtInParameter = BuiltInParameter.INVALID)
        {
            string res = null;
            try
            {
                if (builtInParameter != BuiltInParameter.INVALID)
                {
                    Parameter para = elem.GetParameter(paramName, builtInParameter);
                    if (para != null)
                    {
                        if (para.StorageType == StorageType.ElementId)
                        {
                            var elemId = para.AsElementId();
                            if (elemId != null && elemId != ElementId.InvalidElementId)
                            {
                                var tempElem = elem.Document.GetElement(elemId);
                                res = tempElem.Name;
                            }
                        }
                        else
                        {
                            res = para.AsValueString();
                        }
                    }
                }
                else
                {
                    Parameter para = elem.GetParameterByProName(paramName);
                    if (para != null)
                    {
                        if (para.StorageType == StorageType.ElementId)
                        {
                            var elemId = para.AsElementId();
                            if (elemId != null && elemId != ElementId.InvalidElementId)
                            {
                                var tempElem = elem.Document.GetElement(elemId);
                                res = tempElem.Name;
                            }
                        }
                        else
                        {
                            res = para.AsValueString();
                        }
                    }
                }
            }
            catch
            {
            }
            return res;
        }
    }
    public static class ParameterUtil
    {
        /// <summary>
        /// 有内置参数的,调用该函数
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName">参数名</param>
        /// <param name="builtInParameter">内置参数</param>
        /// <returns></returns>
        public static Parameter GetParameter(this Element element, string parameterName, BuiltInParameter builtInParameter)
        {
            Parameter para = null;
            try
            {
                if (element is ElementType)
                {
                    para = element.get_Parameter(builtInParameter);
                }
                else
                {
                    para = element.get_Parameter(builtInParameter);
                    if (para == null)
                    {
                        var typeId = element.GetTypeId();
                        if (typeId == null)
                        {
                            return null;
                        }
                        var type = element.Document.GetElement(typeId) as ElementType;
                        para = type.get_Parameter(builtInParameter);
                    }
                }
            }
            catch (Exception ex)
            {
                para = null;
            }
            return para == null ? GetParameterByProName(element, parameterName) : para;
        }
        /// <summary>
        /// 根据参数名获取参数,如果element是类型,获取的就是类型参数,
        /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先
        /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName"></param>
        /// <returns></returns>
        public static Parameter GetParameterByProName(this Element element, string parameterName)
        {
            if (element is ElementType elementType)
            {
                return GetParameterByName(elementType, parameterName);
            }
            else
            {
                var result = GetParameterByName(element, parameterName);
                if (result != null)
                {
                    return result;
                }
                var typeId = element.GetTypeId();
                if (typeId == null || typeId == ElementId.InvalidElementId)
                {
                    return null;
                }
                var type = element.Document.GetElement(typeId) as ElementType;
                return GetParameterByName(type, parameterName);
            }
        }
        /// <summary>
        /// 根据参数名获取参数,如果element是类型,获取的就是类型参数,
        /// 如果element是实例,先获取实例参数,如果获取不到,就获取类型参数,实例参数优先
        /// 如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="paramNames">参数名称列表【有一个匹配则直接返回】</param>
        /// <returns></returns>
        public static Parameter GetParameterByProName(this Element element, List<string> paramNames)
        {
            Parameter ret = null;
            foreach (var parameterName in paramNames)
            {
                if (element is ElementType elementType)
                {
                    return GetParameterByName(elementType, parameterName);
                    ret = GetParameterByName(elementType, parameterName);
                    if (ret == null) { continue; }
                }
                else
                {
@@ -1173,50 +1175,55 @@
                    var typeId = element.GetTypeId();
                    if (typeId == null || typeId == ElementId.InvalidElementId)
                    {
                        return null;
                        continue;
                    }
                    var type = element.Document.GetElement(typeId) as ElementType;
                    return GetParameterByName(type, parameterName);
                    ret = GetParameterByName(type, parameterName);
                    if (ret == null) { continue; }
                }
            }
            return null;
        }
        /// <summary>
        /// 根据参数名获取,如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName"></param>
        /// <returns></returns>
        private static Parameter GetParameterByName(this Element element, string parameterName)
        {
            if (string.IsNullOrEmpty(parameterName))
            {
                return null;
            }
            var parameters = element.GetParameters(parameterName);
            if (parameters.Count == 0)
            {
                return null;
            }
            if (parameters.Count == 1)
            {
                return parameters[0];
            }
            //如果参数有多个,获取有值的参数
            var tempParams = parameters.Where(x => !string.IsNullOrEmpty(ParameterOperator.GetParemeterValue(x))).ToList();
            //如果多个参数都没有值 则返回第一个
            if (tempParams.Count == 0)
            {
                return parameters.First();
            }
            //如果只有一个参数有值 则返回这个参数
            if (tempParams.Count == 1)
            {
                return tempParams.First();
            }
            return tempParams.First();
        }
    }
}
                if (ret != null)
                {
                    return ret;
                }
            }
            return null;
        }
        /// <summary>
        /// 根据参数名获取,如果参数有多个,取有参数值的那个,如果多个有参数值,就取第一个有参数值的
        /// </summary>
        /// <param name="element"></param>
        /// <param name="parameterName"></param>
        /// <returns></returns>
        private static Parameter GetParameterByName(this Element element, string parameterName)
        {
            if (string.IsNullOrEmpty(parameterName))
            {
                return null;
            }
            var parameters = element.GetParameters(parameterName);
            if (parameters.Count == 0)
            {
                return null;
            }
            if (parameters.Count == 1)
            {
                return parameters[0];
            }
            //如果参数有多个,获取有值的参数
            var tempParams = parameters.Where(x => !string.IsNullOrEmpty(ParameterOperator.GetParemeterValue(x))).ToList();
            //如果多个参数都没有值 则返回第一个
            if (tempParams.Count == 0)
            {
                return parameters.First();
            }
            //如果只有一个参数有值 则返回这个参数
            if (tempParams.Count == 1)
            {
                return tempParams.First();
            }
            return tempParams.First();
        }
    }
}