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, DEMFileFormat.SRTM_HGT)) { FileMetadata metaData = raster.ParseMetaData(); Assert.NotNull(metaData); string str2 = "zsq4"; HeightMap heightMap = _elevationService.GetHeightMap(metaData) .ReprojectGeodeticToCartesian() .ZScale(2.5f); MeshPrimitive meshPrimitive = _gltfService.GenerateTriangleMesh(heightMap); Model model = _gltfService.GenerateModel(meshPrimitive, str2); _gltfService.Export(model, ".", str2, false, true); } }
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 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_FileFormat_HGT_OutOfRange() { 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, "."); } 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); Assert.Throws <IndexOutOfRangeException>(() => { float elevation = raster.GetElevationAtPoint(metaData, 10000, 10000); }); // Expect exception } }
public void Test_FileFormat_HGT() { 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, DEMFileFormat.SRTM_HGT)) { FileMetadata metaData = raster.ParseMetaData(); Assert.NotNull(metaData); float elevation = raster.GetElevationAtPoint(metaData, 300, 10); Assert.Equal(751f, elevation); elevation = raster.GetElevationAtPoint(metaData, 10, 300); Assert.Equal(297f, elevation); } }
public float GetPointElevation(IRasterFile raster, FileMetadata metadata, double lat, double lon, IInterpolator interpolator = null) { // Do not dispose Dictionary, as IRasterFile disposal is the caller's responsability RasterFileDictionary rasters = new RasterFileDictionary(); rasters.Add(metadata, raster); return(GetElevationAtPoint(raster, rasters, metadata, lat, lon, 0, interpolator)); }
public HeightMap GetHeightMap(BoundingBox bbox, DEMDataSet dataSet) { DownloadMissingFiles(dataSet, bbox); // Locate which files are needed // Find files matching coords List <FileMetadata> bboxMetadata = GetCoveringFiles(bbox, dataSet); if (bboxMetadata.Count == 0) { string errorMessage = $"Dataset {dataSet.Name} has no coverage for provided bounding box."; this._logger.LogWarning(errorMessage); throw new Exception(errorMessage); } else { // Check if bounding box is fully covered (will result in invalid models without any error being thrown) bool covered = this.IsBoundingBoxCovered(bbox, bboxMetadata.Select(m => m.BoundingBox)); if (!covered) { const string errorMessage = "Bounding box is partially covered by DEM dataset. Heightmap in its current state supports only full data tiles."; this._logger.LogWarning(errorMessage); throw new Exception(errorMessage); } else { // get height map for each file at bbox List <HeightMap> tilesHeightMap = new List <HeightMap>(bboxMetadata.Count); foreach (FileMetadata metadata in bboxMetadata) { using (IRasterFile raster = _IRasterService.OpenFile(metadata.Filename, dataSet.FileFormat)) { tilesHeightMap.Add(raster.GetHeightMapInBBox(bbox, metadata, NO_DATA_OUT)); } } // Merge height maps int totalHeight = tilesHeightMap.GroupBy(h => h.BoundingBox.xMin).Select(g => g.Sum(v => v.Height)).First(); int totalWidth = tilesHeightMap.GroupBy(h => h.BoundingBox.yMin).Select(g => g.Sum(v => v.Width)).First(); HeightMap heightMap = new HeightMap(totalWidth, totalHeight); heightMap.BoundingBox = new BoundingBox(xmin: tilesHeightMap.Min(h => h.BoundingBox.xMin) , xmax: tilesHeightMap.Max(h => h.BoundingBox.xMax) , ymin: tilesHeightMap.Min(h => h.BoundingBox.yMin) , ymax: tilesHeightMap.Max(h => h.BoundingBox.yMax)); heightMap.Coordinates = tilesHeightMap.SelectMany(hmap => hmap.Coordinates).Sort(); heightMap.Count = totalWidth * totalHeight; heightMap.Minimum = tilesHeightMap.Min(hmap => hmap.Minimum); heightMap.Maximum = tilesHeightMap.Max(hmap => hmap.Maximum); System.Diagnostics.Debug.Assert(heightMap.Count == tilesHeightMap.Sum(h => h.Count)); return(heightMap); } } }
public HeightMap GetHeightMap(FileMetadata metadata) { HeightMap map = null; using (IRasterFile raster = _IRasterService.OpenFile(metadata.Filename, metadata.fileFormat)) { map = raster.GetHeightMap(metadata); } return(map); }
public HeightMap GetHeightMap(BoundingBox bbox, string rasterFilePath, DEMFileFormat format) { HeightMap heightMap = null; using (IRasterFile raster = _IRasterService.OpenFile(rasterFilePath, format)) { var metaData = raster.ParseMetaData(); heightMap = raster.GetHeightMapInBBox(bbox, metaData, NO_DATA_OUT); } return(heightMap); }
public float GetPointElevation(FileMetadata metadata, double lat, double lon, IInterpolator interpolator = null) { float heightValue = 0; try { using (IRasterFile raster = _IRasterService.OpenFile(metadata.Filename, metadata.fileFormat)) { heightValue = GetPointElevation(raster, metadata, lat, lon, interpolator); } } catch (Exception e) { _logger?.LogError(e, $"Error while getting elevation data : {e.Message}{Environment.NewLine}{e.ToString()}"); } return(heightValue); }
public FileMetadata ParseMetadata(string fileName, DEMFileFormat fileFormat, bool makeRelativePath = true) { FileMetadata metadata = null; fileName = Path.GetFullPath(fileName); using (IRasterFile rasterFile = OpenFile(fileName, fileFormat)) { metadata = rasterFile.ParseMetaData(); } Uri fullPath = new Uri(metadata.Filename, UriKind.Absolute); Uri relRoot = new Uri(Path.GetFullPath(_localDirectory) + Path.DirectorySeparatorChar, UriKind.Absolute); metadata.Filename = Uri.UnescapeDataString(relRoot.MakeRelativeUri(fullPath).ToString()); return(metadata); }
public HeightMap GetHeightMap(BoundingBox bbox, DEMDataSet dataSet) { DownloadMissingFiles(dataSet, bbox); // Locate which files are needed // Find files matching coords List <FileMetadata> bboxMetadata = GetCoveringFiles(bbox, dataSet); // get height map for each file at bbox List <HeightMap> tilesHeightMap = new List <HeightMap>(bboxMetadata.Count); foreach (FileMetadata metadata in bboxMetadata) { using (IRasterFile raster = _IRasterService.OpenFile(metadata.Filename, dataSet.FileFormat)) { tilesHeightMap.Add(raster.GetHeightMapInBBox(bbox, metadata, NO_DATA_OUT)); } } // Merge height maps int totalHeight = tilesHeightMap.GroupBy(h => h.BoundingBox.xMin).Select(g => g.Sum(v => v.Height)).First(); int totalWidth = tilesHeightMap.GroupBy(h => h.BoundingBox.yMin).Select(g => g.Sum(v => v.Width)).First(); HeightMap heightMap = new HeightMap(totalWidth, totalHeight); heightMap.BoundingBox = new BoundingBox(xmin: tilesHeightMap.Min(h => h.BoundingBox.xMin) , xmax: tilesHeightMap.Max(h => h.BoundingBox.xMax) , ymin: tilesHeightMap.Min(h => h.BoundingBox.yMin) , ymax: tilesHeightMap.Max(h => h.BoundingBox.yMax)); heightMap.Coordinates = tilesHeightMap.SelectMany(hmap => hmap.Coordinates).Sort(); heightMap.Count = totalWidth * totalHeight; heightMap.Minimum = tilesHeightMap.Min(hmap => hmap.Minimum); heightMap.Maximum = tilesHeightMap.Max(hmap => hmap.Maximum); System.Diagnostics.Debug.Assert(heightMap.Count == tilesHeightMap.Sum(h => h.Count)); return(heightMap); }
public FileMetadata ParseMetadata(IRasterFile rasterFile, bool makeRelativePath = false) { return(rasterFile.ParseMetaData()); }
public FileMetadata ParseMetadata(IRasterFile rasterFile, DEMFileDefinition format) { return(rasterFile.ParseMetaData(format)); }
private float GetElevationAtPoint(IRasterFile mainRaster, RasterFileDictionary adjacentTiles, FileMetadata metadata, double lat, double lon, float lastElevation, IInterpolator interpolator) { float heightValue = 0; try { //const double epsilon = (Double.Epsilon * 100); float noData = metadata.NoDataValueFloat; double yPixel, xPixel, xInterpolationAmount, yInterpolationAmount; // pixel coordinates interpolated if (metadata.FileFormat.Registration == DEMFileRegistrationMode.Grid) { yPixel = Math.Sign(metadata.pixelSizeY) == 1 ? (metadata.DataEndLat - lat) / metadata.pixelSizeY : (lat - metadata.DataEndLat) / metadata.pixelSizeY; xPixel = (lon - metadata.DataStartLon) / metadata.pixelSizeX; // If at pixel center (ending by .5, .5), we are on the data point, so no need for adjacent raster checks xInterpolationAmount = (double)(xPixel) % 1d; yInterpolationAmount = (double)(yPixel) % 1d; } else { // In cell registration mode, the actual data point is at pixel center // If at pixel center (ending by .5, .5), we are on the data point, so no need for adjacent raster checks yPixel = Math.Sign(metadata.pixelSizeY) == 1 ? ((metadata.PhysicalEndLat + metadata.pixelSizeY / 2) - lat) / metadata.pixelSizeY : (lat - (metadata.PhysicalEndLat + metadata.pixelSizeY / 2)) / metadata.pixelSizeY; xPixel = (lon - (metadata.PhysicalStartLon + metadata.pixelSizeX / 2)) / metadata.pixelSizeX; xInterpolationAmount = Math.Abs((double)(xPixel) % 1d); yInterpolationAmount = Math.Abs((double)(yPixel) % 1d); } bool xOnDataPoint = Math.Abs(xInterpolationAmount) < EPSILON; bool yOnDataPoint = Math.Abs(yInterpolationAmount) < EPSILON; // If xOnGrid and yOnGrid, we are on a grid intersection, and that's all // TODO fix that // When cell registered, this true when interpolation is 0.5 / 0.5 // When grid registered, this is true if (xOnDataPoint && yOnDataPoint) { int x = (int)Math.Round(xPixel, 0); int y = (int)Math.Round(yPixel, 0); var tile = FindTile(metadata, adjacentTiles, x, y, out x, out y); heightValue = mainRaster.GetElevationAtPoint(tile, x, y); } else { int xCeiling = (int)Math.Ceiling(xPixel); int xFloor = (int)Math.Floor(xPixel); int yCeiling = (int)Math.Ceiling(yPixel); int yFloor = (int)Math.Floor(yPixel); // Get 4 grid nearest points (DEM grid corners) // If not yOnGrid and not xOnGrid we are on grid horizontal line // We need elevations for top, bottom, left and right grid points (along x axis and y axis) float northWest = GetElevationAtPoint(metadata, adjacentTiles, xFloor, yFloor, noData); float northEast = GetElevationAtPoint(metadata, adjacentTiles, xCeiling, yFloor, noData); float southWest = GetElevationAtPoint(metadata, adjacentTiles, xFloor, yCeiling, noData); float southEast = GetElevationAtPoint(metadata, adjacentTiles, xCeiling, yCeiling, noData); float avgHeight = GetAverageExceptForNoDataValue(noData, NO_DATA_OUT, southWest, southEast, northWest, northEast); if (northWest == noData) { northWest = avgHeight; } if (northEast == noData) { northEast = avgHeight; } if (southWest == noData) { southWest = avgHeight; } if (southEast == noData) { southEast = avgHeight; } heightValue = (float)interpolator.Interpolate(southWest, southEast, northWest, northEast, xInterpolationAmount, yInterpolationAmount); } if (heightValue == NO_DATA_OUT) { heightValue = lastElevation; } } catch (Exception e) { _logger?.LogError(e, $"Error while getting elevation data : {e.Message}{Environment.NewLine}{e.ToString()}"); throw; } return(heightValue); }
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); } }
public FileMetadata ParseMetadata(IRasterFile rasterFile, DEMFileDefinition format, bool makeRelativePath = false) { return(rasterFile.ParseMetaData(format)); }
private bool InsertImage(IFeatureUpdater fdb, IFeatureClass rasterFC, FileInfo fi, Dictionary <string, Guid> providers) { if (!_cancelTracker.Continue) { _errMsg = "Canceled by user..."; return(false); } if (ReportAction != null) { ReportAction(this, "Insert Image: " + fi.FullName); } if (ReportProgress != null) { ReportProgress(this, 1); } System.Drawing.Imaging.ImageFormat format = System.Drawing.Imaging.ImageFormat.Jpeg; switch (fi.Extension.ToLower()) { case ".png": format = System.Drawing.Imaging.ImageFormat.Png; break; case ".tif": case ".tiff": format = System.Drawing.Imaging.ImageFormat.Tiff; break; } #region RasterFileDataset bestimmen List <IRasterFileDataset> rFileDatasets = new List <IRasterFileDataset>(); IRasterFileDataset rFileDataset = null; IRasterLayer rasterLayer = null; PlugInManager compMan = new PlugInManager(); foreach (XmlNode ds in compMan.GetPluginNodes(Plugins.Type.IDataset)) { IRasterFileDataset rds = compMan.CreateInstance(ds) as IRasterFileDataset; if (rds == null) { continue; } if (rds.SupportsFormat(fi.Extension) < 0) { continue; } if (providers != null && providers.ContainsKey(fi.Extension.ToLower())) { if (!providers[fi.Extension.ToLower()].Equals(PlugInManager.PlugInID(rds))) { continue; } } rFileDatasets.Add(rds); } if (rFileDatasets.Count == 0) { _errMsg = "No Rasterfile Provider for " + fi.Extension; return(false); } // RasterFileDataset nach priorität sortieren rFileDatasets.Sort(new RasterFileDatasetComparer(fi.Extension)); // RasterFileDataset suchen, mit dem sich Bild öffnen läßt foreach (IRasterFileDataset rfd in rFileDatasets) { rfd.AddRasterFile(fi.FullName); if (rfd.Elements.Count == 0) { //Console.WriteLine(_errMsg = fi.FullName + " is not a valid Raster File..."); continue; } IDatasetElement element = rfd.Elements[0]; if (!(element is IRasterLayer)) { //Console.WriteLine(_errMsg = fi.FullName + " is not a valid Raster Layer..."); rFileDataset.Dispose(); continue; } // gefunden... rasterLayer = (IRasterLayer)element; rFileDataset = rfd; break; } if (rasterLayer == null || rFileDataset == null) { Console.WriteLine(_errMsg = fi.FullName + " is not a valid Raster Layer..."); return(false); } #endregion FileInfo fiWorld = null; double cellX = 1; double cellY = 1; IRasterFile rasterFile = null; if (rasterLayer is IRasterFile) { rasterFile = (IRasterFile)rasterLayer; } if (rasterLayer.RasterClass != null) { if (rasterLayer.RasterClass is IRasterFile && ((IRasterFile)rasterLayer.RasterClass).WorldFile != null) { rasterFile = (IRasterFile)rasterLayer.RasterClass; } else { IRasterClass c = (IRasterClass)rasterLayer.RasterClass; cellX = Math.Sqrt(c.dx1 * c.dx1 + c.dx2 * c.dx2); cellY = Math.Sqrt(c.dy1 * c.dy1 + c.dy2 * c.dy2); } } if (rasterFile != null) { try { IRasterWorldFile world = rasterFile.WorldFile; if (world != null) { if (!world.isGeoReferenced) { if (handleNonGeorefAsError) { _errMsg = "Can't add non georeferenced images: " + fi.FullName; return(false); } else { return(true); } } cellX = Math.Sqrt(world.dx_X * world.dx_X + world.dx_Y * world.dx_Y); cellY = Math.Sqrt(world.dy_X * world.dy_X + world.dy_Y * world.dy_Y); fiWorld = new FileInfo(rasterFile.WorldFile.Filename); if (!fiWorld.Exists) { fiWorld = null; } } } catch { fiWorld = null; } } #region Check if already Exits // // Suchen, ob Image mit gleichen Pfad schon vorhanden ist, wenn ja // nur weitermachen, wenn sich das änderungsdatum unterscheidet... // QueryFilter filter = new QueryFilter(); filter.AddField("FDB_OID"); filter.AddField("PATH"); filter.AddField("LAST_MODIFIED"); filter.AddField("PATH2"); filter.AddField("LAST_MODIFIED2"); string fullName = fi.FullName.Replace(@"\", @"\\"); if (_fdb is AccessFDB) { filter.WhereClause = ((AccessFDB)_fdb).DbColName("PATH") + "='" + fullName + "'"; } else { filter.WhereClause = "PATH='" + fullName + "'"; } int deleteOID = -1; using (IFeatureCursor cursor = rasterFC.GetFeatures(filter)) { IFeature existingFeature = cursor.NextFeature; if (existingFeature != null) { DateTime dt1 = (DateTime)existingFeature["LAST_MODIFIED"]; if (Math.Abs(((TimeSpan)(dt1 - fi.LastWriteTimeUtc)).TotalSeconds) > 1.0) { deleteOID = existingFeature.OID; } else if (fiWorld != null && existingFeature["PATH2"] != System.DBNull.Value && existingFeature["PATH2"].ToString() != String.Empty) { DateTime dt2 = (DateTime)existingFeature["LAST_MODIFIED2"]; if (existingFeature["PATH2"].ToString().ToLower() != fiWorld.FullName.ToLower() || Math.Abs(((TimeSpan)(dt2 - fiWorld.LastWriteTimeUtc)).TotalSeconds) > 1.0) { deleteOID = existingFeature.OID; } } if (deleteOID == -1) { Console.Write("."); //Console.WriteLine(fi.FullName + " already exists..."); return(true); } } } if (deleteOID != -1) { if (!fdb.Delete(rasterFC, deleteOID)) { Console.WriteLine(_errMsg = "Can't delete old record " + fi.FullName + "\n" + fdb.lastErrorMsg); return(false); } } // /////////////////////////////////////////////////////////////////// // #endregion Feature feature = new Feature(); feature.Shape = rasterLayer.RasterClass.Polygon; feature.Fields.Add(new FieldValue("PATH", fi.FullName)); feature.Fields.Add(new FieldValue("LAST_MODIFIED", fi.LastWriteTimeUtc)); if (fiWorld != null) { feature.Fields.Add(new FieldValue("PATH2", fiWorld.FullName)); feature.Fields.Add(new FieldValue("LAST_MODIFIED2", fiWorld.LastWriteTimeUtc)); } else { feature.Fields.Add(new FieldValue("PATH2", "")); } feature.Fields.Add(new FieldValue("RF_PROVIDER", PlugInManager.PlugInID(rFileDataset).ToString())); feature.Fields.Add(new FieldValue("MANAGED", _managed && (rasterLayer is IBitmap))); feature.Fields.Add(new FieldValue("FORMAT", fi.Extension.Replace(".", ""))); feature.Fields.Add(new FieldValue("CELLX", cellX)); feature.Fields.Add(new FieldValue("CELLY", cellY)); feature.Fields.Add(new FieldValue("LEVELS", (_managed) ? Math.Max(_levels, 1) : 0)); if (!fdb.Insert(rasterFC, feature)) { Console.WriteLine("\nERROR@" + fi.FullName + ": " + fdb.lastErrorMsg); } else { if (_managed && (rasterLayer is IBitmap) && (fdb is SqlFDB)) { QueryFilter qfilter = new QueryFilter(); qfilter.SubFields = "FDB_OID"; if (_fdb is AccessFDB) { filter.WhereClause = ((AccessFDB)_fdb).DbColName("PATH") + "='" + fi.FullName + "'"; } else { qfilter.WhereClause = "PATH='" + fi.FullName + "'"; } IFeatureCursor cursor = ((SqlFDB)fdb).Query(rasterFC, qfilter); if (cursor != null) { IFeature feat = cursor.NextFeature; if (feat != null) { InsertImageDatasetBitmap(feat.OID, rasterLayer, _levels, format); } cursor.Dispose(); } } Console.WriteLine(">" + fi.FullName + " added..."); } rFileDataset.Dispose(); return(true); }
private float GetElevationAtPoint(RasterFileDictionary adjacentTiles, FileMetadata metadata, double lat, double lon, float lastElevation, IInterpolator interpolator) { float heightValue = 0; try { IRasterFile mainRaster = adjacentTiles[metadata]; //const double epsilon = (Double.Epsilon * 100); float noData = metadata.NoDataValueFloat; // precise position on the grid (with commas) double ypos = (lat - metadata.StartLat) / metadata.pixelSizeY; double xpos = (lon - metadata.StartLon) / metadata.pixelSizeX; // If pure integers, then it's on the grid float xInterpolationAmount = (float)xpos % 1; float yInterpolationAmount = (float)ypos % 1; bool xOnGrid = Math.Abs(xInterpolationAmount) < float.Epsilon; bool yOnGrid = Math.Abs(yInterpolationAmount) < float.Epsilon; // If xOnGrid and yOnGrid, we are on a grid intersection, and that's all if (xOnGrid && yOnGrid) { int x = (int)Math.Round(xpos, 0); int y = (int)Math.Round(ypos, 0); var tile = FindTile(metadata, adjacentTiles, x, y, out x, out y); heightValue = mainRaster.GetElevationAtPoint(tile, x, y); } else { int xCeiling = (int)Math.Ceiling(xpos); int xFloor = (int)Math.Floor(xpos); int yCeiling = (int)Math.Ceiling(ypos); int yFloor = (int)Math.Floor(ypos); // Get 4 grid nearest points (DEM grid corners) // If not yOnGrid and not xOnGrid we are on grid horizontal line // We need elevations for top, bottom, left and right grid points (along x axis and y axis) float northWest = GetElevationAtPoint(metadata, adjacentTiles, xFloor, yFloor, NO_DATA_OUT); float northEast = GetElevationAtPoint(metadata, adjacentTiles, xCeiling, yFloor, NO_DATA_OUT); float southWest = GetElevationAtPoint(metadata, adjacentTiles, xFloor, yCeiling, NO_DATA_OUT); float southEast = GetElevationAtPoint(metadata, adjacentTiles, xCeiling, yCeiling, NO_DATA_OUT); float avgHeight = GetAverageExceptForNoDataValue(noData, NO_DATA_OUT, southWest, southEast, northWest, northEast); if (northWest == noData) { northWest = avgHeight; } if (northEast == noData) { northEast = avgHeight; } if (southWest == noData) { southWest = avgHeight; } if (southEast == noData) { southEast = avgHeight; } heightValue = interpolator.Interpolate(southWest, southEast, northWest, northEast, xInterpolationAmount, yInterpolationAmount); } if (heightValue == NO_DATA_OUT) { heightValue = lastElevation; } } catch (Exception e) { _logger?.LogError(e, $"Error while getting elevation data : {e.Message}{Environment.NewLine}{e.ToString()}"); } return(heightValue); }
public float GetPointsElevation(IRasterFile raster, FileMetadata metadata, IEnumerable <GeoPoint> points, IInterpolator interpolator = null) { float heightValue = 0; try { if (interpolator == null) { interpolator = GetInterpolator(InterpolationMode.Bilinear); } float noData = metadata.NoDataValueFloat; foreach (var pointsByLat in points.GroupBy(p => p.Latitude)) { double lat = pointsByLat.Key; double ypos = (lat - metadata.StartLat) / metadata.pixelSizeY; foreach (GeoPoint point in pointsByLat) { // precise position on the grid (with commas) double lon = point.Longitude; double xpos = (lon - metadata.StartLon) / metadata.pixelSizeX; // If pure integers, then it's on the grid float xInterpolationAmount = (float)xpos % 1; float yInterpolationAmount = (float)ypos % 1; bool xOnGrid = Math.Abs(xInterpolationAmount) < float.Epsilon; bool yOnGrid = Math.Abs(yInterpolationAmount) < float.Epsilon; // If xOnGrid and yOnGrid, we are on a grid intersection, and that's all if (xOnGrid && yOnGrid) { int x = (int)Math.Round(xpos, 0); int y = (int)Math.Round(ypos, 0); heightValue = raster.GetElevationAtPoint(metadata, x, y); } else { int xCeiling = (int)Math.Ceiling(xpos); int xFloor = (int)Math.Floor(xpos); int yCeiling = (int)Math.Ceiling(ypos); int yFloor = (int)Math.Floor(ypos); // Get 4 grid nearest points (DEM grid corners) // If not yOnGrid and not xOnGrid we are on grid horizontal line // We need elevations for top, bottom, left and right grid points (along x axis and y axis) float northWest = raster.GetElevationAtPoint(metadata, xFloor, yFloor); float northEast = raster.GetElevationAtPoint(metadata, xCeiling, yFloor); float southWest = raster.GetElevationAtPoint(metadata, xFloor, yCeiling); float southEast = raster.GetElevationAtPoint(metadata, xCeiling, yCeiling); float avgHeight = GetAverageExceptForNoDataValue(noData, NO_DATA_OUT, southWest, southEast, northWest, northEast); if (Math.Abs(northWest - noData) < float.Epsilon) { northWest = avgHeight; } if (Math.Abs(northEast - noData) < float.Epsilon) { northEast = avgHeight; } if (Math.Abs(southWest - noData) < float.Epsilon) { southWest = avgHeight; } if (Math.Abs(southEast - noData) < float.Epsilon) { southEast = avgHeight; } heightValue = interpolator.Interpolate(southWest, southEast, northWest, northEast, xInterpolationAmount, yInterpolationAmount); } point.Elevation = heightValue; } } } catch (Exception e) { _logger?.LogError(e, $"Error while getting elevation data : {e.Message}{Environment.NewLine}{e.ToString()}"); } return(heightValue); }