复杂的TIFF图像格式?GeoTIFF如何突破存储读取地理信息难题

为了精准存储地理信息,为了避免出现各类问题,GeoTiff构建了独特的存储机制,该存储机制的空间体系有独特之处,这项技术值得我们深入探究。

Keys存储机制

GeoTiff通过一系列Keys来获取地理信息,这些键起到类似标签的作用,只是在TIFF上有了更高的抽象层级,对于我们常见的数据存储需求,普通标签难以精准满足地理信息存储的要求,然而GeoTiff的Keys却能很好地解决这个问题。所有键都拥有ID号,ID号的范围是从0至65535,和标签不一样,所有键的ID号都能够用来定义GeoTiff参数,这极大地拓展了参数定义的空间。

每个Key的ID都有着不一样的地理参数含义,它如同钥匙一般,能够打开地理信息存储与查询的大门,这种ID号的使用方式十分灵活,这让GeoTiff在处理复杂地理信息时更加顺利,无论是空间坐标,还是特定地理属性,都可以凭借键的ID号实现精准定位与存储。

Geo Key Directory Tag索引

所有的键都被称作GeoKeys,这些键由Geo Key Directory Tag标签索引,这个标签就像地理信息键的目录,依靠它,我们能够快速找到所需的GeoKey,信息查找的效率得到了极大提高。

在一个大型地理信息数据库里,若我们想查找特定区域的地理参数,借助索引标签,就能迅速定位到相关的GeoKeys,它如同图书馆的索引目录,可让我们管理海量地理信息更有条理,也能让我们使用海量地理信息更有条理。

TIFF Tag Location含义

TIFF Tag Location确定了存放值的tag,当这个tag的值为0时,意味着值是SHORT类型,并且包含在Value_Offset元素里,这为准确读取GeoKey的值给出了规则,这规则就如同交通规则保障信息在存储与读取过程中的有序性 。

在实际进行存储操作的时候,如果严格依照这个规则,那么就能够防止信息出现混乱的情况。举例来说,在处理复杂的地理项目时,会涉及到众多GeoKey值的读取工作,要是有TIFF Tag Location进行指引,那么就可以保证每个值都能够被精确地读取并且得到运用。

GeoDoubleParamsTag作用

GeoDoubleParamsTag用来存放DOUBLE型的GeoKeys,它会被GeoKeyDirectoryTag引用,double数组中每个值的意义,是由指向它的GeoKeyDirectoryTag引用来确定的 。

存储对精度要求较高的地理数据时,DOUBLE型的GeoKeys是必不可少的。例如在进行高精度地图绘制时,需借助GeoDoubleParamsTag存储精确数据。又如进行地理模拟时,同样要依靠GeoDoubleParamsTag存储精确数据。还要利用它管理这些精确数据,以此保证地理信息的准确性。

坐标系存储特点

Geotiff可以将标准地图坐标系定义,以单一注册标签的形式随意存储,它还支持对非标准坐标系进行描述,其具有的这种灵活性,能让它在面对各种不同的地理项目时,都可以应对自如。

在不同的地理区域,坐标系可能会不一样,GeoTiff能很好地处理这些情况。如果要在不同坐标系之间转换,借助另外设置的三四个TIFF标签就能实现,既便捷又高效。

三种空间体系

在TIFF/GeoTIFF框架下,存在三种用于坐标系定义的空间,这三种空间分别是光栅空间R、设备空间以及模型空间M,光栅空间R和标准TIFF6.0里的光栅存在关联,它和设备空间有一定的联系,像显示器、扫描仪或打印机等设备的操作,都涉及到这部分空间。

模型空间M能够用来表示地球上的点,其在地理信息处理里作用颇为重要。不同的空间体系为地理信息的多维度表达给予了支持,依靠这些支持我们可以从不同角度处理地理信息,也能够从不同层面分析地理信息。

