如何将Tiff文件切成瓦片( GDAL切片) gdal2tile - 基于C++语言开发

如何,tiff,文件,切成,瓦片,gdal,切片,gdal2tile,基于,c++,语言,开发 · 浏览次数 : 90

小编点评

**代码功能:** 该代码使用 GDAL 库实现对 JPEG 图像的缩放转换。 **主要步骤:** 1. 获取当前程序的路径。 2. 设置 gdal_data 路径。 3. 读取源文件(tif 文件)。 4. 创建输出目录。 5. 创建输出 TIFF 文件。 6. 设置输出文件格式和命名。 7. 打开源文件。 8. 缩放并导出图像。 9. 打印缩放时间。 **关键代码部分:** ```c++ int main(int argc, char** args) { // ... // 设置输出文件路径 std::string gdalData = "gdal_data/"; // ... // 读取源文件 TiffObject tifObject(256, isMercator); if (!tifObject.open(srcFile.c_str())) { return 0; } // ... // 导出输出文件 tifObject.exportTile(outDir, levels, ext.c_str()); // 打印缩放时间 printf("\nall cost %lf second", tms.getElapsedSecond()); // ... } ``` **注意:** 1. `levels` 是一个字符串列表,存储了所有要缩放的级别。 2. `isMercator` 是一个布尔值,指示是否使用 mercator 投影。 3. `outDir` 是输出文件的目录路径。 4. `ext` 是输出文件的扩展名(默认值为 ".jpg")。

正文

准备资料

1. 一张wgs84投影的大tiff文件,建议初学者使用一张全球 2048 * 1024 / 4096 * 2048 的完整数据(有助于观察验证)

2. 准备C++开发环境,配置好gdal (笔者使用的环境是 vs2022 + gdal-2.3.0) c++ 开发环境

3. 建立一个测试工程(笔者建立的控制台)

4. 实现wgs84投影类/初期可以指建立wgs84,后续需要用到Mercator,则一次递进

5. 关键算法实现:如何从一个大图像中获取指定的部分

6. GDALAllRegister() 函数实现对GDAL的初始化

    GDALAllRegister();
    char            szCWD[FE_PATH_LENGHT]   =   {0};
    /// 获取当前exe的路径
    std::string     path        =   getcwd(szCWD,sizeof(szCWD));
    std::string     gdalData    =   path + "/gdal_data";
    /// 设置gdal_data路径,否则gdal无法正确工作
    CPLSetConfigOption( "GDAL_DATA", gdalData.c_str() );

其中  CPLSetConfigOption( "GDAL_DATA", gdalData.c_str() ); 告诉GDAL初始化数据从什么位置读取,很重要,否则会影响后续功能

