Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create Geotiff using "LibTiff.Net", and add geographic information

I'm trying to create a geotiff (elevation DEM data) file by using Libtiff.Net.
The problem is that I have never succeeded to add the following two tags:

TiffTag.GEOTIFF_MODELTIEPOINTTAG
TiffTag.GEOTIFF_MODELPIXELSCALETA

To add the tag, I wrote the code as follows:

tiff.SetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG, 0.0, 0.0, 0.0, leftTopX, leftTopY, 0.0);
tiff.SetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG, pixelScaleX, pixelScaleY, 0.0);

According to the description for the "SetField" method, the method returns "true" if the tag value was set successfully.
However, in my case, the method never returns when trying to add the above 2 tags.
(Other tags can be added without any problem.)

I already confirmed that the created geotiff does not contain the geographic information, by using other GIS softwares, such as ArcGIS.

Am I missing something or did something wrong?
Any hints or answers will be appreciated!


For your convenience, the code I write so far is the following:
public void WriteTiff()
{
   using (var tiff = Tiff.Open("C:\\test\\newCreated.tif", "w"))
   {
       if (tiff == null)
           return;

       int width = 100;
       int height = 100;
       int byteDepth = 4;
       int tileSize = 64;

       //Geo info to add
       double leftTopX = 10000;
       double leftTopY = 15000;
       double pixelScaleX = 1;
       double pixelScaleY = 1;

       //Set the basic tags
       tiff.SetField(TiffTag.IMAGEWIDTH, width);
       tiff.SetField(TiffTag.IMAGELENGTH, height);
       tiff.SetField(TiffTag.SAMPLESPERPIXEL, 1);
       tiff.SetField(TiffTag.BITSPERSAMPLE, 8 * byteDepth);
       tiff.SetField(TiffTag.ORIENTATION, Orientation.TOPLEFT);
       tiff.SetField(TiffTag.ROWSPERSTRIP, height);
       tiff.SetField(TiffTag.XRESOLUTION, 88);
       tiff.SetField(TiffTag.YRESOLUTION, 88);
       tiff.SetField(TiffTag.RESOLUTIONUNIT, ResUnit.INCH);
       tiff.SetField(TiffTag.PLANARCONFIG, PlanarConfig.CONTIG);
       tiff.SetField(TiffTag.PHOTOMETRIC, Photometric.MINISBLACK);
       tiff.SetField(TiffTag.COMPRESSION, Compression.NONE);
       tiff.SetField(TiffTag.FILLORDER, FillOrder.MSB2LSB);
       tiff.SetField(TiffTag.SOFTWARE, "MyLib");
       tiff.SetField(TiffTag.SAMPLEFORMAT, SampleFormat.IEEEFP);

       //Set the size of the tile
       tiff.SetField(TiffTag.TILEWIDTH, tileSize);
       tiff.SetField(TiffTag.TILELENGTH, tileSize);

       //set the geographics info
       //The following two lines never succeeded....
       tiff.SetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG, 0.0, 0.0, 0.0, leftTopX, leftTopY, 0.0);
       tiff.SetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG, pixelScaleX, pixelScaleY, 0.0);

       //Write the tile data here
       //........
       //
   }
}
like image 544
Nazonokaijin Avatar asked Sep 21 '18 07:09

Nazonokaijin


2 Answers

I could finally add the geographic information to my tiff image as follows:

  1. Define a method for "Tiff.TagExtender" method.

    public void TagExtender(Tiff tiff)
    {
        TiffFieldInfo[] tiffFieldInfo = 
        {
            new TiffFieldInfo(TiffTag.GEOTIFF_MODELTIEPOINTTAG, 6, 6, TiffType.DOUBLE, FieldBit.Custom, false, true, "MODELTILEPOINTTAG"),
            new TiffFieldInfo(TiffTag.GEOTIFF_MODELPIXELSCALETAG, 3, 3, TiffType.DOUBLE, FieldBit.Custom, false, true, "MODELPIXELSCALETAG")
        };
    
        tiff.MergeFieldInfo(tiffFieldInfo, tiffFieldInfo.Length);
    }
    
  2. Set the tag extender method which is defined in #1.
    Note: This method must be called "BEFORE" opening or creating the tiff image to take effect.

    Tiff.SetTagExtender(TagExtender);
    
  3. Open the tiff image:

    this.tiff = Tiff.Open(fileName, "w");
    
  4. Add the tag (+required basic tags) :
    The tricky part is that the values (Array of double) must cast to object.
    Otherwise, there is a possibility that the "SetField" method throws an exception.

    double[] tiePoints = new double[] { 0, 0, 0, this.TopLeftX, this.TopLeftY, 0 };
    this.tiff.SetField(TiffTag.GEOTIFF_MODELTIEPOINTTAG, 6, (object)tiePoints);
    double[] pixelScale = new double[] { this.PixelScaleX, this.PixelScaleY, 0 };
    this.tiff.SetField(TiffTag.GEOTIFF_MODELPIXELSCALETAG, 3, (object)pixelScale);
    
  5. Do something related to the pixel values.

  6. Done!

like image 63
Nazonokaijin Avatar answered Oct 22 '22 23:10

Nazonokaijin


LibTiff.Net is not able to write TiffTag.GEOTIFF_MODELTIEPOINTTAG and TiffTag.GEOTIFF_MODELPIXELSCALETAG out of the box. All the tags the library can write out of the box are listed in Tiff_DirInfo.cs file.

The SetField method returns false when you try to write unknown tag. The library also emits an error message to console.

You can teach the library how to write these GEOTIFF tags by using a code similar to one in this sample

Add custom TIFF tags to an existing TIFF image

like image 32
Bobrovsky Avatar answered Oct 23 '22 00:10

Bobrovsky