Example #1
0
 public static bool Warp(
     string inputFile, string outputFile, string[] options)
 {
     using (Dataset inputds = Gdal.Open(
                inputFile, Access.GA_ReadOnly))
     {
         if (inputds == null)
         {
             return(false);
         }
         IntPtr[] ptr      = { Dataset.getCPtr(inputds).Handle };
         GCHandle gcHandle = GCHandle.Alloc(ptr, GCHandleType.Pinned);
         Dataset  result   = null;
         try
         {
             SWIGTYPE_p_p_GDALDatasetShadow dss =
                 new SWIGTYPE_p_p_GDALDatasetShadow(
                     gcHandle.AddrOfPinnedObject(), false, null);
             result = Gdal.wrapper_GDALWarpDestName(
                 outputFile, 1, dss,
                 new GDALWarpAppOptions(options), null, null);
             if (result == null)
             {
                 throw new Exception("GdalWarp failed: " +
                                     Gdal.GetLastErrorMsg());
             }
         }
         catch (Exception) { return(false); }
         finally
         {
             gcHandle.Free();
             result.Dispose();
         }
     }
     return(true);
 }
Example #2
0
        static void Main(string[] args)
        {
            var SO = "WIN";

            if (RuntimeInformation.IsOSPlatform(OSPlatform.Linux))
            {
                SO = "LINUX";
            }
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                SO = "WIN";
            }
            if (RuntimeInformation.IsOSPlatform(OSPlatform.OSX))
            {
                Console.WriteLine("MAC not supported"); System.Environment.Exit(0);
            }

            /* -------------------------------------------------------------------- */
            /*      Read config file  .                                             */
            /* -------------------------------------------------------------------- */
            var env     = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
            var builder = new ConfigurationBuilder()
                          .AddJsonFile("appsettings.json", true, true)
                          .AddJsonFile($"appsettings.{SO}.json", true, true)
                          .AddJsonFile($"appsettings.{env}.json", true, true)
                          .AddEnvironmentVariables();

            config = builder.Build();
            logger.Debug($"Configuration: {config.GetDebugView()}");
            // https://blog.bitscry.com/2017/11/14/reading-lists-from-appsettings-json/
            //List<string> PolygonsLayers = config.GetSection("CATCHMENTS_LAYERS").Get<List<string>>();

            var datapath = config["DATA_PATH"];

            if (!Directory.Exists(datapath))
            {
                logger.Error($"No se ha encontrado la ruta de datos {datapath}");
            }

            /* -------------------------------------------------------------------- */
            /*      Configure GDal driver(s).                                       */
            /* -------------------------------------------------------------------- */
            try
            {
                Gdal.PushErrorHandler(GdalUtils.GDalErrorHandler);
                GdalUtils.Configure();
                Gdal.UseExceptions();
            }
            catch (Exception ex)
            {
                logger.Error(ex, ex.StackTrace + " " + Gdal.GetLastErrorMsg());
            }

            // Lectura de datos de AEMet de GNavarra (radares individuales) y traducción a TIFF
            if (false)
            {
                var TarsDir = @"C:\XXX\GeoTiffTests\data\GNavarra_AEMet.tar\Radar\RAD_ZAR.2021030.00.tar\";
                foreach (var f in Directory.GetFiles(TarsDir, "*.tar"))
                {
                    ReadAEMetRadarFile(f, datapath);
                }
                System.Environment.Exit(1);
            }

            // Lectura de datos de AEMet (composición radar) y traducción a GeoTIFF
            if (false)
            {
                var GZsDir = @"C:\Users\Administrador.000\Desktop\Nueva carpeta\";
                foreach (var f in Directory.GetFiles(GZsDir, "ACUM-RAD-*.gz"))
                {
                    Console.WriteLine(f);
                    UncompressFiles(f, GZsDir);
                }
                foreach (var f in Directory.GetFiles(GZsDir, "AREA????"))
                {
                    var output = Path.ChangeExtension(f, ".tiff");
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }

                    object raster_metedata = new {
                        type              = "AEMet_radar",
                        ogirin            = $"{f}",
                        creation_time_utc = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss")
                    };
                    AREAnnnToGTiff(f, output, JsonConvert.SerializeObject(raster_metedata), JsonConvert.SerializeObject(new {}));
                    logger.Info($"Creado {output} desde AREAnnnn ({f})");
                }
                System.Environment.Exit(1);
            }

            // Lectura de ficheros CRR-Ph, obtención de la banda de acumulación de lluvia y traducción a GeoTIFF
            if (false)
            {
                var BAND_NAME = "crrph_accum";
                foreach (var netcdf in Directory.GetFiles("C:/XXX/Navarra/smb-gnavarra-crr/", "*.nc"))
                {
                    logger.Info($"CRR-Ph NetCDf to GeoTIFF {netcdf}");
                    object raster_metedata = new {
                        type              = "CRR-Ph",
                        ogirin            = $"{netcdf}",
                        creation_time_utc = DateTime.Now.ToUniversalTime().ToString("yyyyMMddHHmmss")
                    };
                    using (Dataset ds = Gdal.Open(netcdf, Access.GA_ReadOnly))
                    {
                        var list = ds.GetMetadata("SUBDATASETS").Cast <string>().ToList();
                        //Console.WriteLine($"  {string.Join(" \r\n", list)}");
                        foreach (var subdataset in list.Where(s => s.Contains("_NAME=") && s.Contains(BAND_NAME, StringComparison.OrdinalIgnoreCase)))
                        {
                            logger.Info($"Subdataset: {subdataset}");
                            Console.WriteLine($"  {subdataset}");
                            var InputFileName  = subdataset.Split("=")[1];
                            var OutputFileName = $"C:/XXX/Navarra/smb-gnavarra-crr/{Path.GetFileNameWithoutExtension(netcdf)}_{subdataset.Split("//")[1]}.tiff";
                            CrrPhNetCDFToGTiff(InputFileName, OutputFileName, JsonConvert.SerializeObject(raster_metedata), JsonConvert.SerializeObject(new {}));
                        }
                    }
                }
                ;
                //var netcdf = "C:/XXX/Navarra/smb-gnavarra-crr/S_NWC_CRR-Ph_MSG4_AEMET-VISIR_20210310T230000Z.nc";
                //-2854883.8 3000.4033 0 4979169.5 0 -3000.4033
            }

            // Equal rasters sum
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("===========================SUM rasters (--)==================================");
                var InputRaster = Path.Combine(datapath, "2021036.120000.RAD_ZAR - copia.tiff");
                GdalUtils.SumRasters(Directory.GetFiles(datapath, "2021036.??0000.RAD_ZAR.tiff"), Path.Combine(datapath, "sumaParalelo.tiff"));
            }
            // Coordinates reprojection
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("===========================REPROJECTION coordinate testing  (OK)==================================");
                try
                {
                    var ret = GdalUtils.ReprojectCoordinates(23030, 4326, 85530d, 446100d, 0d);
                }
                catch (Exception ex)
                {
                    logger.Error(ex, ex.StackTrace + " " + Gdal.GetLastErrorMsg());
                }
            }
            // Gdal info: información sobre la carga de GDAL
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("===========================GDAL INFO==================================");
                try
                {
                    GdalUtils.GetGdalInfo();
                }
                catch (Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // Create TIFF and adding bands
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================Crear GTiff y añadir bandas =====================================");
                try
                {
                    var output = Path.Combine(datapath, "CreateRasterNew.tiff");
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }

                    int    NRows    = 200;
                    int    Ncols    = 100;
                    double MinX     = 55;
                    double MinY     = 45;
                    double CellSize = 0.1;
                    string src_wkt  = GdalUtils.EPSG2WKT(4326);

                    var valores = new List <float[]>();
                    for (var band = 0; band < 5; band++)
                    {
                        var buffer = new float [NRows * Ncols];
                        for (int i = 0; i < Ncols; i++)
                        {
                            for (int j = 0; j < NRows; j++)
                            {
                                buffer[i * Ncols + j] = (float)(i * 256 / Ncols) * band;
                            }
                        }
                        valores.Add(buffer);
                    }
                    var GeoTrans = new[] { MinX, CellSize, 0, MinY, 0, CellSize };
                    GdalUtils.CreateRaster("GTiff", output, NRows, Ncols, MinX, MinY, CellSize, src_wkt, GeoTrans, valores, null, null);
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // Raster reprojection
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================Raster reprojection =====================================");
                try
                {
                    int OutEpsg = 23030;
                    var input   = Path.Combine(datapath, "CreateRaster.tiff");
                    var output  = Path.Combine(datapath, $"CreateRasterNew{OutEpsg}.tiff");
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }
                    GdalUtils.RasterReprojection(input, output, OutEpsg);
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // GDAL Translate GRIB2 => GTiff
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================Translate GRIB2 => GTiff (OK) =====================================");
                try
                {
                    // Funciona pero tarda mucho:
                    var input  = Path.Combine(datapath, "pluviometrosIDW.tiff");
                    var output = Path.Combine(datapath, "pluviometrosIDW.asc");
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }
                    GdalUtils.TranslateRasterFormat(input, output, "AAIGrid");
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // IDW with gradient correction
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================IDW con gradiente (OK)=====================================");
                try
                {
                    double CellSize = 10000;
                    double xMin     = 360000;
                    double yMax     = 4830000;
                    int    NumCols  = 59;
                    int    NumRows  = 39;
                    double yMin     = yMax - (NumRows * CellSize);
                    double xMax     = xMin + (NumCols * CellSize);
                    Random random   = new Random();
                    double GetRandomNumber(double minimum, double maximum)
                    {
                        return(random.NextDouble() * (maximum - minimum) + minimum);
                    }
                    int NumTermometros = 350;
                    var Points         = new List <OSGeo.OGR.Geometry>();
                    // Add more points
                    for (int w = 1; w < NumTermometros; w++)
                    {
                        var pnew = new Geometry(wkbGeometryType.wkbPoint);
                        pnew.AddPointZM(
                            GetRandomNumber(xMin, xMax),
                            GetRandomNumber(yMin, yMax),
                            GetRandomNumber(100, 300),
                            GetRandomNumber(0, 10));
                        Points.Add(pnew);
                    }
                    SurfaceInterpolations.IdwTemperaturesWithElevationCorrection(Path.Combine(datapath, $"IdwTemperaturesWithElevationCorrection_{Points.Count}.tiff"), Points);
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // IDW with NearestNeighbour
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================IDW NN (OK)=====================================");
                try
                {
                    SurfaceInterpolations.IDWwithNearestNeighbour(Path.Combine(datapath, "pluviometros_23030.shp"), Path.Combine(datapath, "pluviometrosIDW.tiff"));
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // Create contour
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("========================Contour (OK)=====================================");
                try
                {
                    var input  = Path.Combine(datapath, "pluviometrosIDW.tiff");
                    var output = Path.Combine(datapath, "contour.shp");
                    if (File.Exists(input))
                    {
                        File.Delete(input);
                    }
                    if (File.Exists(output))
                    {
                        File.Delete(output);
                    }
                    GdalUtils.Contour(input, output, 1d, 0d);
                }
                catch (System.Exception ex)
                {
                    logger.Error(ex, Gdal.GetLastErrorMsg());
                }
            }
            // Raster info: Geotiff multiband
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("=============================Info GEOTIFF Multiband======================================");
                GDALInfo.Info(Path.Combine(datapath, "CHEBROe00.20201125.tif"), false);
            }
            // Raster info: GRIB2 multiband
            if (false)
            {
                Console.WriteLine("===================================================================");
                Console.WriteLine("==============================Info GRIB2=====================================");
                GDALInfo.Info(Path.Combine(datapath, "CHEBROe00.20201125.grib2"), true);
            }
        }
        /// <summary>
        /// Creates a GeoTIFF file
        /// </summary>
        /// <param name="GDalOutputDriver">Output driver</param>
        /// <param name="OutputFile"></param>
        /// <param name="Rows"></param>
        /// <param name="Columns"></param>
        /// <param name="SrcWkt"></param>
        /// <param name="GeoTransform"></param>
        /// <param name="RasterMetadata"></param>
        /// <param name="BandMetadata"></param>
        public static void CreateRaster(string GDalOutputDriver, string OutputFile, int Rows, int Columns, double MinX, double MinY, double CellSize, string SrcWkt, double[] GeoTransform, IEnumerable <float[]> BandsValues, string RasterMetadata, IEnumerable <string> BandMetadata)
        {
            var NumBands = 1;

            if (BandsValues != null)
            {
                NumBands = BandsValues.Count();
            }

            int height = Rows;
            int width  = Columns;
            int bXSize = width;
            int bYSize = 1;

            try
            {
                /* -------------------------------------------------------------------- */
                /*      Get drivers                                                      */
                /* -------------------------------------------------------------------- */
                var GeotiffDriver = Gdal.GetDriverByName(GDalOutputDriver);
                if (GeotiffDriver == null)
                {
                    throw new Exception($"{GDalOutputDriver} GDal driver no encontrado, ¿se ha llamado a la configuración de GDal?");
                }

                /* -------------------------------------------------------------------- */
                /*      Create geotiff dataset.                                         */
                /* -------------------------------------------------------------------- */
                string[] options = new string [] { $"BLOCKXSIZE={bXSize}", $"BLOCKYSIZE={bYSize}" };
                using (var ds = GeotiffDriver.Create(OutputFile, width, height, NumBands, DataType.GDT_Float32, options)) {
                    // Set geo transform
                    // https://stackoverflow.com/questions/27166739/description-of-parameters-of-gdal-setgeotransform
                    ds.SetGeoTransform(GeoTransform);

                    // Set coordinate system
                    ds.SetProjection(SrcWkt);

                    // Set metadata
                    ds.SetMetadataItem("SUAT.INCLAM.NET", RasterMetadata, string.Empty);

                    /* -------------------------------------------------------------------- */
                    /*      Setting corner GCPs.                                            */
                    /* -------------------------------------------------------------------- */
                    //GCP[] GCPs = new GCP[] { new GCP(44.5, 27.5, 0, 0, 0, "info0", "id0"), new GCP(45.5, 27.5, 0, 100, 0, "info1", "id1"), new GCP(44.5, 26.5, 0, 0, 100, "info2", "id2"), new GCP(45.5, 26.5, 0, 100, 100, "info3", "id3") };
                    //ds.SetGCPs(GCPs, "");

                    // Escribir bandas
                    int NumBand = 1;
                    foreach (var vals in BandsValues)
                    {
                        var BandValues = vals;
                        if (vals.Length < (width * height))
                        {
                            logger.Error(new ArgumentOutOfRangeException("BandsValues", vals, $"La longitud de los datos de la banda {NumBand} es menor que el número de filas por columnas."));
                            BandValues = new float[width * height];
                        }
                        var band = ds.GetRasterBand(NumBand);
                        band.SetNoDataValue(-9999.0);
                        if (BandMetadata != null)
                        {
                            if (BandMetadata.ElementAt(NumBand - 1) != null)
                            {
                                band.SetMetadata(BandMetadata.ElementAt(NumBand - 1), "SUAT.INCLAM.NET");
                            }
                        }
                        band.WriteRaster(0, 0, width, height, BandValues, width, height, 0, 0);
                        band.FlushCache();
                        NumBand++;
                    }

                    // Persistir a disco
                    ds.FlushCache();
                }

                /* -------------------------------------------------------------------- */
                /*      Create MEM dataset to support AddBand not during creation.      */
                /* -------------------------------------------------------------------- */

                /*
                 * var MemDriver = Gdal.GetDriverByName("MEM");
                 * OSGeo.GDAL.Dataset dsMem = null;
                 * using(var dsGeoTiff = Gdal.Open(InputRaster, Access.GA_ReadOnly)) {
                 *  dsMem = Gdal.GetDriverByName("MEM").CreateCopy("", dsGeoTiff, 0, null, (Gdal.GDALProgressFuncDelegate)GDalProgress, "GTiff to MEM copy" );
                 * }
                 * for(int band=1; band <5; band++) {
                 *
                 *  if (band>1) dsMem.AddBand(DataType.GDT_CFloat32, null);
                 *
                 *  var ba = dsMem.GetRasterBand(band);
                 *  var buffer = new float [w * h];
                 *  for (int i = 0; i < w; i++)
                 *      for (int j = 0; j < h; j++)
                 *          buffer[i * w + j] = (float)(i * 256 / w) * band;
                 *  ba.WriteRaster(0, 0, w, h, buffer, w, h, 0, 0);
                 *  ba.FlushCache();
                 * }
                 * dsMem.FlushCache();
                 *
                 * // Copy to source GeoTiff
                 * File.Delete(InputRaster);
                 * var dsTiff = GeotiffDriver.CreateCopy(InputRaster, dsMem, 0, null, (Gdal.GDALProgressFuncDelegate)GDalProgress, "MEM to Gtiff copy" );
                 *
                 * dsTiff.Dispose();
                 * dsMem.Dispose();
                 */
            }
            catch (Exception e)
            {
                logger.Error(e);
                Console.WriteLine($"Application error: {e.Message} {Gdal.GetLastErrorMsg()}");
            }
        }
