Files
ShrlAlgoToolkit/ShrlAlgoToolkit.RevitAddins/RvIndependent/MetroGauges/LandXMLData/Alignment.cs
2025-04-24 20:56:44 +08:00

557 lines
17 KiB
C#

using System.Xml.Serialization;
namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges.LandXMLData;
[XmlType("Alignment")]
[Serializable]
public class Alignment : ComparableStructure<Alignment>
{
public Alignment()
{
Init();
}
public Alignment(Alignment alignment)
{
if (alignment != null)
{
Id = alignment.Id;
Description = alignment.Description;
Name = alignment.Name;
StationStart = alignment.StationStart;
StationEnd = alignment.StationEnd;
Length = alignment.Length;
CoordGeom = alignment.CoordGeom;
Regions = alignment.Regions;
FeatureLines = alignment.FeatureLines;
CrossSections = alignment.CrossSections;
Profile = alignment.Profile;
SuperElevations = alignment.SuperElevations;
Structres = alignment.Structres;
Import = alignment.Import;
geometricCenter = alignment.geometricCenter;
return;
}
Init();
}
private string description;
private Point3D geometricCenter;
private string id;
private string name;
[XmlIgnore]
public Point3D GeometricCenter
{
get
{
if (geometricCenter == null)
{
SetGeometricCenter();
}
return geometricCenter;
}
set => geometricCenter = null;
}
[Obsolete("Property \"GetGeometricCenter\" is deprecated, please use \"GeometricCenter\" instead.")]
[XmlIgnore]
public Point3D GetGeometricCenter => GeometricCenter;
[XmlIgnore]
public ProfAlign GroundProfile => Profile.ProfileCurve.Find(item => item.Type == 0) ?? Profile.ProfileCurve.FirstOrDefault();
[XmlIgnore]
public IEnumerable<string> PointCodes => CrossSections.SelectMany(item => item.PointCodes);
[XmlIgnore]
public IEnumerable<string> SurfaceNames => CrossSections.SelectMany(item => item.SurfaceNames);
[XmlIgnore]
public ProfAlign WayProfile
{
get
{
ProfAlign result;
if ((result = Profile.ProfileCurve.Find(item => item.Type == 1)) == null)
{
result = Profile.ProfileCurve.Find(item => item.Type == 2) ?? Profile.ProfileCurve.FirstOrDefault();
}
return result;
}
}
[XmlAttribute("desc")]
public string Description
{
get => description;
set => description = value;
}
[XmlAttribute("AlignmentID")]
public string Id
{
get => id;
set => id = value;
}
[XmlAttribute("name")]
public string Name
{
get => name;
set => name = value;
}
[XmlIgnore]
internal string AlignmentId => (Roadway != null ? Roadway.CorridorID : string.Empty) + Id;
[XmlAttribute("import")]
public bool Import { get; set; }
[XmlElement("CoordGeom")]
public CoordGeom CoordGeom { get; set; }
[XmlAttribute("staStart")]
public double StationStart { get; set; }
[XmlAttribute("staEnd")]
public double StationEnd { get; set; }
[XmlAttribute("length")]
public double Length { get; set; }
[XmlArray("CrossSects")]
public List<CrossSection> CrossSections { get; set; }
[XmlArray("FeatureLines")]
public List<FeatureLine> FeatureLines { get; set; }
[XmlArray("Regions")]
public List<Region> Regions { get; set; }
[XmlArray("Structures")]
public List<Structures> Structres { get; set; }
[XmlElement("Profile")]
public Profile Profile { get; set; }
[XmlElement("Superelevation")]
public List<SuperElevation> SuperElevations { get; set; }
[XmlIgnore]
public Roadway Roadway { get; set; }
public void AddRegion(Region region)
{
Regions.Add(region);
region.Alignment = this;
}
public void ConnectRegions()
{
foreach (var region in Regions)
{
region.Alignment = this;
}
}
public void ConnectSectionsShape(DesignShape linkShape, DesignShape refShape, CrossSection section, CrossSection refSection = null)
{
var num = 0;
linkShape.CrossSectionPoints.Clear();
var array = (from ds in section.DesignShapes where ds.Name == refShape.Name && ds.Side == refShape.Side select ds)
.SelectMany(ds => ds.CrossSectionPoints)
.ToArray();
var list = !(refSection != null)
? new List<CrossSectionPoint>()
: (from ds in refSection.DesignShapes where ds.Name == refShape.Name && ds.Side == refShape.Side select ds)
.SelectMany(ds => ds.CrossSectionPoints)
.ToList();
var list2 = list;
using (var enumerator = refShape.CrossSectionPoints.GetEnumerator())
{
while (enumerator.MoveNext())
{
var point = enumerator.Current;
var crossSectionPoint = array.FirstOrDefault(p => p.Code == point?.Code);
if (crossSectionPoint != null)
{
linkShape.CrossSectionPoints.Add(new CrossSectionPoint(crossSectionPoint));
}
else
{
var num2 = list2.IndexOf(point);
if (num2 >= 0)
{
num = num2;
}
CrossSectionPoint crossSectionPoint2 = new(num < array.Length ? array[num] : array.Last()) { Code = point?.Code };
linkShape.CrossSectionPoints.Add(crossSectionPoint2);
}
num++;
}
}
linkShape.UpdatePointDependentData();
section.DesignShapes.Add(linkShape);
}
public override bool DifferentDescendants(Alignment alignment)
{
if (Regions.Count == alignment.Regions.Count)
{
for (var i = 0; i < Regions.Count; i++)
{
if (!Regions[i].Equals(alignment.Regions[i]))
{
return true;
}
}
return false;
}
return true;
}
public override bool DifferentItem(Alignment alignment)
{
return StationStart != alignment.StationStart || StationEnd != alignment.StationEnd || GeometricCenter != alignment.GeometricCenter;
}
public Region FindRegion(Region reference)
{
return Regions.FirstOrDefault(item => item.Name == reference.Name);
}
public Point3D GeometricCenterInRange(double startStation, double endStation)
{
var array = (from item in CrossSections where item.Station >= startStation && item.Station <= endStation select item).ToArray();
return CalcGeometricCenter(array, array.Length);
}
public double GetAzimuthAtStation(double station)
{
var num = 0.0;
var num2 = 0.0;
foreach (var interval in CoordGeom.HorizonCurve)
{
if (num + interval.Length >= station)
{
num2 += interval.GetDirectionAtPoint(station - num);
break;
}
num2 += interval.GetDirectionAtPoint(interval.Length);
num += interval.Length;
}
return num2;
}
//直线
public double GetHeightAtStation(double station)
{
var result = 0.0;
var profAlign = Profile.ProfileCurve.FirstOrDefault(item => item.Type == 2);
if (profAlign != null)
{
var num = profAlign.PVIs.Count - 1;
var i = 0;
while (i < num)
{
if (profAlign.PVIs[i].First >= station)
{
if (profAlign.PVIs[i] is not ParaCurve && profAlign.PVIs[i + 1] is not ParaCurve)
{
result =
profAlign.PVIs[i].Second
+ (
(station - profAlign.PVIs[i].First)
* (profAlign.PVIs[i + 1].Second - profAlign.PVIs[i].Second)
/ (profAlign.PVIs[i + 1].First - profAlign.PVIs[i].First)
);
}
break;
}
i++;
}
}
return result;
}
public IEnumerable<string> GetPointCodes(Side side, int region = -1)
{
return region >= 0
? side != Side.Both
? (from item in CrossSections where item.Region == region select item).SelectMany(item => item.GetPointCodes(side)).Distinct()
: (from item in CrossSections where item.Region == region select item).SelectMany(item => item.PointCodes).Distinct()
: side != Side.Both
? CrossSections.SelectMany(item => item.GetPointCodes(side)).Distinct()
: PointCodes.Distinct();
}
public void Initialize(string n, double s, double e, double l, string id, string d)
{
Name = n;
StationStart = s;
StationEnd = e;
Length = l;
Id = id;
Description = d;
}
public void RefreshShapes() { }
public void RemoveRegion(Region region)
{
if (Regions.Remove(region))
{
region.Alignment = null;
}
}
public void RemoveSameSections()
{
for (var i = CrossSections.Count - 1; i > 0; i--)
{
if (CrossSections[i - 1].Station == CrossSections[i].Station)
{
CrossSections.RemoveAt(i);
}
}
GeometricCenter = null;
}
public void ResetImportsAndParts()
{
try
{
Import = true;
foreach (var crossSection in CrossSections)
{
crossSection.Import = true;
foreach (var designShape in crossSection.DesignShapes)
{
designShape.Import = true;
designShape.Part = 0;
}
for (var i = crossSection.DesignShapes.Count - 1; i >= 0; i--)
{
var shape = crossSection.DesignShapes[i];
if (crossSection.DesignShapes.Count(ds => ds.NameSide == shape.NameSide) > 1)
{
if (shape.CrossSectionPoints.Count < crossSection.DesignShapes.Max(ds => ds.CrossSectionPoints.Count))
{
crossSection.DesignShapes.RemoveAt(i);
}
}
}
}
}
catch
{
// ignored
}
}
public void SplitDifferentParts()
{
try
{
var crossSection = CrossSections.Count > 0 ? CrossSections[0] : null;
for (var i = 1; i < CrossSections.Count; i++)
{
var crossSection2 = CrossSections[i];
if (crossSection2.Import)
{
var count = crossSection2.DesignShapes.Count;
for (var j = 0; j < count; j++)
{
var shape = crossSection2.DesignShapes[j];
var pointCodesFlat = shape.PointCodesFlat;
var designShape = crossSection.DesignShapes.FirstOrDefault(ds => ds.NameSideSegment == shape.NameSideSegment);
var flag4 = !crossSection.Import;
var flag5 =
designShape != null && designShape.PointCodesFlat != pointCodesFlat && crossSection2.Station != crossSection.Station;
if (designShape == null || !designShape.Import || flag5 || crossSection2.Region != crossSection.Region)
{
flag4 = shape.Import;
if (flag5)
{
if (shape.Import && crossSection.DesignShapes.Count < crossSection2.DesignShapes.Count)
{
ConnectSectionsShape(new DesignShape(designShape) { Import = false }, designShape, crossSection2, crossSection);
}
else if (designShape.Import)
{
DesignShape designShape2 = new(shape) { Import = true };
ConnectSectionsShape(designShape2, shape, crossSection, crossSection2);
AddRange(crossSection2, shape, i);
designShape2.Part = i;
}
}
}
if (!crossSection.Import)
{
AddRange(crossSection2, shape, i);
for (var k = i + 1; k < CrossSections.Count; k++)
{
var designShape3 = CrossSections[k].DesignShapes.FirstOrDefault(ds => ds.NameSideSegment == shape.NameSideSegment);
if (designShape3 != null)
{
designShape3.Part = i;
}
}
shape.Part = i;
}
}
}
crossSection = crossSection2;
}
}
catch
{
// ignored
}
}
public void Transform(GeometryTransformations transformations)
{
foreach (var interval in CoordGeom.HorizonCurve)
{
interval.Transform(transformations);
}
StationStart *= transformations.ScaleFactor;
StationEnd *= transformations.ScaleFactor;
foreach (var region in Regions)
{
region.StartStation *= transformations.ScaleFactor;
region.EndStation *= transformations.ScaleFactor;
}
foreach (var crossSection in CrossSections)
{
crossSection.Transform(transformations);
}
foreach (var profAlign in Profile.ProfileCurve)
{
profAlign.Transform(transformations);
}
GeometricCenter = null;
}
public void TransformByScale(double scale)
{
var point3D = GeometricCenter;
var flag = point3D.LengthSquared3D != 0.0;
GeometryTransformations geometryTransformations = new();
if (flag)
{
geometryTransformations.Translation(-point3D.X, -point3D.Y, -point3D.Z);
}
geometryTransformations.Scale(scale);
point3D *= scale;
if (flag)
{
geometryTransformations.Translation(point3D.X, point3D.Y, point3D.Z);
}
Transform(geometryTransformations);
}
protected void AddRange(Part part, double start, double end, int i)
{
Range range = new() { Part = i };
range.SetRange(start, end);
part.AddRange(range);
}
protected Point3D CalcGeometricCenter(IEnumerable<CrossSection> sections, int count)
{
Point3D point3D = new();
if (count != 0)
{
foreach (var p in sections)
{
point3D += p / count;
}
}
return point3D;
}
protected void SetGeometricCenter()
{
if (CrossSections != null)
{
geometricCenter = CalcGeometricCenter(CrossSections, CrossSections.Count);
return;
}
geometricCenter = new Point3D();
}
internal void AddRange(CrossSection section, DesignShape shape, int i)
{
var region = Regions.FirstOrDefault(item => item.Id == section.Region);
if (region != null)
{
var part = region.Parts.FirstOrDefault(item => item.NameSideSegment == shape.NameSideSegment);
var endStation = part.Ranges.Last().EndStation;
if (section.Station > endStation)
{
AddRange(part, endStation, section.Station, i);
return;
}
if (section.Station != endStation)
{
var startStation = part.Ranges.First().StartStation;
if (section.Station < startStation)
{
AddRange(part, section.Station, startStation, i);
return;
}
if (section.Station != startStation)
{
part.Ranges.Last().EndStation = section.Station;
AddRange(part, section.Station, endStation, i);
}
}
}
}
private void Init()
{
CrossSections = new List<CrossSection>();
FeatureLines = new List<FeatureLine>();
Regions = new List<Region>();
SuperElevations = new List<SuperElevation>();
CoordGeom = new CoordGeom();
Profile = new Profile();
geometricCenter = null;
Import = true;
}
}