#include "geotiffio.h"
#include "xtiffio.h"
#include 
void SetUpTIFFDirectory(TIFF *tif);
void SetUpGeoKeys(GTIF *gtif);
void WriteImage(TIFF *tif);
#define WIDTH 20L
#define HEIGHT 20L
void main()
{
        char *fname = "newgeo.tif";
        TIFF *tif=(TIFF*)0;  
        GTIF *gtif=(GTIF*)0;
        tif=XTIFFOpen(fname,"w");
        if (!tif) goto failure;
        gtif = GTIFNew(tif);
        if (!gtif)
        {
               printf("failed in GTIFNewn");
               goto failure;
        }
        SetUpTIFFDirectory(tif);
        SetUpGeoKeys(gtif);
        WriteImage(tif);
        GTIFWriteKeys(gtif);
        GTIFFree(gtif);
        XTIFFClose(tif);
        exit (0);
failure:
        printf("failure in makegeon");
        if (tif) TIFFClose(tif);
        if (gtif) GTIFFree(gtif);
        exit (-1);
}
void SetUpTIFFDirectory(TIFF *tif)
{
        double tiepoints[6]={0,0,0,130.0,32.0,0.0};
        double pixscale[3]={1,1,0};
        TIFFSetField(tif,TIFFTAG_IMAGEWIDTH,     WIDTH);
        TIFFSetField(tif,TIFFTAG_IMAGELENGTH,    HEIGHT);
        TIFFSetField(tif,TIFFTAG_COMPRESSION,    COMPRESSION_NONE);
        TIFFSetField(tif,TIFFTAG_PHOTOMETRIC,    PHOTOMETRIC_MINISBLACK);
        TIFFSetField(tif,TIFFTAG_PLANARCONFIG,   PLANARCONFIG_CONTIG);
        TIFFSetField(tif,TIFFTAG_BITSPERSAMPLE, 8);
        TIFFSetField(tif,TIFFTAG_ROWSPERSTRIP,   20L);
        TIFFSetField(tif,TIFFTAG_GEOTIEPOINTS, 6,tiepoints);
        TIFFSetField(tif,TIFFTAG_GEOPIXELSCALE, 3,pixscale);
}
void SetUpGeoKeys(GTIF *gtif)
{
        GTIFKeySet(gtif, GTModelTypeGeoKey, TYPE_SHORT, 1, ModelGeographic);
        GTIFKeySet(gtif, GTRasterTypeGeoKey, TYPE_SHORT, 1, RasterPixelIsArea);
        GTIFKeySet(gtif, GTCitationGeoKey, TYPE_ASCII, 0, "Just An Example");
        GTIFKeySet(gtif, GeographicTypeGeoKey, TYPE_SHORT,   1, KvUserDefined);
        GTIFKeySet(gtif, GeogCitationGeoKey, TYPE_ASCII, 0, "Everest Ellipsoid Used.");
        GTIFKeySet(gtif, GeogAngularUnitsGeoKey, TYPE_SHORT,   1, Angular_Degree);
        GTIFKeySet(gtif, GeogLinearUnitsGeoKey, TYPE_SHORT,   1, Linear_Meter);
        GTIFKeySet(gtif, GeogGeodeticDatumGeoKey, TYPE_SHORT,      1, KvUserDefined);
        GTIFKeySet(gtif, GeogEllipsoidGeoKey, TYPE_SHORT,      1, Ellipse_Everest_1830_1967_Definition);
        GTIFKeySet(gtif, GeogSemiMajorAxisGeoKey, TYPE_DOUBLE, 1, (double)6377298.556);
        GTIFKeySet(gtif, GeogInvFlatteningGeoKey, TYPE_DOUBLE, 1, (double)300.8017);
}
void WriteImage(TIFF *tif)
{
        int i;
        char buffer[WIDTH];
        memset(buffer,0,(size_t)WIDTH);
        for (i=0;i<HEIGHT;i++)
               if (!TIFFWriteScanline(tif, buffer, i, 0))
                      TIFFError("WriteImage","failure in WriteScanlinen");
}

大家在实际处理地理信息时,是否遇到过因坐标系转换而受困扰的情况?快来评论区分享经历,别忘了点赞,还要分享这篇文章!

发表评论