using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Text; using System.Xml; using System.Xml.Serialization; namespace ShrlAlgoToolkit.RevitAddins.RvIndependent.MetroGauges.LandXMLData { [XmlRoot("LandXML")] [Serializable] public class Model { public Model() { CgPoints = new List(); Roadways = new List(); Surfaces = new List(); SourcePoints = new List(); TargetPoints = new List(); CoordinateSystem = new CoordinateSystem(); Alignments = new Alignments(); Project = new Project(); Units = new Units(); xsi_schemaLocation = "http://www.landxml.org/schema/LandXML-1.2 http://www.landxml.org/schema/LandXML-1.2/LandXML-1.2.xsd"; } private const string defaultNamespace = "http:http://www.landxml.org/schema/LandXML-1.2"; private const string xsiNamespace = "http://www.w3.org/2001/XMLSchema-instance"; public Point3D GeometricCenter { get { var count = Alignments.Count; var point3D = new Point3D(); if (count != 0) { foreach (var alignment in Alignments) { point3D += alignment.GeometricCenter / count; } } return point3D; } } [Obsolete("Property \"GetGeometricCenter\" is deprecated, please use \"GeometricCenter\" instead.")] public Point3D GetGeometricCenter => GeometricCenter; [XmlIgnore] public string Name { get { var text = string.Empty; foreach (var roadway in Roadways) { text = text + roadway.Name + " "; } if (text != string.Empty) { return text.TrimEnd(); } if (Project == null) { return string.Empty; } return Project.Name; } } public IEnumerable PointCodes { get { return Alignments.AlignmentList.SelectMany(item => item.PointCodes); } } public IEnumerable SurfaceNames { get { return Alignments.AlignmentList.SelectMany(item => item.SurfaceNames).Distinct(); } } public GeometryTransformations Transformations { get { var geometryTransformations = new GeometryTransformations(); geometryTransformations.SetTransformations(SourcePoints[0], SourcePoints[1], TargetPoints[0], TargetPoints[1]); if (Transformed) { geometryTransformations.Invert(); } return geometryTransformations; } } [XmlElement("Application")] public Application Application { get; set; } [XmlElement("BasePoint")] public Point3D BasePoint { get; set; } [XmlElement("CgPoints")] public List CgPoints { get; set; } [XmlElement("Alignments")] public Alignments Alignments { get; set; } [XmlAttribute("readOnly")] public bool ReadOnly { get; set; } [XmlAttribute("t")] public bool Transformed { get; set; } [XmlElement("CoordinateSystem")] public CoordinateSystem CoordinateSystem { get; set; } [XmlElement("ProjectOf")] public Project Project { get; set; } [XmlElement("Units")] public Units Units { get; set; } [XmlElement("SourcePoint")] public List SourcePoints { get; set; } [XmlElement("TargetPoint")] public List TargetPoints { get; set; } [XmlArray("Roadways")] public List Roadways { get; set; } [XmlArray("Surfaces")] public List Surfaces { get; set; } [XmlAttribute("language")] public string Language { get; set; } [XmlAttribute("version")] public string Version { get; set; } [XmlAttribute("time")] public string Time { get; set; } [XmlAttribute("date")] public string Date { get; set; } [XmlAttribute("schemaLocation", Namespace = "http://www.w3.org/2001/XMLSchema-instance")] public string xsi_schemaLocation { get; set; } public void ConnectHierarchy() { ConnectRoadways(); foreach (var roadway in Roadways) { roadway.ConnectAlignments(); } foreach (var alignment in Alignments) { alignment.ConnectRegions(); foreach (var region in alignment.Regions) { region.ConnectParts(); foreach (var part in region.Parts) { part.ConnectRange(); } } foreach (var crossSection in alignment.CrossSections) { crossSection.ConnectShapes(); } } } public void ConnectRoadways() { foreach (var roadway in Roadways) { roadway.LandXml = this; } } public static Model Deserialize(string filename) { Model result; try { using (var fileStream = new FileStream(filename, FileMode.Open)) { result = Deserialize(fileStream); } } catch { result = null; } return result; } public static Model Deserialize(Stream stream) { Model model = null; try { var xmlSerializer = new XmlSerializer(typeof(Model), "http://www.landxml.org/schema/LandXML-1.2"); model = xmlSerializer.Deserialize(stream) as Model; model.ConnectHierarchy(); } catch { model = null; } return model; } public static Model DeserializeBinary(string filename) { Model model = null; try { using (var fileStream = new FileStream(filename, FileMode.OpenOrCreate)) { #if NET5_0_OR_GREATER var ser = new DataContractSerializer(typeof(Model)); ser.WriteObject(fileStream, model); #else BinaryFormatter binaryFormatter = new BinaryFormatter(); model = binaryFormatter.Deserialize(fileStream) as Model; model.ConnectHierarchy(); #endif } } catch { } return model; } public void Initialize(string projectName, string fileName, Application app, int units = 0, string version = "1.2") { Language = "English"; ReadOnly = false; Version = version; Date = string.Concat(DateTime.Now.Year, "-", DateTime.Now.Month, "-", DateTime.Now.Day); Time = string.Concat(DateTime.Now.Hour, ":", DateTime.Now.Minute, ":", DateTime.Now.Second); Units.Clear(); switch (units) { case 0: Units.Add(new Imperial()); break; default: Units.Add(new Metric()); break; } Units[0].Initialize(); Project.Name = projectName; Project.File = fileName; Application = app; } public void RefreshShapes() { foreach (var alignment in Alignments.AlignmentList) { alignment.RefreshShapes(); } } public bool Serialize(string filename) { var result = true; try { using (var fileStream = new FileStream(filename, FileMode.Create)) { var xmlSerializer = new XmlSerializer(typeof(Model), "http://www.landxml.org/schema/LandXML-1.2"); xmlSerializer.Serialize(fileStream, this, Namespaces()); } } catch { result = false; } return result; } public bool Serialize(Stream stream) { var result = true; try { using ( var xmlWriter = XmlWriter.Create( stream, new XmlWriterSettings { NewLineHandling = NewLineHandling.Entitize, NewLineChars = Environment.NewLine, Encoding = Encoding.UTF8, Indent = true } ) ) { var xmlSerializer = new XmlSerializer(typeof(Model), "http://www.landxml.org/schema/LandXML-1.2"); xmlSerializer.Serialize(xmlWriter, this, Namespaces()); } } catch { result = false; } return result; } public bool SerializeBinary(string filename) { var result = true; try { using (var fileStream = new FileStream(filename, FileMode.Create)) { #if NET5_0_OR_GREATER var ser = new DataContractSerializer(typeof(Model)); ser.WriteObject(fileStream, this); #else var binaryFormatter = new BinaryFormatter(); binaryFormatter.Serialize(fileStream, this); #endif } } catch { result = false; } return result; } public void SetBasePoint(bool center = true) { var point3D = SourcePoints.Count > 0 ? SourcePoints[0] : null; if (point3D == null) { if (center) { point3D = GeometricCenter; } else if (Alignments.Count > 0) { var alignment = Alignments[0]; if (alignment.CrossSections.Count > 0) { point3D = new Point3D(alignment.CrossSections[0]); } } } if (point3D != null && point3D != new Point3D()) { BasePoint = point3D; foreach (var alignment2 in Alignments) { foreach (var interval in alignment2.CoordGeom) { foreach (var textPoint2D in interval._points) { textPoint2D.setText(textPoint2D.Y - point3D.Y, textPoint2D.X - point3D.X); textPoint2D.X -= point3D.X; textPoint2D.Y -= point3D.Y; textPoint2D.Z -= point3D.Z; } } foreach (var crossSection in alignment2.CrossSections) { crossSection.X -= point3D.X; crossSection.Y -= point3D.Y; crossSection.Z -= point3D.Z; foreach (var designShape in crossSection.DesignShapes) { foreach (var crossSectionPoint in designShape.CrossSectionPoints) { crossSectionPoint.X -= point3D.X; crossSectionPoint.Y -= point3D.Y; crossSectionPoint.Z -= point3D.Z; } } } foreach (var profAlign in alignment2.Profile) { foreach (var textPoint2D2 in profAlign.PVIs) { textPoint2D2.X -= point3D.X; textPoint2D2.Y -= point3D.Y; textPoint2D2.Z -= point3D.Z; } } } } } public override string ToString() { return Name; } [Obsolete("Method \"Transform\" is deprecated, please use \"TransformByReferencePoints\" instead.")] public int Transform() { return TransformByReferencePoints(); } public void Transform(GeometryTransformations transformations) { foreach (var alignment in Alignments) { alignment.Transform(transformations); } foreach (var roadway in Roadways) { roadway.StationStart *= transformations.ScaleFactor; roadway.StationEnd *= transformations.ScaleFactor; } if (BasePoint != null) { transformations.Transform(BasePoint); } } public int TransformByReferencePoints() { var result = 0; try { if (SourcePoints != null && TargetPoints != null && SourcePoints.Count >= 2 && TargetPoints.Count >= 2) { var transformations = Transformations; Transform(transformations); Transformed = !Transformed; result = Transformed ? 1 : -1; } } catch { result = 2; } return result; } private static XmlSerializerNamespaces Namespaces() { var xmlSerializerNamespaces = new XmlSerializerNamespaces(); xmlSerializerNamespaces.Add("xsi", "http://www.w3.org/2001/XMLSchema-instance"); return xmlSerializerNamespaces; } } }