@@ -9,11 +9,11 @@ mod reproject_options;
99mod resample;
1010mod warp_options;
1111
12- use gdal_sys:: CPLErr ;
12+ use gdal_sys:: { CPLErr , GDALDatasetH , GDALWarp } ;
1313pub use reproject_options:: * ;
1414pub use resample:: * ;
1515use std:: ffi:: CString ;
16- use std:: path:: Path ;
16+ use std:: path:: { Path , PathBuf } ;
1717use std:: ptr;
1818pub use warp_options:: * ;
1919
@@ -22,7 +22,7 @@ use crate::DriverManager;
2222
2323use crate :: errors:: * ;
2424use crate :: spatial_ref:: SpatialRef ;
25- use crate :: utils:: { _last_cpl_err, _path_to_c_string} ;
25+ use crate :: utils:: { _last_cpl_err, _last_null_pointer_err , _path_to_c_string} ;
2626
2727/// Reproject raster dataset into the given [`SpatialRef`] and save result to `dst_file`.
2828pub fn create_and_reproject < P : AsRef < Path > > (
@@ -163,6 +163,79 @@ pub fn reproject_into(
163163 Ok ( ( ) )
164164}
165165
166+ pub fn warp < D > ( source : & Dataset , dest : D , options : & GdalWarpOptions ) -> Result < Dataset >
167+ where
168+ D : Into < WarpDestination > ,
169+ {
170+ warp_multiple ( & [ source] , dest, options)
171+ }
172+
173+ pub fn warp_multiple < D > ( source : & [ & Dataset ] , dest : D , options : & GdalWarpOptions ) -> Result < Dataset >
174+ where
175+ D : Into < WarpDestination > ,
176+ {
177+ let app_opts = GdalWarpAppOptions :: default ( ) ;
178+
179+ if true {
180+ todo ! ( "how the hell do you go from {options:?} to GdalWarpAppOptions?" ) ;
181+ }
182+
183+ let mut source = source. iter ( ) . map ( |ds| ds. c_dataset ( ) ) . collect :: < Vec < _ > > ( ) ;
184+
185+ let dest = dest. into ( ) ;
186+ match dest {
187+ WarpDestination :: Dataset ( ds) => {
188+ let ds_c = unsafe {
189+ GDALWarp (
190+ ptr:: null_mut ( ) ,
191+ ds. c_dataset ( ) ,
192+ source. len ( ) as libc:: c_int ,
193+ source. as_mut_ptr ( ) ,
194+ app_opts. as_ptr ( ) ,
195+ ptr:: null_mut ( ) ,
196+ )
197+ } ;
198+ if ds_c. is_null ( ) {
199+ Err ( _last_null_pointer_err ( "GDALWarp" ) )
200+ } else {
201+ Ok ( ds)
202+ }
203+ }
204+ WarpDestination :: Path ( p) => {
205+ let path = _path_to_c_string ( & p) ?;
206+ let ds_c = unsafe {
207+ GDALWarp (
208+ path. as_ptr ( ) ,
209+ ptr:: null_mut ( ) ,
210+ source. len ( ) as libc:: c_int ,
211+ source. as_ptr ( ) as * mut GDALDatasetH ,
212+ app_opts. as_ptr ( ) ,
213+ ptr:: null_mut ( ) ,
214+ )
215+ } ;
216+ Ok ( unsafe { Dataset :: from_c_dataset ( ds_c) } )
217+ }
218+ }
219+ }
220+
221+ #[ derive( Debug ) ]
222+ pub enum WarpDestination {
223+ Dataset ( Dataset ) ,
224+ Path ( PathBuf ) ,
225+ }
226+
227+ impl From < Dataset > for WarpDestination {
228+ fn from ( ds : Dataset ) -> Self {
229+ WarpDestination :: Dataset ( ds)
230+ }
231+ }
232+
233+ impl From < PathBuf > for WarpDestination {
234+ fn from ( path : PathBuf ) -> Self {
235+ WarpDestination :: Path ( path)
236+ }
237+ }
238+
166239#[ cfg( test) ]
167240mod tests {
168241 use super :: * ;
@@ -251,4 +324,21 @@ mod tests {
251324
252325 Ok ( ( ) )
253326 }
327+
328+ #[ test]
329+ #[ ignore]
330+ fn test_warp ( ) -> Result < ( ) > {
331+ let source = TempFixture :: fixture ( "labels.tif" ) ;
332+ let source_ds = Dataset :: open ( & source) ?;
333+ let dest = Path :: new ( "target" ) . join ( "labels-warp.tif" ) ;
334+
335+ let mut options = GdalWarpOptions :: default ( ) ;
336+ options
337+ . with_band_count ( source_ds. raster_count ( ) )
338+ . with_initial_value ( InitValue :: NoData )
339+ . with_resampling_alg ( WarpResampleAlg :: NearestNeighbour ) ;
340+
341+ warp ( & source_ds, dest, & options) ?;
342+ Ok ( ( ) )
343+ }
254344}
0 commit comments