<div dir="ltr">Maybe it does not compile the formula but runs parser etc. as a kind of interpreter at each function call.<br>Googled and saw <a href="http://beltoforion.de/article.php?a=muparsersse">http://beltoforion.de/article.php?a=muparsersse</a>. Did not try, so no recommendation, let alone guarantee ;)<div>You could check by defining a test function explicitly, if it is much faster when compiled directly, that should be it, I guess.</div><div>Good luck,</div><div>Jan</div></div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Jun 13, 2017 at 1:20 PM, Paul Meems <span dir="ltr"><<a href="mailto:bontepaarden@gmail.com" target="_blank">bontepaarden@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div><div class="m_-1640264729683769852gmail_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"> /* ------------------------------<wbr>------------------------------<wbr>-------- */</font></div><div><font face="monospace, monospace"> /* Get driver */</font></div><div><font face="monospace, monospace"> /* ------------------------------<wbr>------------------------------<wbr>-------- */</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"> /* ------------------------------<wbr>------------------------------<wbr>-------- */</font></div><div><font face="monospace, monospace"> /* Open dataset. */</font></div><div><font face="monospace, monospace"> /* ------------------------------<wbr>------------------------------<wbr>-------- */</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/" target="_blank">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>
<br>______________________________<wbr>_________________<br>
gdal-dev mailing list<br>
<a href="mailto:gdal-dev@lists.osgeo.org">gdal-dev@lists.osgeo.org</a><br>
<a href="https://lists.osgeo.org/mailman/listinfo/gdal-dev" rel="noreferrer" target="_blank">https://lists.osgeo.org/<wbr>mailman/listinfo/gdal-dev</a><br></blockquote></div><br></div>