GDAL數據集寫入空間坐標參考


1. 概述

可以通過GDAL給地理數據寫入空間參考信息,不過要注意的是GDAL給矢量數據和柵格數據寫入空間坐標參考的接口不太一樣。

2. 柵格數據

實現代碼如下:

#include <iostream>
#include <gdal_priv.h>
#include <string>

using namespace std;

int main()
{
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");  //支持中文路徑
	CPLSetConfigOption("SHAPE_ENCODING", "");  //解決中文亂碼問題	
	CPLSetConfigOption("GDAL_DATA", "D:/Work/GDALBuild/gdal-2.4.2/install/data");

	GDALDriver *pDriver = GetGDALDriverManager()->GetDriverByName("GTIFF"); //圖像驅動
	char** ppszOptions = NULL;
	ppszOptions = CSLSetNameValue(ppszOptions, "BIGTIFF", "IF_NEEDED"); //配置圖像信息
	const char* dstPath = "dst.tif";
	GDALDataset* dst = pDriver->Create(dstPath, 256, 256, 3, GDT_Byte, ppszOptions);
	if (dst == nullptr)
	{
		printf("Can't Write Image!");
		return false;
	}

	//空間參考
	OGRSpatialReference spatialReference;
	spatialReference.importFromEPSG(4326);				//wgs84地理坐標系
	char *pszWKT = nullptr;
	spatialReference.exportToWkt(&pszWKT);

	dst->SetProjection(pszWKT);

	CPLFree(pszWKT);
	pszWKT = nullptr;

	//坐標信息
	double padfTransform[6] = {
		114.0,		//左上角點坐標X
		0.000001,		//X方向的分辨率
		0,		//旋轉系數,如果為0,就是標准的正北向圖像
		34.0,			//左上角點坐標Y
		0,			//旋轉系數,如果為0,就是標准的正北向圖像
		0.000001,			//Y方向的分辨率
	};
	dst->SetGeoTransform(padfTransform);

	GDALClose(dst);
}

這里創建了一個wgs84地理坐標系空間參考的柵格數據,通過OGRSpatialReference類導出了描述空間參考的wkt字符串,寫入到GDAL數據集中。

3. 矢量數據

實現代碼如下:

#include <iostream>
#include <gdal_priv.h>
#include <ogrsf_frmts.h>

using namespace std;

int main()
{
	GDALAllRegister();
	CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO");  //支持中文路徑
	CPLSetConfigOption("SHAPE_ENCODING", "");  //解決中文亂碼問題	
	CPLSetConfigOption("GDAL_DATA", "D:/Work/GDALBuild/gdal-2.4.2/install/data");

	//空間參考
	OGRSpatialReference spatialReference;
	spatialReference.importFromEPSG(4326);				//wgs84地理坐標系
	
	//創建
	GDALDriver* driver = GetGDALDriverManager()->GetDriverByName("ESRI Shapefile");
	if (!driver)
	{
		printf("Get Driver ESRI Shapefile Error!\n");
		return false;
	}

	GDALDataset* dataset = driver->Create("dst.shp", 0, 0, 0, GDT_Unknown, NULL);
	OGRLayer* poLayer = dataset->CreateLayer("houseType", &spatialReference, wkbPolygon, NULL);

	//創建屬性字段
	{
		// 字符串
		OGRFieldDefn oField1("名稱", OFTString);
		oField1.SetWidth(8);
		if (poLayer->CreateField(&oField1) != OGRERR_NONE) {
			printf("Creating Name field failed.\n"); return FALSE;
		}

		// 浮點數
		OGRFieldDefn oField2("面積", OFTReal);
		oField2.SetPrecision(3);
		if (poLayer->CreateField(&oField2) != OGRERR_NONE) {
			printf("Creating Name field failed.\n"); return FALSE;
		}

		// 整型
		OGRFieldDefn oField3("結點數", OFTInteger);
		if (poLayer->CreateField(&oField3) != OGRERR_NONE) {
			printf("Creating Name field failed.\n"); return FALSE;
		}
	}

	//創建特征
	OGRFeature *poFeature = new OGRFeature(poLayer->GetLayerDefn());

	OGRLinearRing ogrring;
	int pNum = 4;
	ogrring.setNumPoints(pNum);
	ogrring.setPoint(0, 114.0, 34.0, 0.0);
	ogrring.setPoint(1, 115.0, 34.0, 0.0);
	ogrring.setPoint(2, 115.0, 35.0, 0.0);
	ogrring.setPoint(3, 114.0, 35.0, 0.0);
	   
	OGRPolygon polygon;
	polygon.addRing(&ogrring);
	poFeature->SetGeometry(&polygon);

	poFeature->SetField("名稱", "多邊形");
	poFeature->SetField("面積", polygon.get_Area());
	poFeature->SetField("結點數", pNum);

	if (poLayer->CreateFeature(poFeature) != OGRERR_NONE)
	{
		printf("Failed to create feature in shapefile.\n");
		return false;
	}

	//釋放
	GDALClose(dataset);
	dataset = nullptr;
}

與寫入到柵格數據不同,空間參考信息寫入到矢量數據是寫入到GDAL數據集的圖層類中的,並且直接傳入OGRSpatialReference類即可。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM