gdal坐标变换(x,y变经纬度)


gdal坐标变换

最近因为一些原因需要读取地理数据,我使用的工具是gdal,在处理数据的时候遇到一些小的问题,自己折腾了会儿,现在分享出来,避免大家浪费时间。

  • tiff, geotif和gdal都可以提取tiff数据,对于地理数据gdal可能更方便一些
    我使用了tiff,geotiff尝试提取过手头的tif数据,发现有一些tag是未定义的,会报warning,尽管也可以手工处理,但有些麻烦,gdal一般可以直接处理这类图像
  • gdal图像之后,如果需要进行坐标变换,还要安装proj4
    我在windows下进行安装使用,可能需要安装Visual Studio,linux下的安装更加简单。安装教程一搜一大把,这里略去。个人觉得在windows下可能不用安装VS,如果使用dev C++的话,gcc也可以搞定,但没有试过,就不多说了。下面着重讲一讲tif数据读取,获得相关地理信息,并做坐标变换的过程。

相关程序

#include"gdal_priv.h"
#include "ogrsf_frmts.h"
#include"gdal.h"
#include"ogr_srs_api.h"
#include"ogr_spatialref.h"
#include"ogr_api.h"
#include"proj_api.h"
#include<cstring>
#include<iostream>

int main(){
    /** 过程1:读取相关文件信息 **/
    /** 见下面过程1 **/

    /** 过程2: 进行坐标变换 **/
    /** 见下面过程2 **/
    return 0;
}

过程1包括读文件,获得图像和坐标基本信息,这里假设图像为”test.tif”,按理说每一步操作都应该判断是否成功,这里为了使结构更简单清晰,把这里略去了。

/** 过程1 **/
GDALDataset *poDataset;
GDALAllRegister();
poDataset = (GDALDataset *)GDALOpen("test.tif", GA_ReadOnly);

/** projRef将会存储test.tif中的坐标信息 **/
const char* projRef = poDataset->GetProjectionRef();
/** adfGeoTransform存储一些基准点的坐标和每一个pixel表示的长度等 **/
double adfGeoTransform[6];
poDataSet->GetGeoTransform(adfGeoTransform);

/** 下面获得波段信息 **/
GDALRasterBand *poBand;
poBand = poDataset->GetRasterBand(1);

int nXSize = poBand->GetXSize(),
    nYSize = poBand->GetYSize();

这里说明一下,adfGeoTransform中(这里简称GT),GT[0],GT[3]是做上角坐标,GT[1],GT[5]是图像总向横向分辨率,就是每个像素代表的长度,GT[2],GT[4]是旋转相关,一般是0,不用管他。
所以,如果我们想知道右下角的坐标,以横坐标为例,右边和左边相隔nXSize个像素,所以相距nXSize*GT[1]的长度,所以横坐标自然是GT[0]+nXSize*GT[1]。我们得到右下角的坐标x,y为

double x,y;
x = adfGeoTransform[0] + nXSize * adfGeoTransform[1];
y = adfGeoTransform[3] + nYSize * adfGeoTransform[5];

我们想把x,y变成经纬度怎么办呢?下面就是过程2干的事了

/** 过程2 **/
OGRSpatialReference fRef, tRef;
char *tmp = NULL;
/** 获得projRef的一份拷贝 **/
/** 由于projRef是const char*,下面的一个函数不接受,所以需要转换成非const **/
tmp = (char *)malloc(strlen(projRef) + 1);
strcpy_s(tmp, strlen(projRef)+1, projRef);


/** 设置原始的坐标参数,和test.tif一致 **/
fRef.importFromWkt(&tmp);
/** 设置转换后的坐标 **/
tRef.SetWellKnownGeogCS("WGS84");

/** 下面进行坐标转换,到此为止都不需要proj,但是下面的内容如果不安装proj将会无法编译 **/
OGRCoordinateTransformation *coordTrans;
coordTrans = OGRCreateCoordinateTransformation(&fRef, &tRef);
coordTrans->Transform(1, &x, &y);
/** 这时候x,y已经转化为经纬度啦 **/
std::cout << x << '\t' << y << std::endl;

感谢阅读,祝大家生活愉快!

转载自:https://blog.csdn.net/j_yorkkie/article/details/51786957

You may also like...