예제 #1
0
파일: RasterTests.cs 프로젝트: zy6p/DEM.Net
        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, ".");
            }

            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);

                float elevation = raster.GetElevationAtPoint(metaData, 300, 10);
                Assert.Equal(751f, elevation);

                elevation = raster.GetElevationAtPoint(metaData, 10, 300);
                Assert.Equal(297f, elevation);
            }
        }
예제 #2
0
파일: RasterTests.cs 프로젝트: zy6p/DEM.Net
        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);
            }
        }
예제 #3
0
        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, ".", 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);

                Assert.Throws <IndexOutOfRangeException>(() =>
                {
                    float elevation = raster.GetElevationAtPoint(metaData, 10000, 10000);
                });
                // Expect exception
            }
        }
예제 #4
0
        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);
        }
예제 #5
0
        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);
        }
예제 #6
0
        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);
        }