Beispiel #1
0
        /// <summary>
        /// Computes an IDW surface interpolation using a gradient to take into account differces from a raster
        /// Usefull for climatological data as perform a temperature correction based on terrain elevation
        /// </summary>
        /// <param name="OutputGTiffFile"></param>
        public static void IdwTemperaturesWithElevationCorrection(string OutputGTiffFile, List <Geometry> Points)
        {
            // Datos del malla de salida
            int    EPSG      = 23030;
            double CellSize  = 10000;
            double CellSizeX = CellSize;
            double CellSizeY = CellSize;
            double xMin      = 360000;
            double yMax      = 4830000;
            int    NumCols   = 59;
            int    NumRows   = 39;
            double yMin      = yMax - (NumRows * CellSize);
            double xMax      = xMin + (NumCols * CellSize);

            var CorrectionGradient = -0.65d;
            var IdwExponent        = 3d;

            //---------------------------------------------
            // Filter points with NoData in value or in elevation
            //---------------------------------------------
            Points = Points.Where(po => !double.IsNaN(po.GetM(0)) && !double.IsNaN(po.GetZ(0))).ToList();
            logger.Trace($"INICIANDO con {Points.Count} termómetros.");
            //---------------------------------------------
            // Compute weights for each point and raster cell
            //---------------------------------------------
            var weights = new Dictionary <Geometry, double[, ]>();
            var locker  = new object();

            Parallel.ForEach(Points, (p) => {
                double dXPunto = p.GetX(0);
                double dYPunto = p.GetY(0);

                // Para cada celda del mallado de la aplicación
                double[,] coeficients = new double[NumRows, NumCols];
                for (int i = 0; i < NumRows; i++)
                {
                    for (int j = 0; j < NumCols; j++)
                    {
                        double CellX = xMin + (j * CellSizeX) + (CellSizeX / 2);
                        double CellY = yMax - ((i * CellSizeY) + (CellSizeY / 2));
                        // Se calcula la distancia entre celda y punto como número de pasos, para evitar valores muy grandes
                        double distancia = System.Math.Sqrt(System.Math.Pow((dXPunto - CellX), 2) / (CellSizeX) + System.Math.Pow((dYPunto - CellY), 2) / (CellSizeY));
                        distancia        = Math.Max(distancia, 0.0000001d);
                        // Se calculan coeficientes, multiplicados por una costante, para evitar valores muy pequeños
                        coeficients[i, j] = (1 / (System.Math.Pow(distancia, IdwExponent))) * (10 ^ 3);
                    }
                }
                lock (locker) weights.Add(p, coeficients);
            });
            logger.Trace($"Pesos computados.");

            //---------------------------------------------
            // Compute elevations for each raster cell from DEM
            // AKIIII => read with gdal, retornar double.NAN en caso de nulo
            //---------------------------------------------
            double GetElevation(double x, double y)
            {
                return(200d);
            };

            //---------------------------------------------
            // Compute raster values
            //---------------------------------------------
            var ResultData = new float[NumRows, NumCols];

            for (int i = 0; i < NumRows; i++)
            {
                for (int j = 0; j < NumCols; j++)
                {
                    ResultData[i, j] = float.NaN;
                }
            }

            double CellValue;
            double WeightsSum;// Acumula la suma de los coeficientes válidos para luego dividir por ella

            //------------------------------------------------------------
            // Iterar por todas las celdas del mallado a crear
            //------------------------------------------------------------
            for (int i = 0; i < NumRows; i++)
            {
                logger.Trace($"Tratando fila {i} de {NumRows}.");
                for (int j = 0; j < NumCols; j++)
                {
                    // Inicializar
                    CellValue  = 0d;
                    WeightsSum = 0d;

                    //------------------------------------------------------------
                    // Calcular el valor para la celda i,j
                    //------------------------------------------------------------
                    // Obtner el sumatorio de los C1V1 + C2V2 + ... + CnVn
                    foreach (var p in Points)
                    {
                        double dValAux   = p.GetM(0);
                        double Elevation = p.GetZ(0);
                        if (!double.IsNaN(dValAux))
                        {
                            //-------------------------------------------------------------------------
                            //  Aplicamos corrección de valor por cota:
                            // Búsqueda de la cota de la celda
                            //-------------------------------------------------------------------------
                            double dCeldaX = xMin + (i * CellSizeX) + (CellSizeX / 2d);
                            double dCeldaY = yMax - ((j * CellSizeY) + (CellSizeY / 2d));

                            // Get current cell elevation
                            double CellElevation = GetElevation(dCeldaX, dCeldaY);

                            //------------------------------------------------------------------------------------------
                            // No se aplica el gradiente termométrico a las celdas sobre las que no tenemos cota
                            //------------------------------------------------------------------------------------------
                            if (!double.IsNaN(CellElevation))
                            {
                                //---------------------------------------------
                                // Cálculo del valor de temperatura modificado
                                //---------------------------------------------
                                dValAux += CorrectionGradient * (CellElevation - Elevation) / 100;
                            }
                            double weight = weights[p][i, j];
                            CellValue  += weight * dValAux;
                            WeightsSum += weight;
                        }
                    }
                    // Obtener el valor dividiendo por SUM(C1 ... Cn)
                    if (WeightsSum != 0)
                    {
                        ResultData[i, j] = (float)(CellValue / WeightsSum);
                    }
                }
            }

            // Create results raster
            logger.Trace($"Creando gtif...");
            var datos = new float[NumRows * NumCols];
            var cont  = 0;

            for (int i = NumRows - 1; i >= 0; i--)
            {
                for (int j = 0; j < NumCols; j++)
                {
                    datos[cont] = ResultData[i, j];
                    cont++;
                }
            }

            // Create output GTiff
            if (File.Exists(OutputGTiffFile))
            {
                File.Delete(OutputGTiffFile);
            }
            string EsriWkt  = GdalUtils.EPSG2WKT(EPSG);
            var    GeoTrans = new[] { xMin, CellSize, 0, yMin, 0, CellSize };

            GdalUtils.CreateRaster("GTiff", OutputGTiffFile, NumRows, NumCols, xMin, yMin, CellSize, EsriWkt, GeoTrans, new List <float[]>()
            {
                datos
            }, null, null);
            logger.Trace($"Creado {OutputGTiffFile}");
        }
        public static void Info(string FileName, bool ShowBands)
        {
            try
            {
                /* -------------------------------------------------------------------- */
                /*      Open dataset.                                                   */
                /* -------------------------------------------------------------------- */
                Dataset ds = Gdal.Open(FileName, Access.GA_ReadOnly);
                if (ds == null)
                {
                    Console.WriteLine("Can't open " + FileName);
                    System.Environment.Exit(-1);
                }

                Console.WriteLine("Raster dataset parameters:");
                Console.WriteLine("  Projection: " + ds.GetProjectionRef());
                Console.WriteLine("  RasterCount: " + ds.RasterCount);
                Console.WriteLine("  RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")");

                /* -------------------------------------------------------------------- */
                /*      Get driver                                                      */
                /* -------------------------------------------------------------------- */
                Driver drv = ds.GetDriver();

                if (drv == null)
                {
                    Console.WriteLine("Can't get driver.");
                    System.Environment.Exit(-1);
                }

                Console.WriteLine("Using driver " + drv.LongName);

                /* -------------------------------------------------------------------- */
                /*      Get metadata                                                    */
                /* -------------------------------------------------------------------- */
                string[] metadata = ds.GetMetadata("");
                if (metadata.Length > 0)
                {
                    Console.WriteLine("  Metadata:");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        Console.WriteLine("    " + iMeta + ":  " + metadata[iMeta]);
                    }
                    Console.WriteLine("");
                }

                /* -------------------------------------------------------------------- */
                /*      Report "IMAGE_STRUCTURE" metadata.                              */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("IMAGE_STRUCTURE");
                if (metadata.Length > 0)
                {
                    Console.WriteLine("  Image Structure Metadata:");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        Console.WriteLine("    " + iMeta + ":  " + metadata[iMeta]);
                    }
                    Console.WriteLine("");
                }

                /* -------------------------------------------------------------------- */
                /*      Report subdatasets.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("SUBDATASETS");
                if (metadata.Length > 0)
                {
                    Console.WriteLine("  Subdatasets:");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        Console.WriteLine("    " + iMeta + ":  " + metadata[iMeta]);
                    }
                    Console.WriteLine("");
                }

                /* -------------------------------------------------------------------- */
                /*      Report geolocation.                                             */
                /* -------------------------------------------------------------------- */
                metadata = ds.GetMetadata("GEOLOCATION");
                if (metadata.Length > 0)
                {
                    Console.WriteLine("  Geolocation:");
                    for (int iMeta = 0; iMeta < metadata.Length; iMeta++)
                    {
                        Console.WriteLine("    " + iMeta + ":  " + metadata[iMeta]);
                    }
                    Console.WriteLine("");
                }

                string GetPosition(Dataset ds, double column, double row)
                {
                    var d = GdalUtils.GDALInfoGetPosition(ds, column, row);

                    return($"{d[0].ToString()} , {d[1].ToString()} ");
                }

                /* -------------------------------------------------------------------- */
                /*      Report corners.                                                 */
                /* -------------------------------------------------------------------- */
                Console.WriteLine("Corner Coordinates:");
                Console.WriteLine("  Upper Left (" + GetPosition(ds, 0.0, 0.0) + ")");
                Console.WriteLine("  Lower Left (" + GetPosition(ds, 0.0, ds.RasterYSize) + ")");
                Console.WriteLine("  Upper Right (" + GetPosition(ds, ds.RasterXSize, 0.0) + ")");
                Console.WriteLine("  Lower Right (" + GetPosition(ds, ds.RasterXSize, ds.RasterYSize) + ")");
                Console.WriteLine("  Center (" + GetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + ")");
                Console.WriteLine("");

                /* -------------------------------------------------------------------- */
                /*      Report projection.                                              */
                /* -------------------------------------------------------------------- */
                string projection = ds.GetProjectionRef();
                if (projection != null)
                {
                    SpatialReference srs = new SpatialReference(null);
                    if (srs.ImportFromWkt(ref projection) == 0)
                    {
                        string wkt;
                        srs.ExportToPrettyWkt(out wkt, 0);
                        Console.WriteLine("Coordinate System is:");
                        Console.WriteLine(wkt);
                    }
                    else
                    {
                        Console.WriteLine("Coordinate System is:");
                        Console.WriteLine(projection);
                    }
                }

                /* -------------------------------------------------------------------- */
                /*      Report GCPs.                                                    */
                /* -------------------------------------------------------------------- */
                if (ds.GetGCPCount( ) > 0)
                {
                    Console.WriteLine("GCP Projection: ", ds.GetGCPProjection());
                    GCP[] GCPs = ds.GetGCPs();
                    for (int i = 0; i < ds.GetGCPCount(); i++)
                    {
                        Console.WriteLine("GCP[" + i + "]: Id=" + GCPs[i].Id + ", Info=" + GCPs[i].Info);
                        Console.WriteLine("          (" + GCPs[i].GCPPixel + "," + GCPs[i].GCPLine + ") -> ("
                                          + GCPs[i].GCPX + "," + GCPs[i].GCPY + "," + GCPs[i].GCPZ + ")");
                        Console.WriteLine("");
                    }
                    Console.WriteLine("");

                    double[] transform = new double[6];
                    Gdal.GCPsToGeoTransform(GCPs, transform, 0);
                    Console.WriteLine("GCP Equivalent geotransformation parameters: ", ds.GetGCPProjection());
                    for (int i = 0; i < 6; i++)
                    {
                        Console.WriteLine("t[" + i + "] = " + transform[i].ToString());
                    }
                    Console.WriteLine("");
                }

                /* -------------------------------------------------------------------- */
                /*      Get raster band                                                 */
                /* -------------------------------------------------------------------- */
                for (int iBand = 1; iBand <= ds.RasterCount && ShowBands; iBand++)
                {
                    Band band = ds.GetRasterBand(iBand);
                    Console.WriteLine("Band " + iBand + " :");
                    Console.WriteLine("   DataType: " + Gdal.GetDataTypeName(band.DataType));
                    Console.WriteLine("   ColorInterpretation: " + Gdal.GetColorInterpretationName(band.GetRasterColorInterpretation()));
                    ColorTable ct = band.GetRasterColorTable();
                    if (ct != null)
                    {
                        Console.WriteLine("   Band has a color table with " + ct.GetCount() + " entries.");
                    }

                    Console.WriteLine("   Description: " + band.GetDescription());
                    Console.WriteLine("   Size (" + band.XSize + "," + band.YSize + ")");
                    int BlockXSize, BlockYSize;
                    band.GetBlockSize(out BlockXSize, out BlockYSize);
                    Console.WriteLine("   BlockSize (" + BlockXSize + "," + BlockYSize + ")");
                    double val;
                    int    hasval;
                    band.GetMinimum(out val, out hasval);
                    if (hasval != 0)
                    {
                        Console.WriteLine("   Minimum: " + val.ToString());
                    }
                    band.GetMaximum(out val, out hasval);
                    if (hasval != 0)
                    {
                        Console.WriteLine("   Maximum: " + val.ToString());
                    }
                    band.GetNoDataValue(out val, out hasval);
                    if (hasval != 0)
                    {
                        Console.WriteLine("   NoDataValue: " + val.ToString());
                    }
                    band.GetOffset(out val, out hasval);
                    if (hasval != 0)
                    {
                        Console.WriteLine("   Offset: " + val.ToString());
                    }
                    band.GetScale(out val, out hasval);
                    if (hasval != 0)
                    {
                        Console.WriteLine("   Scale: " + val.ToString());
                    }

                    for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++)
                    {
                        Band over = band.GetOverview(iOver);
                        Console.WriteLine("      OverView " + iOver + " :");
                        Console.WriteLine("         DataType: " + over.DataType);
                        Console.WriteLine("         Size (" + over.XSize + "," + over.YSize + ")");
                        Console.WriteLine("         PaletteInterp: " + over.GetRasterColorInterpretation().ToString());
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine("Application error: " + e.Message);
            }
        }