cpp
#include <geotiff.h>
#include <geotiffio.h>
#include <tiffio.h>
#include <iostream>
#include <xtiffio.h>
void MyTIFFErrorHandler(const char* module, const char* fmt, va_list args) {
// 格式化错误消息
char buffer[1024];
vsnprintf(buffer, sizeof(buffer), fmt, args);
// 输出到标准错误(或日志文件)
std::cerr << "[TIFF ERROR] Module: " << (module ? module : "unknown")
<< ", Message: " << buffer << std::endl;
}
void ReadFloatTifGrid(const char *file) {
TIFFErrorHandler oldHandler = TIFFSetErrorHandler(MyTIFFErrorHandler);
TIFF *tif = NULL;
GTIF *gtif = NULL;
tif = XTIFFOpen(file, "r");
if (!tif) {
return ;
}
gtif = GTIFNew(tif);
if (!gtif) {
XTIFFClose(tif);
return ;
}
unsigned short sampleFormat, samplesPerPixel, bitsPerSample;
TIFFGetField(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesPerPixel);// 1: 无符号整数,2: 有符号整数,3: 浮点
TIFFGetField(tif, TIFFTAG_BITSPERSAMPLE, &bitsPerSample);
TIFFGetField(tif, TIFFTAG_SAMPLEFORMAT, &sampleFormat);
if (sampleFormat != SAMPLEFORMAT_IEEEFP || bitsPerSample != 32 || samplesPerPixel != 1) {
GTIFFree(gtif);
XTIFFClose(tif);
return ;
}
int width, height;
TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
short tiepointsize, pixscalesize;
double* tiepoints;//[6];
double* pixscale;//[3];
TIFFGetField(tif, TIFFTAG_GEOTIEPOINTS, &tiepointsize,
&tiepoints);
TIFFGetField(tif, TIFFTAG_GEOPIXELSCALE, &pixscalesize,
&pixscale);
float data1[30000] = {0};
auto cellSize = pixscale[0];
auto top = tiepoints[4];
auto left = tiepoints[3];
auto bottom = tiepoints[4]-(pixscale[1] * float(height));
auto right = tiepoints[3]+(pixscale[0] * float(width));
if (TIFFIsTiled(tif)) {
// 处理分块图像
uint32_t tileWidth, tileHeight;
TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tileWidth);
TIFFGetField(tif, TIFFTAG_TILELENGTH, &tileHeight);
int a=TIFFTileSize(tif);
unsigned char* buf = (unsigned char*)_TIFFmalloc(TIFFTileSize(tif));
for (uint32_t y = 0; y < height; y += tileHeight) {
for (uint32_t x = 0; x < width; x += tileWidth) {
TIFFReadTile(tif, buf, x, y, 0, 0);
if(y>=3437&&x>18042)
{
int a=0;
}
if (bitsPerSample == 32) {
float* floatData = (float*)buf;//高度
int a=0;
// 处理32位浮点数据...
} else if (bitsPerSample == 64) {
double* doubleData = (double*)buf;
int a=0;
// 处理64位浮点数据...
}
else if (bitsPerSample == 16) {
uint16_t* shortData = (uint16_t*)buf;
}
}
}
_TIFFfree(buf);
}
else {
for (long i = 0; i < height; i++) {
if (TIFFReadScanline(tif, data1, (unsigned int)i, 0) == -1) {
GTIFFree(gtif);
XTIFFClose(tif);
return ;
}
if(i>3000)
{
float sss=data1[17000];
int a=0;
}
}
}
GTIFFree(gtif);
XTIFFClose(tif);
}
int main(int argc, char *argv[]) {
ReadFloatTifGrid("ETOPO_2022_v1_60s_N90W180_surface.tif");
}
全球高程tif从https://www.ncei.noaa.gov/products/etopo-global-relief-model下载
自己编译tiff库要开启zlib,后续补充一个经纬度到xy的映射