title: GeoTIFF libtiff.net get elevation data in c#
body: <p>I am trying to use libtiff.net to read elevation data from a GeoTIFF file.
  So far I have mostly just been able to read metadata from the file using the example at libtiff.net's webpage.</p>
  
  <p>But howto read elevation data I do not understand... I tried first reading with <code>Tiff.ReadScanline()</code> as described <a href="http://build-failed.blogspot.dk/2014/12/processing-geotiff-files-in-net-without.html" rel="nofollow noreferrer">here</a> but the file I have seems to be stored differently (probably in tiles if I understand it correctly)</p>
  
  <p>Here is the metadata (as far as I have been able to read) (the tiff file is from the danish terrain elevation data set):</p>
  
  <blockquote>
    <p>Tiff c:\Users***\DTM_1km_6170_500.tif, page 0 has following tags set:</p>
    
    <p>IMAGEWIDTH System.Int32 : 2500</p>
    
    <p>IMAGELENGTH System.Int32 : 2500</p>
    
    <p>BITSPERSAMPLE System.Int16 : 32</p>
    
    <p>COMPRESSION BitMiracle.LibTiff.Classic.Compression : ADOBE_DEFLATE</p>
    
    <p>PHOTOMETRIC BitMiracle.LibTiff.Classic.Photometric : MINISBLACK</p>
    
    <p>STRIPOFFSETS System.UInt64[] : System.UInt64[]</p>
    
    <p>SAMPLESPERPIXEL System.Int16 : 1</p>
    
    <p>STRIPBYTECOUNTS System.UInt64[] : System.UInt64[]</p>
    
    <p>PLANARCONFIG BitMiracle.LibTiff.Classic.PlanarConfig : CONTIG</p>
    
    <p>PREDICTOR BitMiracle.LibTiff.Classic.Predictor : FLOATINGPOINT</p>
    
    <p>TILEWIDTH System.Int32 : 256</p>
    
    <p>TILELENGTH System.Int32 : 256</p>
    
    <p>TILEOFFSETS System.UInt64[] : System.UInt64[]</p>
    
    <p>TILEBYTECOUNTS System.UInt64[] : System.UInt64[]</p>
    
    <p>SAMPLEFORMAT BitMiracle.LibTiff.Classic.SampleFormat : IEEEFP</p>
    
    <p>DATATYPE System.Int16 : 3</p>
    
    <p>GEOTIFF_MODELPIXELSCALETAG System.Int32 : 3 GEOTIFF_MODELPIXELSCALETAG
    System.Byte[] : Ù?Ù?        </p>
    
    <p>GEOTIFF_MODELTIEPOINTTAG System.Int32 : 6 GEOTIFF_MODELTIEPOINTTAG
    System.Byte[] :                             A    ^WA        </p>
    
    <p>34735 System.Int32 : 36 34735 System.Byte[] :              
    ±   ±     #°       èd   )#</p>
    
    <p>34736 System.Int32 : 3 34736 System.Byte[] :                         </p>
    
    <p>34737 System.Int32 : 30 34737 System.Byte[] : ETRS89 / UTM zone
    32N|ETRS89| </p>
    
    <p>42113 System.Int32 : 6 42113 System.Byte[] : -9999</p>
  </blockquote>
  
  <p>The code I have written so far is as follows:</p>
  
  <pre><code>namespace GeoTIFFReader
  {
    public class GeoTIFF
    {
      private double[,] heightmap;
      private double dx;
      private double dy;
      private double startx;
      private double starty;
  
  
      public GeoTIFF(string fn)
      {
        using (Tiff tiff = Tiff.Open(fn, "r"))
        {
          if (tiff == null)
          {
            // Error - could not open
            return;
          }
  
  
  
          int width = tiff.GetField(TiffTag.IMAGEWIDTH)[0].ToInt();
          int height = tiff.GetField(TiffTag.IMAGELENGTH)[0].ToInt();
          heightmap = new double[width, height];
          FieldValue[] modelPixelScaleTag = tiff.GetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG);
          FieldValue[] modelTiePointTag = tiff.GetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG);
  
          byte[] modelPixelScale = modelPixelScaleTag[1].GetBytes();
          dx = BitConverter.ToDouble(modelPixelScale, 0);
          dy = BitConverter.ToDouble(modelPixelScale, 8) * -1;
  
          byte[] modelTransformation = modelTiePointTag[1].GetBytes();
          double originLon = BitConverter.ToDouble(modelTransformation, 24);
          double originLat = BitConverter.ToDouble(modelTransformation, 32);
  
          startx = originLon + dx / 2.0;
          starty = originLat + dy / 2.0;
  
          double curx = startx;
          double cury = starty;
  
          FieldValue[] bitsPerSampleTag = tiff.GetField(TiffTag.BITSPERSAMPLE);
  
          FieldValue[] tilewtag = tiff.GetField(TiffTag.TILEWIDTH);
          FieldValue[] tilehtag = tiff.GetField(TiffTag.TILELENGTH);
          int tilew = tilewtag[0].ToInt();
          int tileh = tilehtag[0].ToInt();
  
          var tile = new byte[tilew*tileh];
  
          //var scanline = new byte[tiff.ScanlineSize()]; Does not work... wrong format
          for (int il = 0; il &lt; height; il++)
          {
            //tiff.ReadScanline(scanline, il); // Load il'th line of data 
            for (int ir = 0; ir &lt; width; ir++)
            {
  
              // Here I would like to read each pixel data that contains elevation in gray-scale in f32 as far I as I understand from metadata
  
              //object value = scanline[ir];
              //heightmap[ir, il] = double.Parse(value.ToString());
            }
          }
  
          Console.WriteLine(heightmap.ToString());
        }
  
      }
    }
  }
  </code></pre>
  
  <p>So if anyone knows howto extract this data, that would be very much appreciated.</p>