My iOS app allows users to reproject rasters to different spatial reference systems. This is implemented with GDAL Utils (C API, in a Swift wrapper) to run a GDALWarp(). Sometimes these operations can take a long time for large rasters.
My users would like to have a 'Cancel' button but I'm not sure of the best way to actually cancel a GDALWarp() while it is in progress. The GDALWarp() is run within a function that is within a separate Operation (thread-handling object), and in theory I could easily cancel the Operation object and dismiss the progress dialogue in the GUI. But this would leave the warp running in the background, consuming power, CPU, RAM and storage, (and quite a lot of all four), so this would not be acceptable. I still need the cancellation to actually kill the GDALWarp().
Here's how I currently run the warp (this is Swift code utilising GDAL Utils C API):
func reprojectTo(_ url: URL, driver: Driver, srs: SRS) -> (Bool, Int32?) {
guard let destSRSWKT = srs.wkt() else { return (false, nil) }
let opts = ["-t_srs", destSRSWKT, "-r", "cubic", "-dstalpha", "-of", driver.nameShort()]
return withMutableArrayOfMutableCStrings(opts) { (cOpts) in
var optionalSourceDSRef: GDALDatasetH? = _ds
return withUnsafeMutablePointer(to: &optionalSourceDSRef) { (dsPointer) in
let warpOpts = GDALWarpAppOptionsNew(cOpts, nil)
var err: Int32 = 0
let destDSRef = GDALWarp(url.path, nil, 1, dsPointer, warpOpts, &err)
GDALWarpAppOptionsFree(warpOpts)
if destDSRef == nil {
logger.error("FAILED to warp with driver \(driver.nameShort()) to SRS \(srs.authorityCode() ?? "(?)") at:\n\(url)")
return (false, err)
} else {
GDALClose(destDSRef)
return (true, nil)
}
}
}
}
What's the correct way to completely kill a running GDALWarp()?