<div dir="ltr"><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Hi Paul,</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">What is the time to run your code without applying the calculation to each pixel?</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">It is usually better to process the pixels in a block rather than walking across each row especially if you are processing a TIFF as these are usually stored as tiles (blocks).</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">The crossing from C# to C++ will also impact the performance so take a look at the time it takes to set the pixels. There may also be a method to set a block of pixels.</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Sorry I can't help you more than some general advice and hints.</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Regards</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif">Damian</div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div><div class="gmail_default" style="font-family:trebuchet ms,sans-serif"><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On 13 June 2017 at 12:20, 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_8458320473042962887gmail_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>