7. 关键算法实现

 1     bool    createTile(double geoTrans[6],TileDataSet& result)
 2     {
 3         // The transformation option list
 4         CPLStringList   transformOptions;
 5 
 6         // The source, sink and grid srs
 7         const char*     pszSrcWKT   =   GDALGetProjectionRef(_srcDS);
 8         const char*     pszGridWKT  =   pszSrcWKT;
 9         if (pszSrcWKT == nullptr || !strlen(pszSrcWKT))
10             return  false;
11 
12         // Populate the SRS WKT strings if we need to reproject
13         if (requiresReprojection()) 
14         {
15             transformOptions.SetNameValue("SRC_SRS", pszSrcWKT);
16             transformOptions.SetNameValue("DST_SRS", pszGridWKT);
17         }
18 
19         GDALWarpOptions *psWarpOptions  =   GDALCreateWarpOptions();
20         psWarpOptions->eResampleAlg     =   GRA_Average;
21         psWarpOptions->dfWarpMemoryLimit=   0;
22         psWarpOptions->hSrcDS           =   _srcDS;
23         psWarpOptions->nBandCount       =   _srcDS->GetRasterCount();
24         psWarpOptions->panSrcBands      =   (int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount );
25         psWarpOptions->panDstBands      =   (int *) CPLMalloc(sizeof(int) * psWarpOptions->nBandCount );
26 
27         for (int i = 0; i < psWarpOptions->nBandCount; ++i) 
28         {
29             psWarpOptions->panDstBands[i]   =   i + 1;
30             psWarpOptions->panSrcBands[i]   =   i + 1;
31         }
32 
33         void*   transformerArg = GDALCreateGenImgProjTransformer2(_srcDS, NULL, transformOptions.List());
34         if(transformerArg == NULL) 
35         {
36             GDALDestroyWarpOptions(psWarpOptions);
37             return  false;
38         }
39 
40         auto    hWrkSrcDS = psWarpOptions->hSrcDS = _srcDS;
41         GDALSetGenImgProjTransformerDstGeoTransform(transformerArg, geoTrans );
42 
43         if (false)
44         {
45             // approximate: wrap the transformer with a linear approximator
46             psWarpOptions->pTransformerArg =    GDALCreateApproxTransformer(GDALGenImgProjTransform, transformerArg, 0.125000000);
47 
48             if (psWarpOptions->pTransformerArg == nullptr) 
49             {
50                 GDALDestroyWarpOptions(psWarpOptions);
51                 GDALDestroyGenImgProjTransformer(transformerArg);
52                 return  false;
53             }
54             psWarpOptions->pfnTransformer   =   GDALApproxTransform;
55         }
56         else
57         {
58             psWarpOptions->pTransformerArg  =   transformerArg;
59             psWarpOptions->pfnTransformer   =   GDALGenImgProjTransform;
60         }
61         
62         // Specify a multi threaded warp operation using all CPU cores
63         CPLStringList warpOptions(psWarpOptions->papszWarpOptions, false);
64         warpOptions.SetNameValue("NUM_THREADS", "ALL_CPUS");
65         psWarpOptions->papszWarpOptions = warpOptions.StealList();
66 
67         // The raster tile is represented as a VRT dataset
68         auto    dstDS   =   GDALCreateWarpedVRT(hWrkSrcDS, _tileSize, _tileSize, geoTrans, psWarpOptions);
69 
70         if (dstDS == nullptr) 
71         {
72             GDALDestroyGenImgProjTransformer(transformerArg);
73             return  false;
74         }
75 
76         /// Set the projection information on the dataset. This will always be the grid
77         /// SRS.
78         if (GDALSetProjection( dstDS, pszGridWKT ) != CE_None) 
79         {
80             GDALClose(dstDS);
81             if (transformerArg != nullptr) 
82             {
83                 GDALDestroyGenImgProjTransformer(transformerArg);
84             }
85             return  false;
86         }
87 
88         result._dataSet     =   dstDS;
89         result._transArg    =   transformerArg;
90         return  true;
91     }

其中重点 : GDALCreateWarpedVRT函数

8.  框架代码实现如下:

 1 int main(int argc,char** args)
 2 {
 3     system("color 2");
 4     GDALAllRegister();
 5     char            szCWD[FE_PATH_LENGHT]   =   {0};
 6     /// 获取当前exe的路径
 7     std::string     path        =   getcwd(szCWD,sizeof(szCWD));
 8     std::string     gdalData    =   path + "/gdal_data";
 9     /// 设置gdal_data路径,否则gdal无法正确工作
10     CPLSetConfigOption( "GDAL_DATA", gdalData.c_str() );
11 
12     /// conv("d:/tms",int3(4,1,2));
13     /// return  0;
14     std::cout << std::endl;
15     /// 版本号说明 1.0.0.0
16     /// 主版本号.副版本号.增加的功能个数.修复的bug数量
17     std::cout << "版权所有:成都经纬快图科技有限公司" << std::endl;
18     std::cout << "咨询微信:JingWeiKuaiTu" << std::endl;
19     std::cout << "当前版本:V2.0.0.0" << std::endl;
20 
21 
22     cmdline::parser a;
23     a.add<string>("in",         'i', "src file",    true,   "");
24     a.add<string>("out",        'o', "dst dir",     false,  "");
25     a.add<string>("lev",        'l', "levels",      false,  "");
26     a.add<string>("ext",        'e', "jpg,png",     false,  "jpg");
27     a.add<bool>("mercator",     'm', "mercator",    false,  false);
28     a.add("help", 0, "-i d:/src.tif -o d:/dst -l 1-4 -e jpg -m 0\n");
29 
30     a.parse_check(argc, args);
31     
32     Levels          levels;
33 
34     std::string     srcFile     =   a.get<string>("in");
35     std::string     outDir      =   a.get<string>("out");
36     std::string     levs        =   a.get<string>("lev");
37     std::string     ext         =   a.get<string>("ext");
38     bool            isMercator  =   a.get<bool>("mercator");
39     if (!levs.empty())
40     {
41         levels  =   toLevels(levs.c_str());
42     }  
43     if (outDir.empty())
44     {
45         outDir  =   getFilePath(srcFile) + "/tile";
46     }
47     createDir(outDir.c_str());
48 
49     Tiff    tifObject(256,isMercator);
50     if (!tifObject.open(srcFile.c_str()))
51     {
52         return  0;
53     }
54     FETimestamp tms;
55     tifObject.exportTile(outDir,levels,ext.c_str());
56 
57     printf("\nall cost %lf second",tms.getElapsedSecond());
58     /// 获取tif的基本信息
59    
60     return  0;
61 }

