<div dir="ltr"><div><div class="gmail_signature"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>
I'm using GDAL v2.1.3 with the SWIG bindings in my custom C# application.</div><div><br></div><div>I've created a method to do some calculation of my raster file:</div><div><div><font face="monospace, monospace">public bool GdalCalculate(string input, string output, string formula, double? minValue = null)</font></div><div><font face="monospace, monospace">{</font></div><div><font face="monospace, monospace"> if (!File.Exists(input))</font></div><div><font face="monospace, monospace"> throw new FileNotFoundException("Can't find the input file", new Exception("Working with " + input));</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // 1. First copy the input file to create the output file</font></div><div><font face="monospace, monospace"> try</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> /* -------------------------------------------------------------------- */</font></div><div><font face="monospace, monospace"> /* Get driver */</font></div><div><font face="monospace, monospace"> /* -------------------------------------------------------------------- */</font></div><div><font face="monospace, monospace"> using (var drv = Gdal.GetDriverByName("GTiff"))</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> if (drv == null)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("Can't get GTiff driver");<br></font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> /* -------------------------------------------------------------------- */</font></div><div><font face="monospace, monospace"> /* Open dataset. */</font></div><div><font face="monospace, monospace"> /* -------------------------------------------------------------------- */</font></div><div><font face="monospace, monospace"> using (var ds = Gdal.Open(input, Access.GA_ReadOnly))</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> if (ds == null)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("Can't open GDAL dataset: " + input);</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> var options = new[] { "" };</font></div><div><font face="monospace, monospace"> using (var newDataset = drv.CreateCopy(output, ds, 0, options, null, "Sample Data"))</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> if (newDataset == null)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("Can't create destination dataset: " + output);</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // Close input dataset:</font></div><div><font face="monospace, monospace"> ds.Dispose();</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // 2. Loop through all pixels and perform formula on it:</font></div><div><font face="monospace, monospace"> using (var band = newDataset.GetRasterBand(1))</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> double noData;</font></div><div><font face="monospace, monospace"> int hasValue;</font></div><div><font face="monospace, monospace"> band.GetNoDataValue(out noData, out hasValue);</font></div><div><font face="monospace, monospace"> var sizeX = band.XSize;</font></div><div><font face="monospace, monospace"> var numLines = band.YSize;</font></div><div><font face="monospace, monospace"> var func = new Function("f(A) = " + formula);</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // Loop through each line in turn.</font></div><div><font face="monospace, monospace"> for (var line = 0; line < numLines; line++)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> var scanline = new float[sizeX];</font></div><div><font face="monospace, monospace"> // Read in data for the current line</font></div><div><font face="monospace, monospace"> var cplReturn = band.ReadRaster(0, line, sizeX, 1, scanline, sizeX, 1, 0, 0);</font></div><div><font face="monospace, monospace"> if (cplReturn != CPLErr.CE_None)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("band.ReadRaster failed: " + Gdal.GetLastErrorMsg());</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> var outputLine = new List<float>();</font></div><div><font face="monospace, monospace"> foreach (var f in scanline)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> var pixelValue = f;</font></div><div><font face="monospace, monospace"> if ((float)f != (float)noData)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> // Calculate</font></div><div><font face="monospace, monospace"> pixelValue = (float)func.calculate(f);</font></div><div><font face="monospace, monospace"> if (minValue.HasValue)</font></div><div><font face="monospace, monospace"> pixelValue = (float)Math.Max(pixelValue, minValue.GetValueOrDefault());</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> outputLine.Add(pixelValue);</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // Rewrite line:</font></div><div><font face="monospace, monospace"> cplReturn = band.WriteRaster(0, line, sizeX, 1, outputLine.ToArray(), sizeX, 1, 0, 0);</font></div><div><font face="monospace, monospace"> if (cplReturn != CPLErr.CE_None)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("band.WriteRaster failed: " + Gdal.GetLastErrorMsg());</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> // 3. Save changes to file:</font></div><div><font face="monospace, monospace"> band.FlushCache();</font></div><div><font face="monospace, monospace"> newDataset.FlushCache();</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> catch (Exception e)</font></div><div><font face="monospace, monospace"> {</font></div><div><font face="monospace, monospace"> throw new Exception("Can't open GDAL dataset: " + input, e);</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"><br></font></div><div><font face="monospace, monospace"> return true;</font></div><div><font face="monospace, monospace">}</font></div></div><div><br></div><div>This method is working fine, but is very slow. </div><div>I'm using a 3621x4466 tiff file, which has a size of 67MB.</div><div>It is taking around 10 minutes to process.</div><div><span style="font-family:monospace,monospace">(float)func.calculate(f);</span> is using <a href="http://mathparser.org/">http://mathparser.org/</a></div><div>An example of a function I'm using: <font face="monospace, monospace">9.7E-05-e^(3.1 + 0.9 * A)</font> where A is the pixel value.</div><div><br></div><div>How can I optimize my function? </div><div><br></div><div>Thanks,</div><div><br></div><div>Paul</div><div><br></div></div></div></div></div></div>
</div>