<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>