How to read GeoTIFF file from C#

20,735

Solution 1

There are some SDKs out there usable from C# to read GeoTIFF files:

UPDATE:

The spec for GeoTIFF can be found here - to me it seems that GeoTIFFs can contain different "subtypes" of information which in turn need to be interpreted appropriately...

Solution 2

Here's a guy that did it without GDAL: http://build-failed.blogspot.com.au/2014/12/processing-geotiff-files-in-net-without.html

GDAL is available in NuGet, though.

Solution 3

If the GeoTIFF contains tiles, you need a different approach. This is how to read a GeoTiff that contains 32bit floats with height data:

  int buffersize = 1000000;
  using (Tiff tiff = Tiff.Open(geotifffile, "r"))
  {
    int nooftiles = tiff.GetField(TiffTag.TILEBYTECOUNTS).Length;
    int width = tiff.GetField(TiffTag.TILEWIDTH)[0].ToInt();
    int height = tiff.GetField(TiffTag.TILELENGTH)[0].ToInt();
    byte[] buffer = new byte[buffersize];

    for (int i = 0; i < nooftiles; i++)
    {
      int size = tiff.ReadEncodedTile(i, buffer, 0, buffersize);
      float[,] data = new float[width, height];
      Buffer.BlockCopy(buffer, 0, data, 0, size); // Convert byte array to x,y array of floats (height data)
      // Do whatever you want with the height data (calculate hillshade images etc.)
    }
  }
Share:
20,735
Moon
Author by

Moon

Updated on June 16, 2021

Comments

  • Moon
    Moon almost 3 years

    I have acquired Digital Elevation Maps(Height Map of Earth) of some area. My aim was to create Realistic Terrains.

    Terrain Generation is no problem. I have practiced that using VC# & XNA framework.

    The problem is that those Height Map Files are in GeoTIFF format which i don't know how to read. Nor do i have previous experience with reading any image files so that i could experiment something using little tips-bits available on internet about reading GeoTIFF files. So far i have been unsuccessful.

    • The geoTIFF files I have are 3601 x 3601 files.
    • Each file has two version, a decimal & num valued files.
    • Each file has data of every second of longitude & latitude of Geo-Coords along with Height Map i.e Lon, Lat, height from sea level

    How to read these file :)

    The files I have are from ASTER G-DEM Version-2 LINK TO OFFICIAL DESCRIPTION according to them GeoTIFF is pretty standard which is because some GeoTIFF Visualizers I dwonloaded are showing me the correct data.

    I am gonna be using C#. I would appreciate if we talk in relation to this language.


    E D I T

    okay i got the libtiff and this what i have done,

    using (Tiff tiff = Tiff.Open(@"Test\N41E071_dem.tif", r))
    {
      int width   = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
      int height  = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
      double dpiX = tiff.GetField(TiffTag.XRESOLUTION)[0].ToDouble();
      double dpiY = tiff.GetField(TiffTag.YRESOLUTION)[0].ToDouble(); 
    
      byte[] scanline        = new byte[tiff.ScanlineSize()]; 
      ushort[] scanline16Bit = new ushort[tiff.ScanlineSize() / 2];
    
      for (int i = 0; i < height; i++)
      {
        tiff.ReadScanline(scanline, i); //Loading ith Line                        
        MultiplyScanLineAs16BitSamples(scanline, scanline16Bit, 16,i);
      }
    }
    
    private static void MultiplyScanLineAs16BitSamples(byte[] scanline, ushort[] temp, ushort factor,int row)
    {
      if (scanline.Length % 2 != 0)
      {
        // each two bytes define one sample so there should be even number of bytes
        throw new ArgumentException();
      }
      
      Buffer.BlockCopy(scanline, 0,   temp, 0, scanline.Length);
    
      for (int i = 0; i < temp.Length; i++)
      {                
        temp[i] *= factor;
        MessageBox.Show("Row:"+row.ToString()+"Column:"+(i/2).ToString()+"Value:"+temp[i].ToString());
      }
    }
    

    where i am displaying the message box, i am displaying the corresponding values, Am i doing it Right, i am asking this cuz this is my maiden experience with images & 8\16 bit problem. I think unlike the official tutorials of libtiff i should be using short instead of ushort because the images i am using are "GeoTIFF, signed 16 bits"