Example #4
0
 /// <summary>
 /// Initializes a new instance of the <see cref="GdalException"/> class using Gdal.GetLastErrorMsg.
 /// </summary>
 public GdalException()
     : base(Gdal.GetLastErrorMsg())
 {
 }
Example #5
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string datasourceFileLocation = string.Empty;

            DA.GetData <string>(0, ref datasourceFileLocation);

            string dstFileLocation = string.Empty;

            DA.GetData <string>(1, ref dstFileLocation);

            string options = string.Empty;

            DA.GetData <string>(2, ref options);

            var re = new System.Text.RegularExpressions.Regex("(?<=\")[^\"]*(?=\")|[^\" ]+");

            string[] translateOptions = re.Matches(options).Cast <Match>().Select(m => m.Value).ToArray();

            string datasourceInfo = string.Empty;
            string dstInfo        = string.Empty;
            string dstOutput      = string.Empty;


            RESTful.GdalConfiguration.ConfigureGdal();
            OSGeo.GDAL.Gdal.AllRegister();

            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Look for more information about options at:");
            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "https://gdal.org/programs/gdal_polygonize.html");

            if (!string.IsNullOrEmpty(datasourceFileLocation))
            {
                using (Dataset datasource = Gdal.Open(datasourceFileLocation, Access.GA_ReadOnly))
                {
                    if (datasource == null)
                    {
                        throw new Exception("Can't open GDAL dataset: " + datasourceFileLocation);
                    }

                    SpatialReference sr = new SpatialReference(datasource.GetProjection());

                    ///Check if SRS needs to be converted from ESRI format to WKT to avoid error:
                    ///"No translation for Lambert_Conformal_Conic to PROJ.4 format is known."
                    ///https://gis.stackexchange.com/questions/128266/qgis-error-6-no-translation-for-lambert-conformal-conic-to-proj-4-format-is-kn
                    SpatialReference srEsri = sr;
                    srEsri.MorphFromESRI();
                    string projEsri = string.Empty;
                    srEsri.ExportToWkt(out projEsri);

                    ///If no SRS exists, check Ground Control Points SRS
                    SpatialReference srGCP   = new SpatialReference(datasource.GetGCPProjection());
                    string           projGCP = string.Empty;
                    srGCP.ExportToWkt(out projGCP);

                    if (!string.IsNullOrEmpty(projEsri))
                    {
                        datasource.SetProjection(projEsri);
                        sr = srEsri;
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Spatial Reference System (SRS) morphed form ESRI format.");
                    }
                    else if (!string.IsNullOrEmpty(projGCP))
                    {
                        datasource.SetProjection(projGCP);
                        sr = srGCP;
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Spatial Reference System (SRS) set from Ground Control Points (GCPs).");
                    }
                    else
                    {
                        AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Spatial Reference System (SRS) is unknown or unsupported.  " +
                                          "Try setting the SRS with the GdalWarp component using -t_srs EPSG:4326 for the option input.");
                        //sr.SetWellKnownGeogCS("WGS84");
                    }

                    ///Get info about image
                    List <string> infoOptions = new List <string> {
                        "-stats"
                    };
                    datasourceInfo = Gdal.GDALInfo(datasource, new GDALInfoOptions(infoOptions.ToArray()));

                    if (!string.IsNullOrEmpty(dstFileLocation))
                    {
                        if (string.IsNullOrEmpty(options) && File.Exists(dstFileLocation))
                        {
                            Dataset dst = Gdal.Open(dstFileLocation, Access.GA_ReadOnly);
                            dstInfo = Gdal.GDALInfo(dst, null);
                            dst.Dispose();
                            dstOutput = dstFileLocation;
                        }
                        else
                        {
                            ///https://github.com/OSGeo/gdal/issues/813
                            ///https://lists.osgeo.org/pipermail/gdal-dev/2017-February/046046.html
                            ///Odd way to go about setting source dataset in parameters for Warp is a known issue

                            var ptr      = new[] { Dataset.getCPtr(datasource).Handle };
                            var gcHandle = GCHandle.Alloc(ptr, GCHandleType.Pinned);
                            try
                            {
                                var     dss = new SWIGTYPE_p_p_GDALDatasetShadow(gcHandle.AddrOfPinnedObject(), false, null);
                                Dataset dst = Gdal.wrapper_GDALWarpDestName(dstFileLocation, 1, dss, new GDALWarpAppOptions(translateOptions), null, null);
                                if (dst == null)
                                {
                                    throw new Exception("GdalWarp failed: " + Gdal.GetLastErrorMsg());
                                }

                                dstInfo = Gdal.GDALInfo(dst, new GDALInfoOptions(infoOptions.ToArray()));
                                dst.Dispose();
                                dstOutput = dstFileLocation;
                            }
                            finally
                            {
                                if (gcHandle.IsAllocated)
                                {
                                    gcHandle.Free();
                                }
                            }
                        }
                    }
                    datasource.Dispose();
                }
            }

            DA.SetData(0, datasourceInfo);
            DA.SetData(1, dstInfo);
            DA.SetData(2, dstOutput);
        }