代码已经上传

与如何将Tiff文件切成瓦片( GDAL切片) gdal2tile - 基于C++语言开发相似的内容:

如何将Tiff文件切成瓦片( GDAL切片) gdal2tile - 基于C++语言开发

准备资料 1. 一张wgs84投影的大tiff文件,建议初学者使用一张全球 2048 * 1024 / 4096 * 2048 的完整数据(有助于观察验证) 2. 准备C++开发环境,配置好gdal (笔者使用的环境是 vs2022 + gdal-2.3.0) c++ 开发环境 3. 建立一个测试工

如何将文本转换为向量?(方法三)

​ 文本转换为向量有多种方式: 方法一:通过模型服务灵积DashScope将文本转换为向量(推荐) 方法二:通过ModelScope魔搭社区中的文本向量开源模型将文本转换为向量 方法三:通过Jina Embeddings v2模型将文本转换为向量 方法四:通过百川智能向量化模型将文本转换为向量 本文

如何将 Win10 企业版转换为专业版

有时候,我们需要将 Windows 10 企业版转换为专业版。这种情况可能发生在您购买了预装企业版的电脑,但实际上只需要专业版的功能。本文将介绍如何简单地将 Windows 10 企业版转换为专业版。 准备工作 下载转换所需的安装文件。您可以从以下链接获取: 链接: https://pan.baid

如何将WebAssembly优化到1MB?

Blazor WebAssembly加载优化方案 对于Blazor WebAssembly加载方案的优化是针对于WebAssembly首次加载,由于BlazorWebAssembly是在首次加载的时候会将.NET Core的所有程序集都会加载到浏览器中,并且在使用的时候可能引用了很多第三方的dll,

如何将c#在线编辑器嵌入自己项目

如何将c#在线编辑器嵌入自己项目 首先我们需要介绍一下这个在线编辑器,当前的在线编辑器支持c#的代码编译运行,并且无需后台服务,基于WebAssembly实现的在浏览器端去执行我们的c#代码,基于Roslyn提供的Api封装一套简单的编译,并且封装了js的支持,让嵌入的方式更简单。 使用现有项目嵌入

如何将现有的`Blazor`项目的主题切换写的更好看?

# 如何将现有的`Blazor`项目的主题切换写的更好看? 在现有的系统当中,我们的主题切换会比较生硬,下面我们将基于Masa Blazor实现好看的扩散主题切换的样式效果。 ## 安装MASA.Template ```sh dotnet new install MASA.Template ```

如何将BI 工具与业务系统进行单点登录对接,实现用户权限通用

本文由葡萄城技术团队于博客园原创并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具、解决方案和服务,赋能开发者。 首先来看下两套系统的用户体系功能,左边是BI 工具,右边是业务系统,需要实现用户权限对接和打通: 单点登录体系及用户场景 • 场景1. 用户登录Wyn BI页面使用第三

如何将使用中的域名平滑迁移到京东云?(以原域名注册、域名解析都在万网为例)

首先要了解的是,1、域名注册 2、域名解析,是两个独立的产品。一般情况下,域名服务商(万网、新网等)会提供一站式服务,既提供“域名购买注册”,又提供“域名解析服务”。 但实际上,域名和域名解析是可以分开部署的,域名服务商也支持相关的分离设置。比如:域名在万网进行管理,域名解析可以指向其他域名服务商的NS服务器。更进一步,域名也可以从原域名服务商(万网),迁移到新的域名服务商(新网)。

一台不容错过的Java单元测试代码“永动机”

如何将失误降到最低?我们期望能打造一台生产Java单元测试代码的“永动机”,源源不断地为开发者生产代码,辅助大家高效地做好单元测试,节省精力能投入到更多的业务创新中去。

如何将网站保存为手机app

# 1.打开目标页面(hangyejingling.cn) ![](https://img2023.cnblogs.com/blog/1771461/202307/1771461-20230712105707457-2126089695.png) # 2.点击该按钮 ![](https://img2