[gdal-dev] Raster calculation optimalisation
Jan Heckman
jan.heckman at gmail.com
Tue Jun 13 06:51:46 PDT 2017
Maybe it does not compile the formula but runs parser etc. as a kind of
interpreter at each function call.
Googled and saw http://beltoforion.de/article.php?a=muparsersse. Did not
try, so no recommendation, let alone guarantee ;)
You could check by defining a test function explicitly, if it is much
faster when compiled directly, that should be it, I guess.
Good luck,
Jan
On Tue, Jun 13, 2017 at 1:20 PM, Paul Meems <bontepaarden at gmail.com> wrote:
> I'm using GDAL v2.1.3 with the SWIG bindings in my custom C# application.
>
> I've created a method to do some calculation of my raster file:
> public bool GdalCalculate(string input, string output, string formula,
> double? minValue = null)
> {
> if (!File.Exists(input))
> throw new FileNotFoundException("Can't find the input file", new
> Exception("Working with " + input));
>
> // 1. First copy the input file to create the output file
> try
> {
> /* --------------------------------------------------------------------
> */
> /* Get driver
> */
> /* --------------------------------------------------------------------
> */
> using (var drv = Gdal.GetDriverByName("GTiff"))
> {
> if (drv == null)
> {
> throw new Exception("Can't get GTiff driver");
> }
>
> /* ------------------------------
> -------------------------------------- */
> /* Open dataset.
> */
> /* ------------------------------
> -------------------------------------- */
> using (var ds = Gdal.Open(input, Access.GA_ReadOnly))
> {
> if (ds == null)
> {
> throw new Exception("Can't open GDAL dataset: " +
> input);
> }
>
> var options = new[] { "" };
> using (var newDataset = drv.CreateCopy(output, ds, 0,
> options, null, "Sample Data"))
> {
> if (newDataset == null)
> {
> throw new Exception("Can't create destination
> dataset: " + output);
> }
>
> // Close input dataset:
> ds.Dispose();
>
> // 2. Loop through all pixels and perform formula on
> it:
> using (var band = newDataset.GetRasterBand(1))
> {
> double noData;
> int hasValue;
> band.GetNoDataValue(out noData, out hasValue);
> var sizeX = band.XSize;
> var numLines = band.YSize;
> var func = new Function("f(A) = " + formula);
>
> // Loop through each line in turn.
> for (var line = 0; line < numLines; line++)
> {
> var scanline = new float[sizeX];
> // Read in data for the current line
> var cplReturn = band.ReadRaster(0, line,
> sizeX, 1, scanline, sizeX, 1, 0, 0);
> if (cplReturn != CPLErr.CE_None)
> {
> throw new Exception("band.ReadRaster
> failed: " + Gdal.GetLastErrorMsg());
> }
>
> var outputLine = new List<float>();
> foreach (var f in scanline)
> {
> var pixelValue = f;
> if ((float)f != (float)noData)
> {
> // Calculate
> pixelValue = (float)func.calculate(f);
> if (minValue.HasValue)
> pixelValue =
> (float)Math.Max(pixelValue, minValue.GetValueOrDefault());
> }
> outputLine.Add(pixelValue);
> }
>
> // Rewrite line:
> cplReturn = band.WriteRaster(0, line, sizeX,
> 1, outputLine.ToArray(), sizeX, 1, 0, 0);
> if (cplReturn != CPLErr.CE_None)
> {
> throw new Exception("band.WriteRaster
> failed: " + Gdal.GetLastErrorMsg());
> }
> }
>
> // 3. Save changes to file:
> band.FlushCache();
> newDataset.FlushCache();
> }
> }
> }
> }
> }
> catch (Exception e)
> {
> throw new Exception("Can't open GDAL dataset: " + input, e);
> }
>
> return true;
> }
>
> This method is working fine, but is very slow.
> I'm using a 3621x4466 tiff file, which has a size of 67MB.
> It is taking around 10 minutes to process.
> (float)func.calculate(f); is using http://mathparser.org/
> An example of a function I'm using: 9.7E-05-e^(3.1 + 0.9 * A) where A is
> the pixel value.
>
> How can I optimize my function?
>
> Thanks,
>
> Paul
>
>
> _______________________________________________
> gdal-dev mailing list
> gdal-dev at lists.osgeo.org
> https://lists.osgeo.org/mailman/listinfo/gdal-dev
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osgeo.org/pipermail/gdal-dev/attachments/20170613/d0949938/attachment.html>
More information about the gdal-dev
mailing list