Clion下配置GDAL开发环境(不用编译GDAL源码)

Clion下配置GDAL开发环境(不用编译GDAL源码)

一、写在前面

虽然之前通过 Vcpkg配合 CMakeMinGW的环境下成功安装了GDAL3.6.2,但是环境存在缺陷,压根就无法读取数据,举几个例子;
下面有直接安装教程的完整步骤,移步目录第三节。

二、我遇到的问题

1、ERROR 4: xx\xx\test.gdb: Permission denied

特别让人头疼的一个问题,错误显示文件权限不够,于是我找到这个GDB文件,尝试更改他的属性为当前用户全权控制,但是我发现我当前的用户是 Administrator,对这种普通数据文件都是拥有全部权限的,所以压根就不用改。

改变思路,用管理员模式打开 Clion,再次运行这个程序,发现还是 Permission denied。我真服了!

又想到由于之前是用 Java通过 JNI调用 GDAL的动态库,所以安装了其他版本的GDAL。卸载JavaGDAL,再次运行,还是失败。心态彻底崩了 …

最后是在GDAL官网看到教程解决了问题,读取数据源GDALDataset 一开始我用:

auto  *poDataset = (GDALDataset *)GDALOpen(R"(C:\test.gdb)",GA_ReadOnly);

结果这种方式死活有权限问题:ERROR 4: C:\test.gdb: Permission denied,改为官网用的c++读取方式后就没有出现权限问题了,经过了解我发现 GDALOpen主要用于打开栅格数据文件,而GDALOpenEx提供了更广泛的功能,支持打开矢量和栅格数据,同时还允许指定打开模式和其他选项。

auto poDS = (GDALDataset *) GDALOpenEx(R"(C:\test.gdb)",
							GDAL_OF_VECTOR, nullptr,nullptr, nullptr);
2、无法读取到图层,但是图层指针不为NULL(nullptr)

解决了权限的问题后,开心的往下写,获取数据源,通过数据源获取图层,问题随着也来了,图层获取没问题,图层指针也不为NULL或者nullptr,但是如果通过图层获取要素或者图层其他相关属性的话,程序就错误退出了。贴出代码:

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

using namespace std;

int main() {
    
    
    GDALAllRegister();

    auto *poDataset = static_cast<GDALDataset*>(GDALOpenEx(
    							R"(C:\test.gdb)",
    							GDAL_OF_VECTOR, 
    							nullptr,nullptr, nullptr));
    if (poDataset == nullptr){
    
    
        cout << "数据源空" << endl;
        exit(-1);
    }

    int layer_count = poDataset->GetLayerCount();
    cout << "读取到的图层数量:" << layer_count<< endl;

    cout << "开始读取图层" << endl;
    auto *layer = (OGRLayer *)poDataset->GetLayer(0);
    if (layer == nullptr){
    
    
        cout << "图层为空" << endl;
        exit(-1);
    }

    GDALClose(poDataset);
    return 0;
}

运行这个程序,发现输出了读取到的图层数量:0图层为空,我超?没道理啊,于是换成c的读取方式:

cout << GDALDatasetGetLayerCount(poDataset) << endl; //结果:1

来了,诡异的情况出现了,这种方式居然正确的读取到了图层数量!于是继续用这种方式读取图层:

auto *layer = (OGRLayer *)GDALDatasetGetLayerByName(poDataset,"test_layer");

读取到了,并且图层指针不为NULLnullptr,尝试通过图层指针获取图层名:

  cout << layer->GetName() << endl;

不出意外地意外出现了,程序错误退出了,并且控制台没有任何错误信息…
研究了好久,终于找到解决办法了:

三、通过VisualStudio环境加CMake编译已有程序

1、引言

上面的方式都是用的Clion+MinGW+CMake的方式编译的项目,但是不同的是,MinGW用的动态库不是dll,它用的是dll.a,我通过Vcpkg安装的GDAL库都是dll。当然,用MinGW也是能用的,只是比较麻烦,要把当前用到的GDAL库转换为dll.a,才能用MinGW编译整个项目,于是我换了个思路,之前用的方式一直都是:

在这里插入图片描述

当我把它换成VisualStudio环境后就成功了:

在这里插入图片描述

2、具体操作

好了,情况大概就是这么个情况,接下来我们从0开始具体操作,希望能帮到你;

首先各工具版本声明,下载地址我就不给了,难得找:

工具 版本
VisualStudio 2022-17.9.1
Clion 2023.3.3
CMake(可选) 3.27.9
Vcpkg GitHub拉取,保持最新
GDAL 3.6.0以上

Ⅰ、安装VisualStudio并且添加C++的环境,下载就行了,都是图形化操作。
Ⅱ、安装CMake(可选),无脑下一步就行,只是要记住安装位置。
Ⅲ、安装Clion,并且新建一个C++可执行文件项目:

打开设置-> 构建、执行、部署-> 工具链,添加一个环境,选择VisualStudio,记得如果有多个环境,一定要让VisualStudio在第一个,可以通过 +右边的上下按钮调整位置:

在这里插入图片描述

工具集选择你的VisualStudio安装位置:

在这里插入图片描述

CMake可以用VisualStudio自带的,也可以用我们刚才安装的,如果用我们自己安装的,目录选择的时候到bin下的cmake.exe就行:

在这里插入图片描述

其他的都不用管。

Ⅳ、安装Vcpkg,并且安装GDAL

这一步主要是免去编译GDAL源码的麻烦,Vcpkg给我们编译好,如果你自己编译了GDAL源码,那么可以不用Vcpkg,安装Vcpkg教程看我的另外一篇博客,可以根据这篇博客安装GDAL
此外,如果你用Vcpkg的时候,不想用它默认安装的GDAL版本,那么可以更改Vcpkg的清单,也就是说你要在清单模式下才能指定版本,否则就是默认版本:

在这里插入图片描述

Vcpkg初始化好了以后,默认不是清单模式,你需要选择这个 { }才能切换清单模式,点击后会弹出一个对话框让你选择,什么都不选,确定,Vcpkg就会在项目的根目录下生成一个vcpkg.json文件,这个文件有点类似Java中的Manvepom文件,管理依赖的:

在这里插入图片描述

相信你也看到了,只需要将 dependencies这项改成像我一样,然后下面再加一个 overrides就能指定版本了,其他的Vcpkg设置请移步 微软Vcpkg文档

"dependencies" : [ "gdal" ],
  "overrides": [
    {
    
    
      "name": "gdal",
      "version": "3.6.1"
    }
  ]

修改好了以后,删掉根目录下生成的 cmake-build-debug目录,并点击上方的 工具-> CMake-> 重新加载CMake项目,耐心等待CMake执行完成:

在这里插入图片描述

这里比较慢,耐心等待,因为是从GitHub上下载,我开启了科学上网,耗时大概在二十分钟到四十分钟左右

CMake执行完成后如果出现类似:

在这里插入图片描述

这样的字样的话,就代表安装成功了,将这两句代码放到项目根目录下的CMakeLists.txt中去:

cmake_minimum_required(VERSION 3.27)
project(gdal_test)

set(CMAKE_CXX_STANDARD 17)
find_package(GDAL CONFIG REQUIRED)

add_executable(gdal_test main.cpp)
target_link_libraries(gdal_test PRIVATE GDAL::GDAL)

注意find_package(GDAL CONFIG REQUIRED)要放在add_executable()前,target_link_libraries(main PRIVATE GDAL::GDAL)要放到add_executable()后,并且括号内的main要改为你的项目名字,改完后重新加载项目:

在这里插入图片描述

Ⅴ、配置PORJ_LIB环境变量。

这里有一个比较坑的点,就这么安装完后,会有几率出现关于proj的报错,所以我们得手动配置一个proj的环境变量以防外一。

添加环境变量 PROJ_LIB,指向那会Vcpkg安装目录下的
vcpkg安装目录/packages/proj_x64-windows/share/proj
如果你使用Vcpkg成功安装了GDAL,那么proj_x64-windows肯定会有的,因为这是GDAL的最大依赖,如果你没有这个文件夹,那么请反思,检查哪一步出了问题。

弄完环境变量后,写测试代码测试环境是否成功:

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

using namespace std;

int main() {
    
    
    GDALAllRegister();
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");

	//判断一下驱动
    const char *driver_name = "FileGDB";
    GDALDriver *poDriver = GetGDALDriverManager()->GetDriverByName(driver_name);
    if (poDriver){
    
    
        cout << "不存在驱动:" << driver_name << endl;
    }

    auto *poDataset = static_cast<GDALDataset*>(GDALOpenEx(
    											R"(F:\dev_file\test_file\test.gdb)",
                                                GDAL_OF_VECTOR, nullptr,
                                                nullptr, nullptr));
    if (poDataset == nullptr){
    
    
        cout << "数据源空" << endl;
        exit(-1);
    }

    int layerC = poDataset->GetLayerCount();
    cout << "读取到的图层数量:" << layerC << endl;

    cout << "开始读取图层" << endl;
    auto *layer = (OGRLayer *)poDataset->GetLayer(0);
    if (layer == nullptr){
    
    
        cout << "图层为空" << endl;
        exit(-1);
    }

    const char *layer_name = layer->GetName();
    cout << "图层名:" << layer_name << endl;

    auto *feature = layer->GetFeature(1);
    auto *geom = feature->GetGeometryRef();

    cout << "图层读取完成" << endl;

    GDALClose(poDataset);
    return 0;
}

如果没有任何报错且输出正常则环境配置成功

四、总结

首先本文这么做的原理是,我们通过安装VisualStudio获取到VisualStudio的编译环境,Clion默认使用的是MinGW编译环境,我们将它换为VisualStudio
此外,传统的VisualStudio开发需要你自己编译GDAL源码为.lib库或者.dll库,如果使用MinGW编译环境也要将GDAL编译好的.dll.lib库转换为MinGW能用的库,有点麻烦,我没操作过,可以了解一下。
再然后通过Vcpkg安装GDAL,就可以免去手动编译GDAL的麻烦,开箱即用。

再贴一个官方 GDAL教程 的链接,配合科学上网使用最佳。

大概就这么多,后续有问题我会继续补充或修改这篇博客的内容,如果你遇到了本文之外的问题,可以在评论区留言,我会的尽量帮。

猜你喜欢

转载自blog.csdn.net/m0_53928179/article/details/136387448