GDAL六参坐标转换是一种二维坐标转换的参数,常在GDALDataset 类中的CPLErr SetGeoTransform( double* padfTransform )使用;下面让我们先来谈论一下二维的仿射变换。
仿射变换变换公式:
展开形式:
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;
坐标旋转:
坐标缩放:
下面来个示例:
#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 );
}