internal void Run(string gpxFile, DEMDataSet dataSet, float Z_FACTOR = 2f, int outputSrid = Reprojection.SRID_PROJECTED_MERCATOR) { try { float paddingFactor = 2f; float ModelMaxUnits = 250f; float GpxLineWidthSTLUnits = 0.1f; Matrix4x4 stlTransformMatrix = Matrix4x4.CreateRotationX((float)Math.PI / 2f); string outputDir = Path.GetFullPath("."); //======================= /// Line strip from GPX /// // Get GPX points var segments = GpxImport.ReadGPX_Segments(gpxFile); var points = segments.SelectMany(seg => seg); var bbox = points.GetBoundingBox().ReprojectTo(4326, outputSrid); bbox = bbox.Pad(bbox.Width * paddingFactor, bbox.Height * paddingFactor, 0) .ReprojectTo(outputSrid, 4326); var gpxPointsElevated = _elevationService.GetPointsElevation(points, dataSet); HeightMap hMap = _elevationService.GetHeightMap(ref bbox, dataSet); hMap = hMap.ReprojectTo(4326, outputSrid) .ZScale(Z_FACTOR) .CenterOnOrigin() .FitInto(ModelMaxUnits) .BakeCoordinates(); // generate mesh ModelRoot model = _sharpGltfService.CreateTerrainMesh(hMap, GenOptions.BoxedBaseElevationMin, stlTransformMatrix); List <Attribution> attributions = new List <Attribution>(); attributions.Add(dataSet.Attribution); attributions.Add(new Attribution("Generator", "DEM Net Elevation API", "https://elevationapi.com")); _stlService.STLExport(model.LogicalMeshes[0].Primitives[0], Path.ChangeExtension(gpxFile, ".stl"), false, attributions); var bboxPoints = bbox.ReprojectTo(4326, outputSrid).CenterOnOrigin(); gpxPointsElevated = gpxPointsElevated.ReprojectTo(4326, outputSrid) .ZScale(Z_FACTOR) .CenterOnOrigin(bbox.ReprojectTo(4326, outputSrid)) .FitInto(bboxPoints, ModelMaxUnits) .ToList(); var gpxModel = _sharpGltfService.AddLine(null, "GPX", gpxPointsElevated, Vector4.One, GpxLineWidthSTLUnits, stlTransformMatrix); _stlService.STLExport(gpxModel.LogicalMeshes[0].Primitives[0], Path.ChangeExtension(gpxFile, ".gpx.stl"), false, attributions); } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }
public void Run() { try { DEMDataSet dataset = DEMDataSet.SRTM_GL3; Stopwatch sw = Stopwatch.StartNew(); string modelName = $"Montagne Sainte Victoire {dataset.Name}"; // You can get your boox from https://geojson.net/ (save as WKT) string bboxWKT = "POLYGON((5.54888 43.519525, 5.61209 43.519525, 5.61209 43.565225, 5.54888 43.565225, 5.54888 43.519525))"; _logger.LogInformation($"Processing model {modelName}..."); _logger.LogInformation($"Getting bounding box geometry..."); var bbox = GeometryService.GetBoundingBox(bboxWKT); _logger.LogInformation($"Getting height map data..."); var heightMap = _elevationService.GetHeightMap(ref bbox, dataset); _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)..."); heightMap = heightMap .ReprojectGeodeticToCartesian() // Reproject to 3857 (useful to get coordinates in meters) .ZScale(2f) // Elevation exageration .CenterOnOrigin() // .FitInto(250f); // Make sure model fits into 250 coordinates units (3D printer size was 30x30cm) // Triangule Irregular Network (not implemented to STL yet) //var TINmesh =TINGeneration.GenerateTIN(heightMap, 2, _glTFService, null, 3857); // Triangulate height map // and add base and sides _logger.LogInformation($"Triangulating height map and generating box (5mm thick)..."); // STL axis differ from glTF var model = _sharpGltfService.CreateTerrainMesh(heightMap, GenOptions.BoxedBaseElevationMin, Matrix4x4.CreateRotationX((float)Math.PI / 2f)); _logger.LogInformation($"Exporting STL model..."); var stlFilePath = Path.Combine(Directory.GetCurrentDirectory(), $"{modelName}.stl"); _stlService.STLExport(model.LogicalMeshes[0].Primitives[0], stlFilePath, false); _logger.LogInformation($"Model exported in {stlFilePath}."); _logger.LogInformation($"Done in {sw.Elapsed:g}"); } catch (Exception ex) { _logger.LogError(ex, ex.Message); } }