我有一个格式的ESRI ASCII文件:

ncols         5
nrows         4
xllcorner     0
yllcorner     0
cellsize      10
NODATA_value  -9999
25.4 26.1 27 28.6 27.7
25 26 26.4 27.9 27.4
25.1 25.8 26.8 28.6 27.6
27.5 28 27.7 30.6 28.3

而且我需要使用libtiff.net(或其等效的C++,libtiff或libgeotiff或GDAL或任何其他C#或C++库)将其转换为geotiff文件。

但是我根本不知道要设置什么字段,有很多字段,例如TIFFTAG_IMAGEWIDTHTIFFTAG_SAMPLESPERPIXELTIFFTAG_BITSPERSAMPLE我不知道它们是否相关。

给定上面的ESRI ASCII文件,如何使用libtiff.net或libtiff库创建geotiff文件?

我为什么要这样做?

在我的应用程序中,我有一个网格,并且必须将网格转换为栅格文件。我想直接从网格采样中创建这样的geotiff栅格文件,而不首先创建中间ASCII文件,因为与最终的geotiff输出文件相比,中间文件的大小很大。

我能想到的唯一方法是在获取网格上的网格点时使用libtiff.net直接操作geotiff文件。

怎么做,还是有更好的方法?

最佳答案

即使您计划不在应用程序中使用GDAL(稍后会对此进行更多介绍),也不会阻止您从ESRI ASCII GRID(gdal_translate -of "GTiff" in.asc out.tif)生成Geotiff,并检查所生成文件的TIFF标记(这些是必需的标记)从给定的网格生成一个geotiff)。

AsTiffTagViewer给出以下输出(similar to TiffTags utility output):

TagCode (Count DataType): Value  // my comments

ImageWidth (1 Short): 5    // ncols
ImageLength (1 Short): 4   // nrows
BitsPerSample (1 Short): 32
Compression (1 Short): Uncompressed
Photometric (1 Short): MinIsBlack
StripOffsets (1 Long): 260
SamplesPerPixel (1 Short): 1
RowsPerStrip (1 Short): 4    //nrows
StripByteCounts (1 Long): 80
PlanarConfig (1 Short): Contig
SampleFormat (1 Short): 3
33550 (3 Double):
33922 (6 Double):
42113 (6 ASCII): -9999    // NODATA_value

如您所见,有11个标准Tiff标签和3个非标准标签(但我们知道数据类型,更重要的是最后3个标签的维度366)。让我们确认一下,我们有2个GeoTiff标签和一个非标准GDAL专用标签。

Libgeotiff C库随listgeo实用程序一起分发,用于转储GeoTIFF元数据。输出:
Geotiff_Information:
   Version: 1
   Key_Revision: 1.0
   Tagged_Information:
      ModelTiepointTag (2,3):
         0                0                0
         0                40               0
      ModelPixelScaleTag (1,3):
         10               10               0
      End_Of_Tags.
   Keyed_Information:
      End_Of_Keys.
   End_Of_Geotiff.

Corner Coordinates:
Upper Left    (       0.000,      40.000)
Lower Left    (       0.000,       0.000)
Upper Right   (      50.000,      40.000)
Lower Right   (      50.000,       0.000)
Center        (      25.000,      20.000)

通过Tagged_Information的尺寸,我们可以识别以下2个标签。同样,由于网格是规则的(X和Y间距相等,并且没有偏斜的网格线),我们可以建立以下公式:
33550标签:
ModelPixelScaleTag = [ cellsize , cellsize , 0 ]
33922标签:
ModelTiepointTag = [ 0 , 0 , 0 , UpperLeftCorner_X , UpperLeftCorner_Y , 0]

    where
            UpperLeftCorner_X = xllcorner

            UpperLeftCorner_Y = yllcorner + cellsize * nrows

剩下最后一个标签42113。 geotiff格式没有用于nodata值的标准标签。 GDAL将频段nodata值存储在非标准TIFFTAG_GDAL_NODATA ASCII标记中(代码42113)。

最后,作为一个示例,我们可以使用Libgeotiff C库编写一个函数,该函数将网格的 header (ncols, nrows, cellsize, xllcorner, yllcorner)与Tiff标签相关联:
void SetUpTIFFDirectory(TIFF *tif)
{
    double tiepoints[6];
    double pixscale[3];

    double upperLeftCorner_X, upperLeftCorner_Y;

    upperLeftCorner_X = xllcorner;

    upperLeftCorner_Y = yllcorner + (cellsize*nrows);

    tiepoint[0] = 0.0;
    tiepoint[1] = 0.0;
    tiepoint[2] = 0.0;
    tiepoint[3] = upperLeftCorner_X;
    tiepoint[4] = upperLeftCorner_Y;
    tiepoint[5] = 0.0;

    pixscale[0] = cellsize;
    pixscale[1] = cellsize;
    pixscale[2] = 0.0;

    TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,    ncols);
    TIFFSetField(tif,TIFFTAG_IMAGELENGTH,   nrows);
    TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 32);
    TIFFSetField(tif,TIFFTAG_COMPRESSION,   COMPRESSION_NONE);
    TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,   PHOTOMETRIC_MINISBLACK);
    TIFFSetField(tif,TIFFTAG_STRIPOFFSETS,  260L);
    TIFFSetField(tif,TIFFTAG_SAMPLESPERPIXEL, 1);
    TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP, nrows;
    TIFFSetField(tif,TIFFTAG_STRIPBYTECOUNTS, 80L);
    TIFFSetField(tif,TIFFTAG_PLANARCONFIG,  PLANARCONFIG_CONTIG);
    TIFFSetField(tif,TIFFTAG_SAMPLEFORMAT,  3;

    TIFFSetField(tif,GTIFF_TIEPOINTS, 6,tiepoints);
    TIFFSetField(tif,GTIFF_PIXELSCALE, 3,pixscale);

}

注意:当您说不能使用GDAL时,有一种“内存中栅格”格式可以在添加网格样本时用作栅格的临时占位符:

https://www.gdal.org/frmt_mem.html

09-04 23:52