添加项目文件。
This commit is contained in:
556
RevitKits/MetroGauges/LandXMLData/Alignment.cs
Normal file
556
RevitKits/MetroGauges/LandXMLData/Alignment.cs
Normal file
@@ -0,0 +1,556 @@
|
||||
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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user