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);
        }
Пример #13
0
        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;
            }
        }
Пример #16
0
        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);
            }
        }
Пример #17
0
 public static IColorCalculator CreateDepthGradient(VisualTopoModel model) => new ColorFromDepthCalculation(model);
Пример #18
0
 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));
 }