public void Test_FileFormat_GeoTIFF() { string fileName = "N043E005_AVE_DSM.tif"; string sourceFile = Path.Combine("TestData", fileName + ".zip"); bool fileOk = File.Exists(sourceFile); Assert.True(fileOk, "TestData is missing"); if (!File.Exists(fileName)) { ZipFile.ExtractToDirectory(sourceFile, "."); } Assert.True(File.Exists(fileName), "Unzip failed."); // Pass the full file name fileName = Path.GetFullPath(fileName); using (IRasterFile raster = _rasterService.OpenFile(fileName, DEMFileType.GEOTIFF)) { FileMetadata metaData = raster.ParseMetaData(new DEMFileDefinition(DEMFileType.GEOTIFF, DEMFileRegistrationMode.Cell)); Assert.NotNull(metaData); float elevation = raster.GetElevationAtPoint(metaData, 1000, 200); Assert.Equal(304f, elevation); elevation = raster.GetElevationAtPoint(metaData, 200, 1000); Assert.Equal(95f, elevation); } }
public void Test_GLB_Export() { string fileName = "N43E005.hgt"; string sourceFile = Path.Combine("TestData", fileName + ".zip"); bool fileOk = File.Exists(sourceFile); Assert.True(fileOk, "TestData is missing"); if (!File.Exists(fileName)) { ZipFile.ExtractToDirectory(sourceFile, ".", true); } Assert.True(File.Exists(fileName), "Unzip failed."); // Pass the full file name fileName = Path.GetFullPath(fileName); using (IRasterFile raster = _rasterService.OpenFile(fileName, DEMFileType.SRTM_HGT)) { FileMetadata metaData = raster.ParseMetaData(new DEMFileDefinition(DEMFileType.SRTM_HGT, DEMFileRegistrationMode.Grid)); Assert.NotNull(metaData); HeightMap heightMap = _elevationService.GetHeightMap(metaData) .ReprojectGeodeticToCartesian() .ZScale(2.5f); var model = _sharpGltfService.CreateTerrainMesh(heightMap); model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), "test.glb")); } }
public void GenerateModel(string bboxWkt, DEMDataSet litto3DDataset, ImageryProvider imageryProvider, float zFactor = 3f, bool withTexture = true, bool withboat = true, bool withWaterSurface = true, DEMDataSet fallbackDataset = null) { try { bool centerOnOrigin = true; int TEXTURE_TILES = 20; string outputDir = Directory.GetCurrentDirectory(); string modelName = $"{litto3DDataset.ResolutionMeters}m_z{zFactor}_{imageryProvider.Name}-{DateTime.Now:yyyyMMdd-hhmmss}"; _logger.LogInformation($"Getting height map data..."); var bbox = GeometryService.GetBoundingBox(bboxWkt).ReprojectTo(4326, litto3DDataset.SRID); var heightMap = _elevationService.GetHeightMap(ref bbox, litto3DDataset); heightMap = heightMap.BakeCoordinates(); var nullCoordsEnumerator = heightMap.Coordinates.Where(c => (c.Elevation ?? litto3DDataset.NoDataValue) == litto3DDataset.NoDataValue); var interpolator = _elevationService.GetInterpolator(InterpolationMode.Bilinear); using (IRasterFile raster = _rasterService.OpenFile(@"D:\Data\ELEVATION_DO_NOT_DELETE\GEBCO2020\cote azur\gebco_2020_subset.tif", DEMFileType.GEOTIFF)) using (RasterFileDictionary dic = new RasterFileDictionary()) { var metadata = raster.ParseMetaData(fallbackDataset.FileFormat); dic.Add(metadata, raster); foreach (var pt in nullCoordsEnumerator) { var proj = pt.ReprojectTo(litto3DDataset.SRID, fallbackDataset.SRID); pt.Elevation = _elevationService.GetElevationAtPoint(raster, dic, metadata, proj.Latitude, proj.Longitude, 0, interpolator, NoDataBehavior.UseNoDataDefinedInDem); } } var nullCoords = heightMap.Coordinates.Where(c => (c.Elevation ?? litto3DDataset.NoDataValue) == litto3DDataset.NoDataValue).ToList(); var nullCoordsFallbackProj = nullCoords.ReprojectTo(litto3DDataset.SRID, fallbackDataset.SRID, nullCoords.Count); var nullCoordsFallbackProj2 = _elevationService.GetPointsElevation(nullCoordsFallbackProj, fallbackDataset, InterpolationMode.Bilinear, NoDataBehavior.UseNoDataDefinedInDem); ModelGenerationTransform transform = new ModelGenerationTransform(bbox, 3857, centerOnOrigin: centerOnOrigin, zFactor, centerOnZOrigin: false); ModelGenerationTransform transformFrom4326 = new ModelGenerationTransform(bbox.ReprojectTo(2154, 4326), 3857, centerOnOrigin: centerOnOrigin, zFactor, centerOnZOrigin: false); _logger.LogInformation($"Processing height map data ({heightMap.Count} coordinates)..."); heightMap = transform.TransformHeightMap(heightMap); var min = heightMap.Coordinates.Where(g => (g.Elevation ?? 0d) > litto3DDataset.NoDataValue).Min(g => g.Elevation ?? 0d); heightMap.Coordinates = heightMap.Coordinates.Select(p => { if (p.Elevation.GetValueOrDefault(0) <= litto3DDataset.NoDataValue) { p.Elevation = min; } return(p); }); //======================= // Textures // PBRTexture pbrTexture = null; if (withTexture) { var bbox4326 = bbox.ReprojectTo(2154, 4326); Console.WriteLine("Download image tiles..."); TileRange tiles = _imageryService.DownloadTiles(bbox4326, imageryProvider, TEXTURE_TILES); string fileName = Path.Combine(outputDir, "Texture.jpg"); Console.WriteLine("Construct texture..."); //TextureInfo texInfo = _imageryService.ConstructTexture(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg); TextureInfo texInfo; if (withboat) { var trackPoints = GetGeoPointFromGeoJson(BoatCourseGeoJson); texInfo = _imageryService.ConstructTextureWithGpxTrack(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg, trackPoints, drawGpxVertices: true, color: SixLabors.ImageSharp.PixelFormats.Rgba32.Green, 30); } else { texInfo = _imageryService.ConstructTexture(tiles, bbox4326, fileName, TextureImageFormat.image_jpeg); } // //======================= //======================= // Normal map Console.WriteLine("Height map..."); //float Z_FACTOR = 0.00002f; //hMap = hMap.CenterOnOrigin().ZScale(Z_FACTOR); //var normalMap = _imageryService.GenerateNormalMap(heightMap, outputDir); pbrTexture = PBRTexture.Create(texInfo, null);// normalMap); //hMap = hMap.CenterOnOrigin(Z_FACTOR); // //======================= } // Triangulate height map // and add base and sides _logger.LogInformation($"Triangulating height map and generating 3D mesh..."); heightMap = heightMap.BakeCoordinates(); var coords = heightMap.Coordinates.ToList(); var model = _sharpGltfService.CreateTerrainMesh(heightMap, pbrTexture); if (withWaterSurface) { var bottomLeft = coords[heightMap.Width * (heightMap.Height - 1)].AsVector3(); bottomLeft.Z = 0; var topRight = coords[heightMap.Width - 1].AsVector3(); topRight.Z = 0; var topLeft = coords[0].AsVector3(); topLeft.Z = 0; var bottomRight = coords.Last().AsVector3(); bottomRight.Z = 0; var waterSurface = _meshService.CreateWaterSurface(bottomLeft, topRight, topLeft, bottomRight, minZ: (float)min, color: VectorsExtensions.CreateColor(0, 150, 255, 64)); model = _sharpGltfService.AddMesh(model, "Water", waterSurface, doubleSided: true); } if (withboat) { var boatInitPos = centerOnOrigin ? new GeoPoint(0, 0).AsVector3() : new GeoPoint(43.010625204304304, 6.3711613671060086).ReprojectTo(4326, 3857).AsVector3(); var axis = _meshService.CreateAxis(2, 10, 3, 3).Translate(boatInitPos); model = _sharpGltfService.AddMesh(model, "Boat", axis, doubleSided: false); var boatCourse = transformFrom4326.TransformPoints(GetGeoPointFromGeoJson(BoatCourseGeoJson)).ToList(); //ReprojectGeodeticToCartesian().CenterOnOrigin().ToList(); model = _sharpGltfService.AddLine(model, "BoatCourse", boatCourse, VectorsExtensions.CreateColor(255, 0, 0, 128), 4); } model.SaveGLB(Path.Combine(Directory.GetCurrentDirectory(), modelName + ".glb")); _logger.LogInformation($"Model exported as {Path.Combine(Directory.GetCurrentDirectory(), modelName + ".gltf")} and .glb"); //var point = new GeoPoint(43.01142119356318, 6.385200681010872).ReprojectTo(4326, 2154); //point = _elevationService.GetPointElevation(point, litto3DDataset); } catch (Exception e) { _logger.LogError(e, e.Message); } }
void TestEdges(string dataSetName, double lat, double lon , string rasterSouthWestName, string rasterSouthEastName , string rasterNorthWestName, string rasterNorthEastName) { DEMDataSet dataSet = DEMDataSet.RegisteredDatasets.FirstOrDefault(d => d.Name == dataSetName); Assert.NotNull(dataSet); DEMFileType fileType = dataSet.FileFormat.Type; int rasterSize = dataSet.PointsPerDegree; double amountx = (1d / rasterSize) / 4d; double amounty = (1d / rasterSize) / 4d; // Regenerates all metadata //_rasterService.GenerateDirectoryMetadata(dataSet // , force: true // , deleteOnError: false // , maxDegreeOfParallelism: 1); _elevationService.DownloadMissingFiles(dataSet, lat, lon); var tiles = _rasterService.GenerateReportForLocation(dataSet, lat, lon); Assert.True(tiles.Count == 4); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterSouthWestName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterSouthEastName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterNorthWestName, StringComparison.OrdinalIgnoreCase)); Assert.Single(tiles, t => string.Equals(Path.GetFileName(t.LocalName), rasterNorthEastName, StringComparison.OrdinalIgnoreCase)); if (dataSet.FileFormat.Registration == DEMFileRegistrationMode.Cell) { using (var rasterNW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterNE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) { var elevNW = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize - 1); var elevNE = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 0, rasterSize - 1); var elevSW = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, 0); var elevSE = rasterSE.GetElevationAtPoint(rasterSE.ParseMetaData(dataSet.FileFormat), 0, 0); BilinearInterpolator interpolator = new BilinearInterpolator(); var elev0 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.25, 0.25); var apiElev0 = _elevationService.GetPointElevation(lat + amounty, lon - amountx, dataSet); Assert.True((elev0 - apiElev0.Elevation.Value) < double.Epsilon); var elev1 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.75, 0.25); var apiElev1 = _elevationService.GetPointElevation(lat + amounty, lon + amountx, dataSet); Assert.True((elev1 - apiElev1.Elevation.Value) < double.Epsilon); var elev2 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.25, 0.75); var apiElev2 = _elevationService.GetPointElevation(lat - amounty, lon - amountx, dataSet); Assert.True((elev2 - apiElev2.Elevation.Value) < double.Epsilon); var elev3 = interpolator.Interpolate(elevSW, elevSE, elevNW, elevNE, 0.75, 0.75); var apiElev3 = _elevationService.GetPointElevation(lat - amounty, lon + amountx, dataSet); Assert.True((elev3 - apiElev3.Elevation.Value) < double.Epsilon); } } else { using (var rasterNW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterNE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterNorthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSW = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthWestName, Path.GetFileName(t.LocalName))).LocalName, fileType)) using (var rasterSE = _rasterService.OpenFile(tiles.First(t => string.Equals(rasterSouthEastName, Path.GetFileName(t.LocalName))).LocalName, fileType)) { // Northen row, west to east var elevN0 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize - 1); var elevN1 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize, rasterSize - 1); var elevN2 = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 1, rasterSize - 1); // middle row, west to east var elevM0 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, rasterSize); var elevM1 = rasterNW.GetElevationAtPoint(rasterNW.ParseMetaData(dataSet.FileFormat), rasterSize, rasterSize); var elevM2 = rasterNE.GetElevationAtPoint(rasterNE.ParseMetaData(dataSet.FileFormat), 1, rasterSize); // Sourthen row, west to east var elevS0 = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize - 1, 1); var elevS1 = rasterSW.GetElevationAtPoint(rasterSW.ParseMetaData(dataSet.FileFormat), rasterSize, 1); var elevS2 = rasterSE.GetElevationAtPoint(rasterSE.ParseMetaData(dataSet.FileFormat), 1, 1); BilinearInterpolator interpolator = new BilinearInterpolator(); var elev0 = interpolator.Interpolate(elevM0, elevM1, elevN0, elevN1, 0.75, 0.75); var apiElev0 = _elevationService.GetPointElevation(lat + amounty, lon - amountx, dataSet); Assert.True((elev0 - apiElev0.Elevation.Value) < double.Epsilon); var elev1 = interpolator.Interpolate(elevM1, elevM2, elevN1, elevN2, 0.25, 0.75); var apiElev1 = _elevationService.GetPointElevation(lat + amounty, lon + amountx, dataSet); Assert.True((elev1 - apiElev1.Elevation.Value) < double.Epsilon); var elev2 = interpolator.Interpolate(elevS0, elevS1, elevM0, elevM1, 0.75, 0.25); var apiElev2 = _elevationService.GetPointElevation(lat - amounty, lon - amountx, dataSet); Assert.True((elev2 - apiElev2.Elevation.Value) < double.Epsilon); var elev3 = interpolator.Interpolate(elevS1, elevS2, elevM1, elevM2, 0.25, 0.25); var apiElev3 = _elevationService.GetPointElevation(lat - amounty, lon + amountx, dataSet); Assert.True((elev3 - apiElev3.Elevation.Value) < double.Epsilon); } } }