Example #6
0
        /// <summary>
        /// This is the method that actually does the work.
        /// </summary>
        /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param>
        protected override void SolveInstance(IGH_DataAccess DA)
        {
            string srcFileLocation = string.Empty;

            DA.GetData <string>(0, ref srcFileLocation);

            string dstFileLocation = string.Empty;

            DA.GetData <string>(1, ref dstFileLocation);

            string options = string.Empty;

            DA.GetData <string>(2, ref options);

            string[] translateOptions = options.Split(' ');

            string srcInfo   = string.Empty;
            string dstInfo   = string.Empty;
            string dstOutput = string.Empty;


            RESTful.GdalConfiguration.ConfigureGdal();
            OSGeo.GDAL.Gdal.AllRegister();

            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Look for more information about options at:");
            AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "https://gdal.org/programs/gdalwarp.html");

            if (!string.IsNullOrEmpty(srcFileLocation))
            {
                using (Dataset src = Gdal.Open(srcFileLocation, Access.GA_ReadOnly))
                {
                    if (src == null)
                    {
                        throw new Exception("Can't open GDAL dataset: " + srcFileLocation);
                    }

                    srcInfo = Gdal.GDALInfo(src, null);

                    if (!string.IsNullOrEmpty(dstFileLocation))
                    {
                        if (string.IsNullOrEmpty(options) && File.Exists(dstFileLocation))
                        {
                            Dataset dst = Gdal.Open(dstFileLocation, Access.GA_ReadOnly);
                            dstInfo = Gdal.GDALInfo(dst, null);
                            dst.Dispose();
                            dstOutput = dstFileLocation;
                        }
                        else
                        {
                            ///https://github.com/OSGeo/gdal/issues/813
                            ///https://lists.osgeo.org/pipermail/gdal-dev/2017-February/046046.html
                            ///Odd way to go about setting source dataset in parameters for Warp is a known issue

                            var ptr      = new[] { Dataset.getCPtr(src).Handle };
                            var gcHandle = GCHandle.Alloc(ptr, GCHandleType.Pinned);
                            try
                            {
                                var     dss = new SWIGTYPE_p_p_GDALDatasetShadow(gcHandle.AddrOfPinnedObject(), false, null);
                                Dataset dst = Gdal.wrapper_GDALWarpDestName(dstFileLocation, 1, dss, new GDALWarpAppOptions(translateOptions), null, null);
                                if (dst == null)
                                {
                                    throw new Exception("GdalWarp failed: " + Gdal.GetLastErrorMsg());
                                }

                                dstInfo = Gdal.GDALInfo(dst, null);
                                dst.Dispose();
                                dstOutput = dstFileLocation;
                            }
                            finally
                            {
                                if (gcHandle.IsAllocated)
                                {
                                    gcHandle.Free();
                                }
                            }
                        }
                    }
                    src.Dispose();
                }
            }

            DA.SetData(0, srcInfo);
            DA.SetData(1, dstInfo);
            DA.SetData(2, dstOutput);
        }