gdal的简单代码使用——瓦片地图拼接

  • 瓦片地图
  • 何为瓦片地图
  • 所用的库
  • 代码
  • 相关资源


瓦片地图

随着现在地图信息愈加强大,为了更加详细地表示地图信息,瓦片地图成为了一种比较好的方式,这篇博客主要就是讲述了一下将瓦片拼接成为地图的原理,以及相关代码。

何为瓦片地图

何为瓦片地图,其实非常简单,可以理解为小时候大家玩过的拼图,只不过拼图的数量更多,完成拼接的人,也从自己变为计算机,这样瓦片地图的作用和方法就变得非常清晰了。下面再来看看瓦片地图的参数,(x,y,z)。首先从z说起,当z = 1时,代表着瓦片地图的第一层,此时一副完整的世界地图切割了(z-1 )次,同理z等于多少就代表切割了多少次,并且此时瓦片的个数为2^(z - 1)。x和y则更加好理解,大致等于直角坐标系的横纵坐标。

所用的库

在这次所使用的库为gdal,GDAL(Geospatial Data Abstraction Library)是一个在X/MIT许可协议下的开源栅格空间数据转换库。它利用抽象数据模型来表达所支持的各种文件格式。它还有一系列命令行工具来进行数据转换和处理。(后附gdal文件的相关库,可自行配置)

代码

#include<cstdio>
#include<iostream>
#include "gdal_priv.h"
#include<iomanip>
#include "cpl_conv.h"
#include "ogrsf_frmts.h"
#include<cmath>

using namespace std;

int main()
{
	int x_1 = 22390, x_2 = 22470, y_1 = 52017, y_2 = 52072;//在此处输入,x和y的值,尽量保证x_2 - x_1 = 80,y_2 - y_1 = 55
	int i, j;
	//如果想改成输入经纬度,可以研究一下中间被注释的代码
	/*
	//int pi = 3.1415
	//int ix, iy, il;
	//int lat_min,lon_max,lat_min,lon_max;
	//int x_1 = ((lon_min + 180)/360) * pow(2,17);
	//int x_2 = ((lon_max + 180)/360) * pow(2,17);
	//int y_1 = (1 - ((log(tan(lat_min*(pi / 180))) + (1 / (cos(lat_min * (pi / 180))))) / pi)) * pow(2,16);
	//int y_2 = (1 - ((log(tan(lat_max*(pi / 180))) + (1 / (cos(lat_max * (pi / 180))))) / pi)) * pow(2,16);
	*/
	typedef unsigned char       BYTE;//定义无符号性的char型为BYTE
	typedef unsigned short      WORD;
	typedef unsigned long       DWORD;
	GDALDataset *poDataset2;//数据集对象指针
	GDALAllRegister();//注册驱动
	BYTE* data = new BYTE[256 * 256 * 3];
	GDALDataset *poDataset;//GDAl数据集
	GDALDriver* poDriver;//驱动,用于创建新的文件
	poDriver = GetGDALDriverManager()->GetDriverByName("GTiff");//获取GDALDriverManager类的tiff的单例
	char** papszMetadata = poDriver->GetMetadata();//一系列键值对。可以分为不同的Domain。
	poDataset = poDriver->Create("E:\\c++code\\test3\\photo generate\\tif\\CREATE1.tif", 85 * 256, 60 * 256, 3, GDT_Byte, papszMetadata);//在此处修改过渡文件tif的保存路径
	//创建过渡用的TIF文件
	for(i=x_1;i <=x_2;i++)//行号
		for (j = y_1; j <= y_2; j++)//列号
		{
			std::string input = string("E:\\c++code\\test3\\17\\") + std::to_string(i) + "\\" + std::to_string(j) + ".png";
			poDataset2 = (GDALDataset*)GDALOpen(input.c_str(), GA_ReadOnly);// , GA_ReadOnly);//打开数据
			poDataset2->RasterIO(GF_Read, 0, 0, 256, 256, data, 256, 256, GDT_Byte, 3, 0, 0, 0, 0);//读取数据
			poDataset->RasterIO(GF_Write, 256 * (i - x_1), 256 * (j - y_1), 256, 256, data, 256, 256, GDT_Byte, 3, 0, 0, 0, 0);//写入数据

		}
	poDriver = GetGDALDriverManager()->GetDriverByName("PNG");
	poDataset2 = poDriver->CreateCopy("E:\\c++code\\test3\\photo generate\\png\\output1.png", poDataset, 3, papszMetadata, NULL, NULL); //在此处修改保存的路径

}