天天看点

GDAL坐标转换六参的使用方法

https://blog.csdn.net/ivan_ljf/article/details/9175857

GDAL六参坐标转换是一种二维坐标转换的参数,常在GDALDataset 类中的CPLErr SetGeoTransform( double* padfTransform )使用;下面让我们先来谈论一下二维的仿射变换。

仿射变换变换公式:

GDAL坐标转换六参的使用方法

展开形式:

GDAL坐标转换六参的使用方法

x’,y’为目标坐标,x,y为原始坐标,dx,dy为平移参数。A为存储用于绕(dx,dy)旋转,和x,y方向的拉伸比例参数。

与GDAL坐标转换六参的对应:

double *dfGeoTransform = new double[6];

dfGeoTransform[0] = dx;

dfGeoTransform[1] = a11;

dfGeoTransform[2] = a12;

dfGeoTransform[3] = dy;

dfGeoTransform[4] = a21;

dfGeoTransform[5] = a22;

初始化时,A为2×2的单位矩阵,dx = dy = 0.0;

 即dfGeoTransform[] = {0.0,1.0,0.0,0.0,0.0,1.0};

坐标平移:

dx = dx + xtranslation;

dy = dy + xtranslation;

坐标旋转:

GDAL坐标转换六参的使用方法

坐标缩放:

GDAL坐标转换六参的使用方法

下面来个示例:

#include "ogrsf_frmts.h"
#include "stdio.h"
#include <iostream>
#include <string>
using namespace std;

// 定义坐标转换器
class GeoTransform
{
public:
	GeoTransform()
	{
		// 初始化六参数
		dfGeoTransform[0] = 0.0;
		dfGeoTransform[1] = 1.0;
		dfGeoTransform[2] = 0.0;
		dfGeoTransform[3] = 0.0;
		dfGeoTransform[4] = 0.0;
		dfGeoTransform[5] = 1.0;
	}

	~GeoTransform()
	{

	}

	// 设置平移
	void SetTranslate(const double dx, const double dy)
	{
		dfGeoTransform[0] += dx;
		dfGeoTransform[3] += dy;
	}

	// 设置旋转角度
	void SetRotate(const double dangle)
	{
		dfGeoTransform[1] = dfGeoTransform[1] * cos(dangle) 
			+ dfGeoTransform[2] * sin(dangle);
		dfGeoTransform[2] = - dfGeoTransform[1] * sin(dangle) 
			+ dfGeoTransform[2] * cos(dangle);
		dfGeoTransform[4] = dfGeoTransform[4] * cos(dangle) 
			+ dfGeoTransform[5] * sin(dangle);
		dfGeoTransform[5] = - dfGeoTransform[4] * sin(dangle) 
			+ dfGeoTransform[5] * cos(dangle);
	}
	// 设置x,y方向缩放比例
	void SetScale(const double xScale, const double yScale)
	{
		dfGeoTransform[1] = dfGeoTransform[1] * xScale;
		dfGeoTransform[2] = dfGeoTransform[2] * yScale;
		dfGeoTransform[4] = dfGeoTransform[4] * xScale;
		dfGeoTransform[5] = dfGeoTransform[5] * yScale;
	}

	// 转换坐标
	OGRPoint Transform(const double dx, const double dy)
	{
		double x, y;
		x = dfGeoTransform[0]
		+ dx * dfGeoTransform[1] 
		+ dy * dfGeoTransform[2];
		y = dfGeoTransform[3]
		+ dx * dfGeoTransform[4] 
		+ dy * dfGeoTransform[5];

		return OGRPoint(x,y);
	}

private:
	double dfGeoTransform[6];
};

int main()
{
	const char *pszDriverName = "DXF";
	OGRSFDriver *poDriver;
	
	RegisterOGRDXF();

	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
	CPLSetConfigOption("GDAL_DATA", "C:\\GDAL\\data");  //改了这句话就对了:OGR创建DXF格式需要data文件夹下的head.dxf,所以首先要设置GDAL_DATA的目录。
	poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName(
		pszDriverName );
	if( poDriver == NULL )
	{
		printf( "%s driver not available.\n", pszDriverName );
		exit( 1 );
	}

	OGRDataSource *poDS;
	const char* pszFileName="out.dxf";
	poDS = poDriver->CreateDataSource( pszFileName, NULL );
	if( poDS == NULL )
	{
		printf( "Creation of output file failed.\n" );
		exit( 1 );
	}

	OGRLayer *poLayer;

	poLayer = poDS->CreateLayer( "out", NULL, wkbUnknown, NULL );
	if( poLayer == NULL )
	{
		printf( "Layer creation failed.\n" );
		exit( 1 );
	}

	OGRFeature *poFeature = OGRFeature::CreateFeature( poLayer->GetLayerDefn() );

	// 原始矩形
	OGRLinearRing oSquare;
	oSquare.addPoint(2.0,2.0);
	oSquare.addPoint(4.0,2.0);
	oSquare.addPoint(4.0,3.0);
	oSquare.addPoint(2.0,3.0);
	oSquare.closeRings();
	poFeature->SetGeometry( &oSquare );
	if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
	{
		printf( "Failed to create feature in dxffile.\n" );
		exit( 1 );
	}

	// 定义转换器
	GeoTransform geoTransform;
	// 平移
	geoTransform.SetTranslate(2.0,3.0);
	// 旋转
	geoTransform.SetRotate(2);
	// 缩放比例
	geoTransform.SetScale(2.0,3.0);

	// 转换坐标之后的矩形
	OGRLinearRing oSquare2;
	oSquare2.addPoint(&geoTransform.Transform(2.0,2.0));
	oSquare2.addPoint(&geoTransform.Transform(4.0,2.0));
	oSquare2.addPoint(&geoTransform.Transform(4.0,3.0));
	oSquare2.addPoint(&geoTransform.Transform(2.0,3.0));
	oSquare2.closeRings();
	poFeature->SetGeometry( &oSquare2 );
	if( poLayer->CreateFeature( poFeature ) != OGRERR_NONE )
	{
		printf( "Failed to create feature in dxffile.\n" );
		exit( 1 );
	}

	OGRFeature::DestroyFeature( poFeature );

	OGRDataSource::DestroyDataSource( poDS );
}
           

继续阅读