private void Build3DTopology(VisualTopoModel model, float zFactor) { List <List <GeoPointRays> > branches = new List <List <GeoPointRays> >(); GraphTraversal_Lines(model.Graph.Root, branches, null, Vector3.Zero, 0, zFactor); model.Topology3D = branches; }
public void Create3DTriangulation(VisualTopoModel model) { // ======================== // 3D model Build3DTopology_Triangulation(model, ColorStrategy.CreateFromModel); //Build3DTopology_Triangulation(model, ColorStrategy.CreateDepthGradient(model)); }
private void CreateGraph(VisualTopoModel model) { Dictionary <string, Node <VisualTopoData> > nodesByName = new Dictionary <string, Node <VisualTopoData> >(); foreach (var data in model.Sets.SelectMany(s => s.Data)) { if (data.Entree == model.Entree && model.Graph.Root == null) // Warning! Entrance may not be the start node { data.IsRoot = true; var node = model.Graph.CreateRoot(data, data.Entree); nodesByName[node.Key] = node; } if (data.Entree != data.Sortie) { var node = model.Graph.CreateNode(data, data.Sortie); if (!nodesByName.ContainsKey(data.Entree)) { // Début graphe disjoint _logger.LogWarning($"Disconnected node {data.Entree} found"); node.Model.IsDisconnected = true; nodesByName[data.Entree] = node; } nodesByName[data.Entree].AddArc(node, data.Longueur); nodesByName[node.Key] = node; } } }
private VisualTopoModel ParseHeader(VisualTopoModel model, StreamReader sr) { sr.ReadUntil(string.IsNullOrWhiteSpace); var headerLines = sr.ReadUntil(string.IsNullOrWhiteSpace) .Where(s => !string.IsNullOrWhiteSpace(s)) .Select(s => s.Split(new[] { ' ' }, 2, StringSplitOptions.RemoveEmptyEntries)) .ToDictionary(s => s[0], s => s[1]); if (headerLines.TryGetValue("Trou", out string trou)) { ParseEntryHeader(model, trou); } if (headerLines.TryGetValue("Club", out string club)) { model.Author = club; } if (headerLines.TryGetValue("Entree", out string entree)) { model.Entree = entree; } if (headerLines.TryGetValue("Toporobot", out string toporobot)) { model.TopoRobot = toporobot == "1"; } if (headerLines.TryGetValue("Couleur", out string couleur)) { model.DefaultColor = ParseColor(couleur); } return(model); }
// Useful to debug : output graph as node names public List <List <string> > GetBranchesNodeNames(VisualTopoModel model) { List <List <string> > branches = new List <List <string> >(); GetBranches(model.Graph.Root, branches, null, n => n.Sortie); return(branches); }
private VisualTopoModel PreAnalyzeFile(VisualTopoModel model, float zFactor = 1f) { // ======================== // Graph CreateGraph(model); // ======================== // 3D model - do not remove Build3DTopology(model, zFactor); return(model); }
private void ParseEntryHeader(VisualTopoModel model, string entry) { var data = entry.Split(','); model.Name = data[0]; model.EntryPointProjectionCode = data[4]; model.EntryPoint = convers3Reprojection.CreateGeoPoint(inputProjectionCode: model.EntryPointProjectionCode, outputSrid: ModelDefaultSRID , x: double.Parse(data[1], CultureInfo.InvariantCulture) , y: double.Parse(data[2], CultureInfo.InvariantCulture) , z: double.Parse(data[3], CultureInfo.InvariantCulture)); model.SRID = ModelDefaultSRID; }
private void Build3DTopology_Triangulation(VisualTopoModel model, IColorCalculator colorFunc) { // Build color function float minElevation = model.Graph.AllNodes.Min(n => n.Model.VectorLocal.Z); // Generate triangulation // TriangulationList <Vector3> markersTriangulation = new TriangulationList <Vector3>(); TriangulationList <Vector3> triangulation = GraphTraversal_Triangulation(model, null, ref markersTriangulation, model.Graph.Root, colorFunc); model.TriangulationFull3D = triangulation + markersTriangulation; }
private VisualTopoModel ParseFile(string vtopoFile, Encoding encoding, bool decimalDegrees, bool ignoreRadialBeams) { VisualTopoModel model = null; // ======================== // Parsing using (StreamReader sr = new StreamReader(vtopoFile, encoding)) { model = ParseFile(sr, decimalDegrees, ignoreRadialBeams); } return(model); }
private VisualTopoModel ParseSet(VisualTopoModel model, StreamReader sr, bool decimalDegrees, bool ignoreRadialBeams) { VisualTopoSet set = new VisualTopoSet(); string setHeader = sr.ReadLine(); if (setHeader.StartsWith("[Configuration ")) { sr.ReadToEnd(); // skip until end of stream return(model); } // Set header var data = setHeader.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries); var headerSlots = data[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); set.Color = this.ParseColor(headerSlots); set.Name = data.Length > 1 ? data[1].Trim() : string.Empty; sr.Skip(1); var dataLine = sr.ReadLine(); do { VisualTopoData topoData = new VisualTopoData(); var parts = dataLine.Split(';'); if (parts.Length > 1) { topoData.Comment = parts[1].Trim(); } var slots = parts[0].Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); //Debug.Assert(slots.Length == 13); // Parse data line topoData = this.ParseData(topoData, slots, decimalDegrees, ignoreRadialBeams); if (topoData != null) { set.Add(topoData); } dataLine = sr.ReadLine(); }while (!string.IsNullOrWhiteSpace(dataLine)); model.Sets.Add(set); return(model); }
// Elevations public void ComputeCavityElevations(VisualTopoModel model, DEMDataSet dataset, float zFactor = 1) { var entryPoint4326 = model.EntryPoint.ReprojectTo(model.SRID, dataset.SRID); model.EntryPoint.Elevation = zFactor * _elevationService.GetPointElevation(entryPoint4326, dataset).Elevation ?? 0; foreach (var set in model.Sets.Where(s => s.Data.First().GeoPointLocal != null)) { VisualTopoData setStartData = set.Data.First(d => d.GeoPointLocal != null); GeoPoint dataPoint = setStartData.GeoPointLocal.Clone(); dataPoint.Longitude += model.EntryPoint.Longitude; dataPoint.Latitude += model.EntryPoint.Latitude; var setStartPointDem = dataPoint.ReprojectTo(model.SRID, dataset.SRID); setStartData.TerrainElevationAbove = zFactor * _elevationService.GetPointElevation(setStartPointDem, dataset).Elevation ?? 0; } }
private VisualTopoModel ParseFile(StreamReader vtopoFileReader, bool decimalDegrees, bool ignoreRadialBeams) { VisualTopoModel model = new VisualTopoModel(); // ======================== // Parsing model = this.ParseHeader(model, vtopoFileReader); while (!vtopoFileReader.EndOfStream) { model = this.ParseSet(model, vtopoFileReader, decimalDegrees, ignoreRadialBeams); } return(model); }
public static MemoryStream ExportToCsv(this VisualTopoModel model, string separator) { MemoryStream ms = new MemoryStream(); using (StreamWriter sw = new StreamWriter(ms)) { sw.WriteLine(string.Join(separator, headers)); foreach (var set in model.Sets) { sw.WriteLine(string.Join(separator, GetSectionHeader(set))); foreach (var data in set.Data) { sw.WriteLine(string.Join(separator, data.Entree, data.Sortie, data.Longueur, data.Cap, data.Pente, data.CutSection.left, data.CutSection.right, data.CutSection.up, data.CutSection.down, data.VectorLocal.X, data.VectorLocal.Y, data.VectorLocal.Z, // Latitude, Long, X,Y data.GeoPointGlobal_DEMProjection?.Latitude, data.GeoPointGlobal_DEMProjection?.Longitude, data.GeoPointGlobal_ProjectedCoords?.Longitude, data.GeoPointGlobal_ProjectedCoords?.Latitude, data.DistanceFromEntry, data.VectorLocal.Z, data.TerrainElevationAbove, data.TerrainElevationAbove - (model.EntryPoint.Elevation ?? 0) - data.VectorLocal.Z, // comment row (red for disconnected node) data.IsDisconnected ? string.Concat("[DISCONNECTED] ", data.Comment) : data.Comment)); } } } return(ms); }
private TriangulationList <Vector3> GraphTraversal_Triangulation(VisualTopoModel visualTopoModel, TriangulationList <Vector3> triangulation, ref TriangulationList <Vector3> markersTriangulation, Node <VisualTopoData> node, IColorCalculator colorFunc) { triangulation = triangulation ?? new TriangulationList <Vector3>(); var model = node.Model; if (model.IsSectionStart && triangulation.NumPositions > 0) { // Cylinder height = point depth + (terrain height above - entry Z) float cylinderHeight = -model.VectorLocal.Z + (float)(model.TerrainElevationAbove - visualTopoModel.EntryPoint.Elevation.Value); markersTriangulation += _meshService.CreateCylinder(model.VectorLocal, 0.2f, cylinderHeight, model.Set.Color); //var surfacePos = new Vector3(model.GlobalVector.X, model.GlobalVector.Y, (float)model.TerrainElevationAbove); float coneHeight = 10; markersTriangulation += _meshService.CreateCone(model.VectorLocal, 5, coneHeight, model.Set.Color) //.Translate(Vector3.UnitZ * -coneHeight / 2F) .Transform(Matrix4x4.CreateRotationY((float)Math.PI, new Vector3(model.VectorLocal.X, model.VectorLocal.Y, model.VectorLocal.Z + coneHeight / 2f))) //.Translate(Vector3.UnitZ * coneHeight / 2F) .Translate(Vector3.UnitZ * cylinderHeight); } if (node.Arcs.Count == 0) // leaf { Debug.Assert(triangulation.NumPositions > 0, "Triangulation should not be empty"); // Make a rectangle perpendicual to direction centered on point(should be centered at human eye(y = 2m) triangulation = AddCorridorRectangleSection(triangulation, model, null, triangulation.NumPositions - 4, colorFunc); } else { int posIndex = triangulation.NumPositions - 4; foreach (var arc in node.Arcs) { // Make a rectangle perpendicual to direction centered on point(should be centered at human eye(y = 2m) triangulation = AddCorridorRectangleSection(triangulation, model, arc.Child.Model, posIndex, colorFunc); posIndex = triangulation.NumPositions - 4; triangulation = GraphTraversal_Triangulation(visualTopoModel, triangulation, ref markersTriangulation, arc.Child, colorFunc); } } return(triangulation); }
public void ComputeFullCavityElevations(VisualTopoModel model, DEMDataSet dataset, float zFactor = 1) { var entryPoint4326 = model.EntryPoint.ReprojectTo(model.SRID, dataset.SRID); model.EntryPoint.Elevation = zFactor * _elevationService.GetPointElevation(entryPoint4326, dataset).Elevation ?? 0; foreach (var data in model.Graph.AllNodes.Where(n => n.Model.GeoPointLocal != null).Select(n => n.Model)) { GeoPoint dataPoint = data.GeoPointLocal.Clone(); dataPoint.Longitude += model.EntryPoint.Longitude; dataPoint.Latitude += model.EntryPoint.Latitude; var dataPointDem = dataPoint.ReprojectTo(model.SRID, dataset.SRID); data.GeoPointGlobal_ProjectedCoords = dataPoint; data.GeoPointGlobal_DEMProjection = dataPointDem; data.TerrainElevationAbove = zFactor * _elevationService.GetPointElevation(dataPointDem, dataset).Elevation ?? 0; data.Depth = data.TerrainElevationAbove - model.EntryPoint.Elevation.Value - data.VectorLocal.Z; } }
public static MemoryStream ExportToExcel(this VisualTopoModel model, bool autoFitColumns = true) { using (var wb = new XLWorkbook(XLEventTracking.Disabled)) { var ws = wb.Worksheets.Add($"Cavité entrée Z={model.EntryPoint.Elevation:N1} m"); int ro = 1; int co = 0; foreach (string header in headers) { ws.Cell(ro, ++co).Value = header; } var row = ws.Row(ro); row.Style.Fill.BackgroundColor = XLColor.GreenYellow; row.Style.Font.Bold = true; foreach (var set in model.Sets) { ro++; co = 0; foreach (string header in GetSectionHeader(set)) { ws.Cell(ro, ++co).Value = header; } var setRow = ws.Row(ro); setRow.Style.Fill.BackgroundColor = XLColor.GreenYellow; setRow.Style.Font.Bold = true; foreach (var data in set.Data) { ro++; co = 0; ws.Cell(ro, ++co).Value = string.Concat("'", data.Entree); ws.Cell(ro, ++co).Value = string.Concat("'", data.Sortie); ws.Cell(ro, ++co).Value = data.Longueur; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.Cap; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.Pente; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.CutSection.left; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.CutSection.right; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.CutSection.up; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.CutSection.down; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.VectorLocal.X; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.VectorLocal.Y; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.VectorLocal.Z; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; // Latitude, Long, X,Y ws.Cell(ro, ++co).Value = data.GeoPointGlobal_DEMProjection?.Latitude; // ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.GeoPointGlobal_DEMProjection?.Longitude; //ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.GeoPointGlobal_ProjectedCoords?.Longitude; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.GeoPointGlobal_ProjectedCoords?.Latitude; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.DistanceFromEntry; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.VectorLocal.Z; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; ws.Cell(ro, ++co).Value = data.TerrainElevationAbove; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; var formula = string.Format(CultureInfo.InvariantCulture, "=RC[-1]-{0:N2}-RC[-2]", model.EntryPoint.Elevation ?? 0); ws.Cell(ro, ++co).FormulaR1C1 = formula; ws.Cell(ro, co).Style.NumberFormat.NumberFormatId = 2; // comment row (red for disconnected node) if (data.IsDisconnected) { var disconnectedRow = ws.Row(ro); setRow.Style.Fill.BackgroundColor = XLColor.Red; disconnectedRow.Style.Fill.BackgroundColor = XLColor.Red; ws.Cell(ro, ++co).Value = string.Concat("[DISCONNECTED] ", data.Comment); } else { ws.Cell(ro, ++co).Value = data.Comment; } } } if (autoFitColumns) { ws.Columns().AdjustToContents(); } wb.CalculateMode = XLCalculateMode.Auto; MemoryStream ms = new MemoryStream(); wb.SaveAs(ms, validate: true, evaluateFormulae: true); ms.Seek(0, SeekOrigin.Begin); return(ms); } }
public static IColorCalculator CreateDepthGradient(VisualTopoModel model) => new ColorFromDepthCalculation(model);
public ColorFromDepthCalculation(VisualTopoModel model) { _maxDepth = model.Graph.AllNodes.Min(n => n.Model.VectorLocal.Z); _colorConverter = new ColorSpaceConverter(); }
public MemoryStream ExportToCsv(VisualTopoModel model, string separator) { return(model.ExportToCsv(separator)); }
public MemoryStream ExportToExcel(VisualTopoModel model, bool autoFitColumns = true) { return(model.ExportToExcel(autoFitColumns)); }