/// <summary> /// Размер вреда от превышения допустимых осевых нагрузок на ось (ПО ФОРМУЛЕ) /// </summary> private static float GetAxisDamageByFormula(AutoRoad road, Axis axis) { float damage; RoadType t = road.RoadType; float kd = Settings.Default.ConstDorojhnoKlimatZon; float kk = Settings.Default.ConstKapitalniyRemont; float kc = Settings.Default.Klimat_usloviya ? 1f : 0.35f; float p = ConstDamageDefault(t); float a = ConstA(t); float b = ConstB(t); float h = ConstH(t); float over = axis.GetOver(); if (!road.IsSoftClothes) { // для дорог с одеждой капитального и облегченного типа, в том числе для зимнего периода года var pOver = (float)Math.Pow(over, 1.92f); damage = kd * kk * kc * p * (1 + 0.2f * pOver * (a / h - b)); } else { // для дорог с одеждой переходного типа, в том числе для зимнего периода года var pOver = (float)Math.Pow(over, 1.24f); damage = kk * kc * p * (1 + 0.14f * pOver * (a / h - b)); } return(damage); }
/// <summary> /// Размер вреда от превышения допустимых осевых нагрузок на ось /// </summary> private static float GetAxisDamage(AutoRoad road, Axis axis) { float over = axis.GetOver(); float overPercent = axis.GetOverPercent(); if (over <= 0 || overPercent <= Settings.Default.DopustimiyProcentAxis) { return(0); } float damage = -1; //Размер вреда, причиняемого тяжеловесными транспортными средствами, //при движении таких транспортных средств по автомобильным дорогам федерального значения if (road.IsFederalRoad && (road.RoadType == RoadType.R10Tc || road.RoadType == RoadType.R115Tc)) { string percent = overPercent.ToString(NumberFormatInfo.InvariantInfo); DataRow damageAxisRow = Program.GetAccess("SELECT TOP 1 * FROM " + "(SELECT Damage, ProcentLimit FROM DamageAxis " + $"WHERE {percent} < ProcentLimit " + $"AND TypeRoadId = {(int)road.RoadType} " + "ORDER BY ProcentLimit ASC)").Rows[0]; damage = float.Parse(damageAxisRow["Damage"].ToString()); if (Math.Abs(damage) < 0.1f) { return(0); } if (damage > -1) { if (Settings.Default.Klimat_usloviya) { damage *= Settings.Default.ConstKlimatAxisMult; } // есть в ayt.su, но не нашел в законе // if (overPercent < 10) { // damage *= .2f; // } else { // damage *= .6f; // } } } if (damage <= -1) { damage = GetAxisDamageByFormula(road, axis); } return((float)Math.Round(damage, 2)); }
private static void PopulateAxisBlockLoadLimitsAndDamage(IEnumerable <AxisBlock> axisBlocks, AutoRoad road) { RoadType roadType = road.RoadType; foreach (AxisBlock axisBlock in axisBlocks) { Axis[] axises = axisBlock.Axises; AxisBlockType blockType = axisBlock.BlockType; if (roadType == RoadType.R5Tc) { Array.ForEach(axises, a => a.LoadLimit = 5); Array.ForEach(axises, a => a.Damage = GetAxisDamage(road, a)); continue; } string blockInfo = $"Группа осей ({string.Join(",", axises.Select(a => a.Index + 1))}){Environment.NewLine}"; switch (blockType) { case AxisBlockType.Single: { Axis singleAxis = axises.Single(); singleAxis.LoadLimit = GetLimitForAxisesBlock(roadType, AxisBlockType.Single, singleAxis.IsDouble, singleAxis.IsPnevmo, distanceToNext: 0); singleAxis.Damage = GetAxisDamage(road, singleAxis); break; } case AxisBlockType.Dual: case AxisBlockType.Triple: { bool blockIsDouble = axises.All(a => a.IsDouble); bool blockIsPnevmo = axises.All(a => a.IsPnevmo); float blockWeight = axises.Sum(a => a.WeightValueWithInaccuracy); float maxAxisWeight = axises.Max(a => a.WeightValueWithInaccuracy); float singleAxisLimit = GetLimitForAxisesBlock(road.RoadType, AxisBlockType.Single, blockIsDouble, blockIsPnevmo, distanceToNext: 0); int distanceCount = axises.Length - 1; float averageDistance = axises.Take(distanceCount).Sum(a => a.DistanceToNextWithInaccuracy) / distanceCount; float blockLimit = GetLimitForAxisesBlock(roadType, blockType, blockIsDouble, blockIsPnevmo, averageDistance); if (blockWeight <= blockLimit && maxAxisWeight <= singleAxisLimit) { Array.ForEach(axises, a => a.LoadLimit = 0); Array.ForEach(axises, a => a.Damage = 0); } else { float axisLimit = blockLimit / axises.Length; Array.ForEach(axises, a => a.LoadLimit = axisLimit); Array.ForEach(axises, a => a.Damage = GetAxisDamage(road, a)); } blockInfo += $" - Нагрузка на группу осей (Фактическая/Допустимая): {blockWeight}т./{blockLimit}т.{Environment.NewLine}" + $" - Нагрузка на наиболее нагруженную ось (Фактическая/Допустимая): {maxAxisWeight}т./{singleAxisLimit}т.{Environment.NewLine}"; break; } case AxisBlockType.MoreThree: case AxisBlockType.MultiWheeled: { for (int i = 0; i < axises.Length; i++) { Axis axis = axises[i]; float dist; if (i == 0) { dist = axis.DistanceToNextWithInaccuracy; } else if (i == axises.Length - 1) { dist = axises[i - 1].DistanceToNextWithInaccuracy; } else { dist = Math.Min(axis.DistanceToNextWithInaccuracy, axises[i - 1].DistanceToNextWithInaccuracy); } axis.LoadLimit = GetLimitForAxisesBlock(roadType, blockType, axis.IsDouble, axis.IsPnevmo, dist); axis.Damage = GetAxisDamage(road, axis); } break; } default: throw new NotImplementedException(); } Array.ForEach(axises, a => a.BlockInfo = blockInfo); } }