我用AI搜索了很久,总算完成了这个代码。
- 工作思路
无人机在空中飞行,需要匹配地面影像,确认自己的真实位置。
- 瓦片数据
使用QGIS下载瓦片地图-CSDN博客
- 代码
能编译运行,能正确产生不同ZOOM的图片。
#include <stdio.h> #include <stdlib.h> #include "gdal.h" #include "gdal_utils.h" #define MAPTILE_FILE "wuxi.mbtiles" #define POINT_LONGITUDE 120.337 #define POINT_LATITUDE 31.505 #define AREA_SIZE 0.010 static GDALDatasetH openMapFile(const int zoom) { #if 1 char param1[32]; sprintf(param1, "ZOOM_LEVEL=%d", zoom); const char* openOpts[] = {param1, NULL}; // 3. 使用GDALOpenEx打开数据集 GDALDatasetH hSrcDS = GDALOpenEx( MAPTILE_FILE, // 文件名 GDAL_OF_RASTER | GDAL_OF_READONLY, // 只读方式打开栅格数据 NULL, // 不限制驱动 openOpts, // 传入我们设置的打开选项 NULL // 无关联文件 ); #else GDALDatasetH hSrcDS = GDALOpen(MAPTILE_FILE, GA_ReadOnly); #endif return hSrcDS; } static int convertToPng(const char* file, const GDALDatasetH hSrcDS, const GDALTranslateOptions* psOptions) { // 6. 执行裁剪和格式转换 GDALDatasetH hDstDS = GDALTranslate(file, hSrcDS, psOptions, NULL); if (hDstDS) { printf("成功将 %s 裁剪并保存为 %s\n", MAPTILE_FILE, file); return -1; } else { printf("转换失败!\n"); } return 0; } static GDALTranslateOptions* initTransOptions() { // 2, 将边界值转换为字符串,并加入到参数数组中 char szMinLon[32], szMaxLat[32], szMaxLon[32], szMinLat[32]; snprintf(szMinLon, sizeof(szMinLon), "%.6f", (POINT_LONGITUDE-AREA_SIZE/2)); snprintf(szMaxLat, sizeof(szMaxLat), "%.6f", (POINT_LATITUDE +AREA_SIZE/2)); snprintf(szMaxLon, sizeof(szMaxLon), "%.6f", (POINT_LONGITUDE+AREA_SIZE/2)); snprintf(szMinLat, sizeof(szMinLat), "%.6f", (POINT_LATITUDE -AREA_SIZE/2)); // 3. 构建 参数数组 // 重新构建包含边界值的参数数组 // 示例范围:围绕北京的区域 (经度: 116.3 ~ 116.5, 纬度: 39.8 ~ 40.0) // 注意:-projwin 的顺序是左上角 (minLon, maxLat) 到右下角 (maxLon, minLat) const char* const apszArgvFull[] = { "-projwin", szMinLon, szMaxLat, szMaxLon, szMinLat, "-projwin_srs", "EPSG:4326", "-of", "PNG", NULL }; // 4. 创建 GDALTranslateOptions 对象 GDALTranslateOptions* psOptions = GDALTranslateOptionsNew((char**)apszArgvFull, NULL); if (!psOptions) { printf("解析 GDALTranslateOptions 参数失败!\n"); return NULL; } return psOptions; } int main() { // 1. 注册所有 GDAL 驱动 GDALAllRegister(); GDALTranslateOptions* psOptions = initTransOptions(); if (!psOptions) { return -1; } for (int zoom=8; zoom<=16; zoom++) { // 5. 打开源数据集 (MBTiles) GDALDatasetH hSrcDS = openMapFile(zoom); if (hSrcDS == NULL) { printf("无法打开源文件: %s(zoom=%d)\n", MAPTILE_FILE, zoom); continue; } char file[32]; sprintf(file, "zoom%d.png", zoom); convertToPng(file, hSrcDS, psOptions); GDALClose(hSrcDS); } // 7. 清理资源 GDALTranslateOptionsFree(psOptions); GDALClearMemoryCaches(); GDALDestroy(); // Why core dump ? return 0; }- 编译脚本
export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${HOME}/map_gdal/lib:${HOME}/map_proj/lib export PKG_CONFIG_PATH=${PKG_CONFIG_PATH}:${HOME}/map_gdal/lib/pkgconfig rm core.* reset SRC_FILE=test2.cpp EXE_FILE=test if [ -f ${EXE_FILE} ]; then rm ${EXE_FILE} fi g++ ${SRC_FILE} \ -o ${EXE_FILE} \ $(pkg-config --cflags --libs gdal) ./${EXE_FILE}