gdal/programs/raster/
vrt.rs1use std::{
2 borrow::Borrow,
3 ffi::{c_char, c_int, CString},
4 path::Path,
5 ptr::{null, null_mut},
6};
7
8use gdal_sys::GDALBuildVRTOptions;
9
10use crate::{
11 errors::*,
12 utils::{_last_null_pointer_err, _path_to_c_string},
13 Dataset,
14};
15
16pub struct BuildVRTOptions {
20 c_options: *mut GDALBuildVRTOptions,
21}
22
23impl BuildVRTOptions {
24 pub fn new<S: Into<Vec<u8>>, I: IntoIterator<Item = S>>(args: I) -> Result<Self> {
28 let cstr_args = args
30 .into_iter()
31 .map(CString::new)
32 .collect::<std::result::Result<Vec<_>, _>>()?;
33
34 let mut c_args = cstr_args
38 .iter()
39 .map(|x| x.as_ptr() as *mut c_char)
40 .chain(std::iter::once(null_mut()))
41 .collect::<Vec<_>>();
42
43 unsafe {
44 Ok(Self {
45 c_options: gdal_sys::GDALBuildVRTOptionsNew(c_args.as_mut_ptr(), null_mut()),
46 })
47 }
48 }
49
50 pub unsafe fn c_options(&self) -> *mut GDALBuildVRTOptions {
55 self.c_options
56 }
57}
58
59impl Drop for BuildVRTOptions {
60 fn drop(&mut self) {
61 unsafe {
62 gdal_sys::GDALBuildVRTOptionsFree(self.c_options);
63 }
64 }
65}
66
67pub fn build_vrt<D: Borrow<Dataset>>(
74 dest: Option<&Path>,
75 datasets: &[D],
76 options: Option<BuildVRTOptions>,
77) -> Result<Dataset> {
78 _build_vrt(
79 dest,
80 &datasets
81 .iter()
82 .map(|x| x.borrow())
83 .collect::<Vec<&Dataset>>(),
84 options,
85 )
86}
87
88fn _build_vrt(
89 dest: Option<&Path>,
90 datasets: &[&Dataset],
91 options: Option<BuildVRTOptions>,
92) -> Result<Dataset> {
93 let dest = dest.map(_path_to_c_string).transpose()?;
95 let c_dest = dest.as_ref().map(|x| x.as_ptr()).unwrap_or(null());
96
97 let c_options = options
98 .as_ref()
99 .map(|x| x.c_options as *const GDALBuildVRTOptions)
100 .unwrap_or(null());
101
102 let dataset_out = unsafe {
103 let mut datasets_raw: Vec<gdal_sys::GDALDatasetH> =
105 datasets.iter().map(|x| x.c_dataset()).collect();
106
107 gdal_sys::GDALBuildVRT(
108 c_dest,
109 datasets_raw.len() as c_int,
110 datasets_raw.as_mut_ptr(),
111 null(),
112 c_options,
113 null_mut(),
114 )
115 };
116
117 if dataset_out.is_null() {
118 return Err(_last_null_pointer_err("GDALBuildVRT"));
119 }
120
121 let result = unsafe { Dataset::from_c_dataset(dataset_out) };
122
123 Ok(result)
124}