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", "G:/gdal-1.9.2/data"); poDriver = OGRSFDriverRegistrar::GetRegistrar()->GetDriverByName( pszDriverName ); if( poDriver == NULL ) { printf( "%s driver not available.\n", pszDriverName ); exit( 1 ); } OGRDataSource *poDS; poDS = poDriver->CreateDataSource( "out.dxf", 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(0.5); // 缩放比例 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 ); }
效果: