First steps

The Rust GDAL bindings consist of two crates, gdal and gdal-sys. The former contains high-level, idiomatic APIs, while the latter exposes the C API almost unchanged. Since the high-level bindings are incomplete, at times you will need to drop down to gdal-sys. When that happens, a familiarity with the GDAL C API will be very useful.

And if you want to expand the gdal API, pull requests are always appreciated!

Linking with GDAL

gdal-sys does not compile GDAL from source, so it has to be available on your system.

On Linux, that usually means installing a GDAL development package (gdal-devel, libgdal-dev or gdal). If you are an advanced user, you can use the GDAL_INCLUDE_DIR, GDAL_LIB_DIR and GDAL_STATIC environment variables to control the linking.

On Windows and MacOS, you will need to acquire or build GDAL. The environment variables mentioned above work, but setting GDAL_HOME, or even using WSL, might be easier for Windows users.

Generating the bindings

The gdal crate bundles bindings for some versions of GDAL, but if you have a newer one, you can enable the bindgen feature.

Checking the GDAL version

Once you've got everything set up, run cargo add gdal and try the following code:

use gdal::version::VersionInfo;

fn main() {
    println!("{}", gdal::version_info("VERSION_NUM"));
    // 3060200
    println!("{}", VersionInfo::release_name());
    // 3.6.2
}

Setting an error handler

The following example installs an error handle and emits an error. You can notice that there is no API available in gdal, so it uses the gdal-sys crate, at the cost of a lot of ceremony.

use std::ffi::CString;

use gdal::{config, errors::CplErrType};
use gdal_sys::CPLErr;

fn error_handler(class: CplErrType, number: i32, message: &str) {
    let class = match class {
        CplErrType::None => "[NONE]",
        CplErrType::Debug => "[DEBUG]",
        CplErrType::Warning => "[WARN]",
        CplErrType::Failure => "[ERROR]",
        CplErrType::Fatal => "[FATAL]",
    };
    eprintln!("{class} [{number}] {message}");
}

fn main() {
    config::set_error_handler(error_handler);
    unsafe {
        let message = CString::new("test error").unwrap();
        gdal_sys::CPLError(CPLErr::CE_Debug, 2, message.as_ptr());
        // [DEBUG] [2] test error
    }
    config::remove_error_handler();
}