1

I'm trying to read a GeoTIFF with one band which stores a value between 0 and 3 ( 255 is no maks ). My Goal is to write a little program which takes in a latitude/longitude and returns the fitting pixel value at the geocoordinate in the geotiff.

I downloaded it from here : https://dataverse.harvard.edu/dataset.xhtml?persistentId=doi:10.7910/DVN/QQHCIK And if you wanna take a look at it... heres the download link. https://drive.google.com/file/d/104De_YQN1V8tSbj2uhIPO0FfowjnInnX/view?usp=sharing

However, my code does not work. It just outputs the wrong pixel value for a set of geocoordinates every single time. I guess either my geocordinate to pixel transformation is wrong or theres a huge logic mistake.

This was my first try, it prints the wrong value for the geo-coordinate. Furthermore it crashes with some geocoordinates, a negative longitude makes it crashes because this will make pixelY negative which causes an exception in the raster method.

            GdalConfiguration.ConfigureGdal();
            var tif = "C:\\Users\\Lars\\Downloads\\pnv_biome.type_biome00k_c_1km_s0..0cm_2000..2017_v0.1.tif";
            var lat = 51.0;
            var lon = 8.3;
            using (var image = Gdal.Open(tif, Access.GA_ReadOnly)) {

                var bOneBand = image.GetRasterBand(1);
                var width = bOneBand.XSize;
                var height = bOneBand.YSize;
                
                // Geocoordinate ( lat, lon ) to pixel in the tiff ? 
                var geoTransform = new double[6];
                image.GetGeoTransform(geoTransform);
                Gdal.InvGeoTransform(geoTransform, geoTransform);
                
                var bOne = new int[1];
                Gdal.ApplyGeoTransform(geoTransform, lat, lon, out var pixelXF, out var pixelYF);

                var pixelX = (int)Math.Floor(pixelXF);
                var pixelY = (int)Math.Floor(pixelYF);
                
                // Read pixel 
                bOneBand.ReadRaster(pixelX, pixelY, 1, 1, bOne, 1, 1,0,0);
                Console.WriteLine(bOne[0]); // bOne[0] contains wrong data
            }

My second attempt looks like the following... but also outputs the wrong pixel value for the given coordinates.

GdalConfiguration.ConfigureGdal();
            var tif = "C:\\Users\\Lars\\Downloads\\pnv_biome.type_biome00k_c_1km_s0..0cm_2000..2017_v0.1.tif";
            var lat = 24.7377; // 131.5847
            var lon = 131.5847;
            
            using (var image = Gdal.Open(tif, Access.GA_ReadOnly)) {

                var bOneBand = image.GetRasterBand(1);
                var bOne = new int[1];
                
                // Spatial reference to transform latlng to map coordinates... from python code
                var point_srs = new SpatialReference("");
                var file_srs = new SpatialReference(image.GetProjection());
                point_srs.ImportFromEPSG(4326);
                point_srs.SetAxisMappingStrategy(AxisMappingStrategy.OAMS_TRADITIONAL_GIS_ORDER);
           
                var mapCoordinates = new double[2]{ lat, lon};
                var transform = new CoordinateTransformation(point_srs, file_srs);
                transform.TransformPoint(mapCoordinates);
                
                // Map coordinates to pixel coordinates ? 
                var geoTransform = new double[6];
                image.GetGeoTransform(geoTransform);
                Gdal.InvGeoTransform(geoTransform, geoTransform);
                
                Gdal.ApplyGeoTransform(geoTransform, mapCoordinates[0], mapCoordinates[1], out var pixelXF, out var pixelYF);
                var pixelX = (int)pixelXF;
                var pixelY = (int)pixelYF;
                
                bOneBand.ReadRaster(pixelX, pixelY, 1, 1, bOne, 1, 1, 0,0);
                Console.WriteLine(bOne[0]);  // bOne[0] contains wrong value
            }

Does anyone here have experience on that topic?

I simple cannot fix it after hours of searching and looking at examples.

1
  • As per the help center please do not include chit chat like statements of appreciation within your posts.
    – PolyGeo
    May 19, 2022 at 22:08

1 Answer 1

2

Such a program "gdallocationinfo" exists already and it is one of the standard GDAL utilities. The usage is documented in https://gdal.org/programs/gdallocationinfo.html and the source code is here https://github.com/OSGeo/gdal/blob/master/apps/gdallocationinfo.cpp. You would probably use the -wgs84 option

Description

The gdallocationinfo utility provide a mechanism to query information about a pixel given its location in one of a variety of coordinate systems. Several reporting options are provided.

...

-wgs84

Indicates input x,y points are WGS84 long, lat.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.