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

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

仿射变换变换公式:

展开形式:

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;

初始化时,A2×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 );
}

 

效果:


### GDAL 坐标转换过程中经纬度顺序错误解决方案 在处理GDAL坐标转换时,如果遇到经纬度顺序颠倒的问题,通常是因为输入或输出坐标的顺序不符合预期。为了确保正确的坐标转换,在设置`OGRCoordinateTransformation`对象时需特别注意。 当创建坐标转换器实例并指定源和目标坐标系时,应确认所使用的坐标系定义文件中的数是否正确设置了经度优先还是纬度优先[^2]。对于WGS84等地理坐标系,默认情况下采用的是经度-纬度顺序。因此,在构建`OGRSpatialReference`对象时要保证遵循这一约定: ```cpp // 定义UTM坐标系作为源坐标系 oUTM.SetProjCS("UTM 17 / WGS84"); oUTM.SetWellKnownGeogCS("WGS84"); oUTM.SetUTM(17); // 获取对应的地理坐标系副本用于后续操作 poLatLong = oUTM.CloneGeogCS(); // 创建从UTM到地理坐标系的转换关系 poTransform = OGRCreateCoordinateTransformation(&oUTM, poLatLong); ``` 另外,当调用`Transform()`方法执行实际的数据点转换之前,可以先通过检查API文档来验证传入数组x,y,z的具体含义,即它们分别代表什么类型的坐标值(例如,x通常是经度而y是纬度)。这有助于防止因误解而导致的误用情况发生。 最后,考虑到不同版本间可能存在行为差异,建议查阅最新版GDAL/OGR API指南以获取最准确的信息,并考虑升级至较新版本以便利用改进后的特性和支持更好的兼容性[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值