public void ExportVisualTopoToExcel(VisualTopoModel model, string outputExcelFileName) { using (MemoryStream ms = visualTopoService.ExportToExcel(model, autoFitColumns: false)) { File.WriteAllBytes(outputExcelFileName, ms.ToArray()); } }
/// <summary> /// Generate an excel output of all nodes with /// - their computed coordinates relative to entry /// - their distance from entry /// - their distance from the ground surface above them /// </summary> /// <param name="visualTopoFile"></param> /// <param name="dataSet"></param> private void Run_ExcelExport(string visualTopoFile, DEMDataSet dataSet) { try { StopwatchLog timeLog = StopwatchLog.StartNew(_logger); //======================= // Generation params // string outputDir = Directory.GetCurrentDirectory(); VisualTopoModel model = _visualTopoService.LoadFile(visualTopoFile, Encoding.GetEncoding("ISO-8859-1") , decimalDegrees: true , ignoreRadialBeams: true); // for debug, //var b = GetBranches(model); // graph list of all nodes //var lowestPoint = model.Sets.Min(s => s.Data.Min(d => d.GlobalGeoPoint?.Elevation ?? 0)); BoundingBox bbox = model.BoundingBox // relative coords .Translate(model.EntryPoint.Longitude, model.EntryPoint.Latitude, model.EntryPoint.Elevation ?? 0) // absolute coords .Pad(50) // margin around model .ReprojectTo(model.SRID, dataSet.SRID); _elevationService.DownloadMissingFiles(dataSet, bbox); timeLog.LogTime("Terrain height map"); //======================= // Get entry elevation (need to reproject to DEM coordinate system first) // and sections entry elevations // _visualTopoService.ComputeFullCavityElevations(model, dataSet); // will add TerrainElevationAbove and entry elevations // CSV string csvFileName = Path.GetFileName(Path.ChangeExtension(visualTopoFile, ".csv")); File.WriteAllBytes(csvFileName, _visualTopoService.ExportToCsv(model, "\t").ToArray()); // Excel string xlsFileName = Path.GetFileName(Path.ChangeExtension(visualTopoFile, ".xlsx")); using (MemoryStream ms = _visualTopoService.ExportToExcel(model, autoFitColumns: false)) { File.WriteAllBytes(xlsFileName, ms.ToArray()); } timeLog.LogTime("Cavity points elevation"); timeLog.LogTime("3D model"); } catch (Exception ex) { _logger.LogError("Error :" + ex.Message); } }
public async Task UpdateModelAsync(VisualTopoModel model, Guid id) { await DeleteModelAsync(id); await memoryCache.GetOrCreateAsync(GetKey(id), entry => { entry.SetSlidingExpiration(TimeSpan.FromMinutes(options.MemoryCacheDurationMinutes)); return(Task.FromResult(model)); }); }
public async Task <Guid> AddModelAsync(VisualTopoModel model) { Guid id = Guid.NewGuid(); await memoryCache.GetOrCreateAsync(GetKey(id), entry => { entry.SetSlidingExpiration(TimeSpan.FromMinutes(options.MemoryCacheDurationMinutes)); return(Task.FromResult(model)); }); return(id); }
private void btnExport3D_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; try { lblStatus.Text = "Traitement en cours..."; btnExport3D.Enabled = false; Application.DoEvents(); VisualTopoModel visualTopoModel = demNetService.CreateVisualTopoModelFromFile(visualTopoFile, dataSet, (float)numZFactor.Value); string outputFile = Path.GetFullPath($"{visualTopoModel.Name}_{DateTime.Now:yyyy MM dd - HH mm ss}.glb"); demNetService.ExportVisualTopoToGLB(visualTopoModel, dataSet, outputFile , imageryProvider: cmbImagery.SelectedValue as ImageryProvider , drawOnTexture: chkDrawOnTexture.Checked , marginMeters: (float)numMarginAroundModel.Value , zFactor: (float)numZFactor.Value); StringBuilder sb = new StringBuilder(); sb.AppendLine($"{visualTopoModel.Name} - Auteur: {visualTopoModel.Author}"); sb.AppendLine($"Projection {visualTopoModel.EntryPointProjectionCode}"); sb.AppendLine($"{visualTopoModel.Sets.Count} section(s), {visualTopoModel.Sets.Sum(s => s.Data.Count)} lignes"); sb.AppendLine($"Profondeur max : {visualTopoModel.Graph.AllNodes.Max(n => n.Model.Depth):N2} m"); sb.AppendLine($"Distance max : {visualTopoModel.Graph.AllNodes.Max(n => n.Model.DistanceFromEntry):N2} m"); sb.AppendLine($"Fichier 3D exporté vers {outputFile}"); _glbFile = outputFile; txtReport.Text = sb.ToString(); lblStatus.Text = "Fichier exporté avec succès !"; } catch (Exception ex) { _glbFile = null; lblStatus.Text = $"Erreur : {ex.Message}"; } finally { this.Cursor = Cursors.Default; btnExport3D.Enabled = true; } }
public VisualTopoModel CreateVisualTopoModelFromFile(string visualTopoFileName, DEMDataSet dataSet, float zFactor) { VisualTopoModel model = this.visualTopoService.LoadFile(visualTopoFileName, Encoding.GetEncoding("ISO-8859-1") , decimalDegrees: true , ignoreRadialBeams: true , zFactor); BoundingBox bbox = model.BoundingBox // relative coords .Translate(model.EntryPoint.Longitude, model.EntryPoint.Latitude, model.EntryPoint.Elevation ?? 0) // absolute coords .Pad(50) // margin around model .ReprojectTo(model.SRID, dataSet.SRID); this.elevationService.DownloadMissingFiles(dataSet, bbox); this.visualTopoService.ComputeFullCavityElevations(model, dataSet, zFactor); // will add TerrainElevationAbove and entry elevations this.visualTopoService.Create3DTriangulation(model); return(model); }
private void btnExport_Click(object sender, EventArgs e) { this.Cursor = Cursors.WaitCursor; try { lblStatus.Text = "Traitement en cours..."; btnExport.Enabled = false; Application.DoEvents(); VisualTopoModel visualTopoModel = demNetService.CreateVisualTopoModelFromFile(visualTopoFile, dataSet, (float)numZFactor.Value); string outputFile = Path.GetFullPath(visualTopoModel + ".xlsx"); demNetService.ExportVisualTopoToExcel(visualTopoModel, outputFile); StringBuilder sb = new StringBuilder(); sb.AppendLine($"{visualTopoModel.Name} - Auteur: {visualTopoModel.Author}"); sb.AppendLine($"{visualTopoModel.Sets.Count} section(s), {visualTopoModel.Sets.Sum(s => s.Data.Count)} lignes"); sb.AppendLine($"Profondeur max : {visualTopoModel.Graph.AllNodes.Max(n => n.Model.Depth):N2} m"); sb.AppendLine($"Distance max : {visualTopoModel.Graph.AllNodes.Max(n => n.Model.DistanceFromEntry):N2} m"); sb.AppendLine($"Fichier excel exporté vers {outputFile}"); _excelFile = outputFile; txtReport.Text = sb.ToString(); lblStatus.Text = "Fichier exporté avec succès !"; } catch (Exception ex) { _excelFile = null; lblStatus.Text = $"Erreur : {ex.Message}"; } finally { this.Cursor = Cursors.Default; btnExport.Enabled = true; } }
internal void ExportVisualTopoToGLB(VisualTopoModel visualTopoModel, DEMDataSet dataset, string outputFile, bool drawOnTexture, float marginMeters, float zFactor, ImageryProvider imageryProvider) { int outputSrid = 3857; float lineWidth = 1.0F; int numTilesPerImage = 4; BoundingBox bbox = visualTopoModel.BoundingBox // relative coords .Translate(visualTopoModel.EntryPoint.Longitude, visualTopoModel.EntryPoint.Latitude, visualTopoModel.EntryPoint.Elevation ?? 0) // absolute coords .Pad(marginMeters) // margin around model .ReprojectTo(visualTopoModel.SRID, dataset.SRID); // DEM coords //======================= // Height map (get dem elevation for bbox) // // Get height map // Note that ref Bbox means that the bbox will be adjusted to match DEM data var heightMap = elevationService.GetHeightMap(ref bbox, dataset, downloadMissingFiles: true); var bboxTerrainSpace = bbox.ReprojectTo(dataset.SRID, outputSrid); // terrain coords // Model origin GeoPoint axisOriginWorldSpace = visualTopoModel.EntryPoint.ReprojectTo(visualTopoModel.SRID, outputSrid) .CenterOnOrigin(bboxTerrainSpace); Vector3 axisOriginModelSpace = visualTopoModel.EntryPoint.AsVector3(); //await signalR.ReportGenerateProgressAsync(signalRConnectionId, "Getting GPX extent elevation...", 20); //======================= // Local transform function from model coordinates (relative to entry, in meters) // and global coordinates absolute in final 3D model space // IEnumerable <GeoPoint> TransformLine(IEnumerable <GeoPoint> line) { var newLine = line.Translate(visualTopoModel.EntryPoint) // Translate to entry (=> global topo coord space) .ReprojectTo(visualTopoModel.SRID, outputSrid) // Reproject to terrain coord space .CenterOnOrigin(bboxTerrainSpace) // Center on terrain space origin .CenterOnOrigin(axisOriginWorldSpace); return(newLine); }; //======================= // 3D model // var gltfModel = sharpGltfService.CreateNewModel(); // Add X/Y/Z axis on entry point var axis = meshService.CreateAxis(); sharpGltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false); int i = 0; var triangulation = visualTopoModel.TriangulationFull3D.Clone() .Translate(axisOriginModelSpace) // already zScaled if zFactor > 1 .ReprojectTo(visualTopoModel.SRID, outputSrid) .CenterOnOrigin(bboxTerrainSpace) .CenterOnOrigin(axisOriginWorldSpace.AsVector3()); gltfModel = sharpGltfService.AddMesh(gltfModel, "Cavite3D", triangulation, VectorsExtensions.CreateColor(0, 255, 0), doubleSided: false); ////======================= //// 3D cavity model //foreach (var line in visualTopoModel.Topology3D) // model.Topology3D is the graph of topo paths //{ // // Add line to model // gltfModel = sharpGltfService.AddLine(gltfModel // , string.Concat("CavitySection", i++) // name of 3D node // , TransformLine(line) // call transform function // , color: VectorsExtensions.CreateColor(255, 0, 0, 128) // , lineWidth); //} // Reproject and center height map coordinates heightMap = heightMap.ReprojectTo(dataset.SRID, outputSrid) .CenterOnOrigin(bboxTerrainSpace) .ZScale(zFactor) .CenterOnOrigin(axisOriginWorldSpace); //======================= // Textures // PBRTexture pbrTexture = null; if (imageryProvider != null) { TileRange tiles = imageryService.DownloadTiles(bbox, imageryProvider, numTilesPerImage); string fileName = Path.Combine(Path.GetDirectoryName(outputFile), "Texture.jpg"); Console.WriteLine("Construct texture..."); TextureInfo texInfo = null; if (drawOnTexture) { var topoTexture = visualTopoModel.Topology3D.SelectMany(l => l).Translate(visualTopoModel.EntryPoint).ReprojectTo(visualTopoModel.SRID, 4326); texInfo = imageryService.ConstructTextureWithGpxTrack(tiles, bbox, fileName, TextureImageFormat.image_jpeg , topoTexture, drawGpxVertices: true); } else { texInfo = imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg); } pbrTexture = PBRTexture.Create(texInfo, null); } // //======================= gltfModel = sharpGltfService.AddTerrainMesh(gltfModel, heightMap, pbrTexture); gltfModel.SaveGLB(outputFile); }
/// <summary> /// Generates a VisualTopo file 3D model /// </summary> /// <remarks>LT* (Lambert Carto) projections are not supported and could produce imprecise results (shifted by +10meters)</remarks> /// <param name="vtopoFile">VisualTopo .TRO file</param> /// <param name="imageryProvider">Imagery provider for terrain texture. Set to null for untextured model</param> /// <param name="bboxMarginMeters">Terrain margin (meters) around VisualTopo model</param> public void Run_3DModelGeneration(string vtopoFile, ImageryProvider imageryProvider, float bboxMarginMeters = 1000, bool generateTopoOnlyModel = false, float zFactor = 1f) { try { //======================= // Generation params // int outputSRID = 3857; // Output SRID float lineWidth = 1.0F; // Topo lines width (meters) var dataset = DEMDataSet.AW3D30; // DEM dataset for terrain and elevation int TEXTURE_TILES = 8; // Texture quality (number of tiles for bigger side) 4: med, 8: high, 12: ultra string outputDir = Directory.GetCurrentDirectory(); bool GENERATE_LINE3D = false; //======================= // Open and parse file // // model will have available properties // => Graph (nodes/arcs) // => BoundingBox // => Topology3D -> list of point-to-point lines // => SRID of model file StopwatchLog timeLog = StopwatchLog.StartNew(_logger); VisualTopoModel model = _visualTopoService.LoadFile(vtopoFile, Encoding.GetEncoding("ISO-8859-1") , decimalDegrees: true , ignoreRadialBeams: true , zFactor); timeLog.LogTime($"Loading {vtopoFile} model file"); // for debug, //var b = GetBranches(model); // graph list of all nodes //var lowestPoint = model.Sets.Min(s => s.Data.Min(d => d.GlobalGeoPoint?.Elevation ?? 0)); BoundingBox bbox = model.BoundingBox // relative coords .Translate(model.EntryPoint.Longitude, model.EntryPoint.Latitude, model.EntryPoint.Elevation ?? 0) // absolute coords .Pad(bboxMarginMeters) // margin around model .ReprojectTo(model.SRID, dataset.SRID); // DEM coords // Get height map // Note that ref Bbox means that the bbox will be adjusted to match DEM data var heightMap = _elevationService.GetHeightMap(ref bbox, dataset, downloadMissingFiles: true); var bboxTerrainSpace = bbox.ReprojectTo(dataset.SRID, outputSRID); // terrain coords timeLog.LogTime("Terrain height map"); //======================= // Get entry elevation (need to reproject to DEM coordinate system first) // and sections entry elevations // _visualTopoService.ComputeFullCavityElevations(model, dataset, zFactor); // will add TerrainElevationAbove and entry elevations _visualTopoService.Create3DTriangulation(model); timeLog.LogTime("Cavity points elevation"); // Model origin GeoPoint axisOriginWorldSpace = model.EntryPoint.ReprojectTo(model.SRID, outputSRID) .CenterOnOrigin(bboxTerrainSpace); Vector3 axisOriginModelSpace = model.EntryPoint.AsVector3(); //======================= // Local transform function from model coordinates (relative to entry, in meters) // and global coordinates absolute in final 3D model space // IEnumerable <GeoPoint> TransformLine(IEnumerable <GeoPoint> line) { var newLine = line.Translate(model.EntryPoint) // Translate to entry (=> global topo coord space) .ReprojectTo(model.SRID, outputSRID) // Reproject to terrain coord space .CenterOnOrigin(bboxTerrainSpace) // Center on terrain space origin .CenterOnOrigin(axisOriginWorldSpace); return(newLine); }; //======================= // 3D model // var gltfModel = _gltfService.CreateNewModel(); // Add X/Y/Z axis on entry point var axis = _meshService.CreateAxis(); _gltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false); int i = 0; var triangulation = model.TriangulationFull3D.Clone() .Translate(axisOriginModelSpace) // already zScaled if zFactor > 1 .ReprojectTo(model.SRID, outputSRID) .CenterOnOrigin(bboxTerrainSpace) .CenterOnOrigin(axisOriginWorldSpace.AsVector3()); gltfModel = _gltfService.AddMesh(gltfModel, "Cavite3D", model.TriangulationFull3D, VectorsExtensions.CreateColor(0, 255, 0), doubleSided: false); if (GENERATE_LINE3D) { foreach (var line in model.Topology3D) // model.Topology3D is the graph of topo paths { // Add line to model gltfModel = _gltfService.AddLine(gltfModel , string.Concat("GPX", i++) // name of 3D node , TransformLine(line) // call transform function , color: VectorsExtensions.CreateColor(255, 0, 0, 128) , lineWidth); } } timeLog.LogTime("Topo 3D model"); //axis = _meshService.CreateAxis(10,100); //_gltfService.AddMesh(gltfModel, "Axis", axis, doubleSided: false); if (generateTopoOnlyModel) { // Uncomment this to save 3D model for topo only (without terrain) gltfModel.SaveGLB(string.Concat(Path.GetFileNameWithoutExtension(vtopoFile) + $"Z{zFactor}_TopoOnly.glb")); } // Reproject and center height map coordinates heightMap = heightMap.ReprojectTo(dataset.SRID, outputSRID) .CenterOnOrigin(bboxTerrainSpace) .ZScale(zFactor) .CenterOnOrigin(axisOriginWorldSpace); //.BakeCoordinates(); timeLog.LogTime("Height map transform"); //======================= // Textures // PBRTexture pbrTexture = null; if (imageryProvider != null) { TileRange tiles = _imageryService.DownloadTiles(bbox, imageryProvider, TEXTURE_TILES); string fileName = Path.Combine(outputDir, "Texture.jpg"); timeLog.LogTime("Imagery download"); Console.WriteLine("Construct texture..."); //TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox, fileName, TextureImageFormat.image_jpeg); var topoTexture = model.Topology3D.SelectMany(l => l).Translate(model.EntryPoint).ReprojectTo(model.SRID, 4326); TextureInfo texInfo = _imageryService.ConstructTextureWithGpxTrack(tiles, bbox, fileName, TextureImageFormat.image_jpeg , topoTexture, false); pbrTexture = PBRTexture.Create(texInfo, null); timeLog.LogTime("Texture creation"); } // //======================= // Triangulate height map _logger.LogInformation($"Triangulating height map and generating 3D mesh..."); gltfModel = _gltfService.AddTerrainMesh(gltfModel, heightMap, pbrTexture); gltfModel.SaveGLB(string.Concat(Path.GetFileNameWithoutExtension(vtopoFile) + $"Z{zFactor}.glb")); timeLog.LogTime("3D model"); } catch (Exception ex) { _logger.LogError("Error :" + ex.Message); } }