/************************************ 生成等值线 **********************************************/ public static string dzx(string filePath) { Console.WriteLine("开始创建等值线!"); OSGeo.OGR.Ogr.RegisterAll(); OSGeo.GDAL.Gdal.AllRegister(); //无效值 double noDataValue; //0不使用无效值,1使用无效值 int hasDataValue; //读入数据源 OSGeo.GDAL.Dataset inData = OSGeo.GDAL.Gdal.Open(filePath, OSGeo.GDAL.Access.GA_ReadOnly); //分析数据源 inData.GetRasterBand(1).GetNoDataValue(out noDataValue, out hasDataValue); double min, max, mean, std; inData.GetRasterBand(1).GetStatistics(0, 1, out min, out max, out mean, out std); int jianG = 2; int count = Convert.ToInt32((max - min) / jianG + 0.5); double[] shu = new double[count]; for (int i = 0; i < count; i++) { shu[i] = min + jianG * i; } //创建空的SHP OSGeo.OGR.Ogr.RegisterAll(); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); string a = StaticTools.tempFilePath("shp", "原始等值线"); OSGeo.OGR.DataSource ds = dr.CreateDataSource(a, null); OSGeo.OGR.Layer dzxLayer = ds.CreateLayer("", null, OSGeo.OGR.wkbGeometryType.wkbMultiLineString, null); OSGeo.OGR.FieldDefn fieldDf0 = new OSGeo.OGR.FieldDefn("LID", OSGeo.OGR.FieldType.OFTInteger); OSGeo.OGR.FieldDefn fieldDf1 = new OSGeo.OGR.FieldDefn("EVE", OSGeo.OGR.FieldType.OFTReal); dzxLayer.CreateField(fieldDf0, 1); //ID dzxLayer.CreateField(fieldDf1, 1); //Value //Band(1), 间隔, 起始高度, 分段数量, 分段值数组, 是否有无效值, 无效值, 预置图层. ID字段, 高度值字段, null , null OSGeo.GDAL.Gdal.ContourGenerate(inData.GetRasterBand(1), jianG, min, count, shu, hasDataValue, noDataValue, dzxLayer, 0, 1, null, null); if (dzxLayer.GetFeatureCount(0) > 0) { Console.WriteLine("等值线创建完成!"); } else { Console.WriteLine("等值线创建失败!"); } ds.Dispose(); inData.Dispose(); return(a); }
//返回值是函数的系数 //例如:y=a0+a1*x 返回值则为a0 a1 //例如:y=a0+a1*x+a2*x*x 返回值则为a0 a1 a2 #endregion /*************************************************************************************************/ /************************************ 生成等值线 **********************************************/ public static string dzxPath(string filePath) { OSGeo.OGR.Ogr.RegisterAll(); OSGeo.GDAL.Gdal.AllRegister(); //无效值 double noDataValue; //0不使用无效值,1使用无效值 int hasDataValue; //读入数据源 OSGeo.GDAL.Dataset inData = OSGeo.GDAL.Gdal.Open(filePath, OSGeo.GDAL.Access.GA_ReadOnly); //分析数据源 inData.GetRasterBand(1).GetNoDataValue(out noDataValue, out hasDataValue); double min, max, mean, std; inData.GetRasterBand(1).GetStatistics(0, 1, out min, out max, out mean, out std); int jianG = 2; int count = Convert.ToInt32((max - min) / jianG + 0.5); double[] shu = new double[count]; for (int i = 0; i < count; i++) { shu[i] = min + jianG * i; } //创建空的SHP string dzSavePath = filePath.Substring(0, filePath.LastIndexOf(".")) + "_dzx.shp"; OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); if (System.IO.File.Exists(dzSavePath)) { System.IO.File.Delete(dzSavePath); } OSGeo.OGR.DataSource ds = dr.CreateDataSource(dzSavePath, null); OSGeo.OGR.Layer dzxLayer = ds.CreateLayer("等值线", null, OSGeo.OGR.wkbGeometryType.wkbMultiLineString, null); OSGeo.OGR.FieldDefn fieldDf0 = new OSGeo.OGR.FieldDefn("LID", OSGeo.OGR.FieldType.OFTInteger); OSGeo.OGR.FieldDefn fieldDf1 = new OSGeo.OGR.FieldDefn("EVE", OSGeo.OGR.FieldType.OFTReal); dzxLayer.CreateField(fieldDf0, 1); //ID dzxLayer.CreateField(fieldDf1, 1); //Value //Band(1), 间隔, 起始高度, 分段数量, 分段值数组, 是否有无效值, 无效值, 预置图层. ID字段, 高度值字段, null , null OSGeo.GDAL.Gdal.ContourGenerate(inData.GetRasterBand(1), jianG, min, count, shu, hasDataValue, noDataValue, dzxLayer, 0, 1, null, null); dzxLayer.Dispose(); ds.Dispose(); return(dzSavePath); }
/// <summary> /// 创建slopeMap,设置无效值 /// </summary> /// <param name="DemPath"></param> /// <param name="OutSlpPath"></param> static void CreateSlopeMap() { double dsm_NoDataValue; int dsm_HasNoDataValue; OSGeo.GDAL.Band dsmBand = dsmDataset.GetRasterBand(1); dsmBand.GetNoDataValue(out dsm_NoDataValue, out dsm_HasNoDataValue); //调用GDal创建slope影像 if (File.Exists(slopePath)) { gdalDriver.Delete(slopePath); } slopeDataSet = gdalDriver.Create(slopePath, dsm_Xsize, dsm_Ysize, 1, OSGeo.GDAL.DataType.GDT_Float32, null); slopeDataSet.SetProjection(dsmDataset.GetProjection()); slopeDataSet.SetGeoTransform(dsm_Transform); OSGeo.GDAL.Band slopeBand = slopeDataSet.GetRasterBand(1); //设置无效值 if (dsm_HasNoDataValue == 0) //dsm没有无效值 { //把DSM和SLOPE全设置成用户指定的值 dsmBand.SetNoDataValue(imgNodata); slopeBand.SetNoDataValue(imgNodata); } else //DSM有无效值时 { //把SLOPE和全局变量设置成DSM的无效值 imgNodata = dsm_NoDataValue; slopeBand.SetNoDataValue(dsm_NoDataValue); } // BufferOnePixel(slopeBand); }
/// <summary> /// 获取Feature的最大值和最小值 范围不准 /// </summary> /// <param name="dsmDs"></param> /// <param name="oriFeat"></param> /// <param name="bufFeat"></param> /// <param name="subRasterOff_Size"></param> private static void getMaxMinValue(OSGeo.GDAL.Dataset dsmDs, OSGeo.OGR.Feature oriFeat, OSGeo.OGR.Feature bufFeat, int[] subRasterOff_Size) { //拿到当前Feature对应的栅格值(数组) double[] rastValue = new double[subRasterOff_Size[2] * subRasterOff_Size[3]]; //把SUBimg的值读进数组 lock (dsmDs) { dsmDs.GetRasterBand(1).ReadRaster( subRasterOff_Size[0], subRasterOff_Size[1], subRasterOff_Size[2], subRasterOff_Size[3], rastValue, subRasterOff_Size[2], subRasterOff_Size[3], 0, 0); } double max = rastValue.Max(); double min = rastValue.Min(); double cay = max - min; oriFeat.SetField("TEMP", max - min); oriFeat.SetField("MIN", 0); oriFeat.SetField("MAX", min); oriFeat.SetField("HIGHT", max); }
/// <summary> /// Gdal to DotSpatial at Raster Level /// </summary> /// <param name="dataset">Gdal Dataset</param> /// <param name="bandIndex">Index of Band</param> /// <returns>Dotspatial Raster</returns> public static DotSpatial.Data.IRaster Gdal2DSRaster(OSGeo.GDAL.Dataset dataset, int bandIndex) { DotSpatial.Data.IRaster result = null; OSGeo.GDAL.Band band = dataset.GetRasterBand(bandIndex); if (dataset != null) { switch (band.DataType) { case OSGeo.GDAL.DataType.GDT_Byte: result = new GdalRaster <byte>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_CFloat32: case OSGeo.GDAL.DataType.GDT_CFloat64: case OSGeo.GDAL.DataType.GDT_CInt16: case OSGeo.GDAL.DataType.GDT_CInt32: break; case OSGeo.GDAL.DataType.GDT_Float32: result = new GdalRaster <float>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_Float64: result = new GdalRaster <double>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_Int16: result = new GdalRaster <short>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_UInt16: case OSGeo.GDAL.DataType.GDT_Int32: result = new GdalRaster <int>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_TypeCount: break; case OSGeo.GDAL.DataType.GDT_UInt32: result = new GdalRaster <long>(dataset, band); break; case OSGeo.GDAL.DataType.GDT_Unknown: break; default: break; } } if (result != null) { (result as DotSpatial.Data.Raster).Open(); } return(result); }
/// <summary> /// 和GetData功能相同,但是使用GDAL直接从文件中读取数据。 /// </summary> /// <param name="fileName">文件名字</param> /// <param name="width">ref用于返回数据的宽度</param> /// <param name="height">ref用于返回数据的高度</param> /// <returns>一维数据数组,按行优先</returns> private double[] GdalGetData(string fileName, ref int width, ref int height) { OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(fileName, OSGeo.GDAL.Access.GA_ReadOnly); width = dataset.RasterXSize; height = dataset.RasterYSize; double[] imageBuffer = new double[width * height]; OSGeo.GDAL.Band b = dataset.GetRasterBand(1); b.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); return(imageBuffer); }
public static bool FT(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); Tools.Common.CopyMetadata(InputDS, DS); //Matrix<Complex32> M = new Matrix<Complex32>; //for (int i = 0; i < InputDS.RasterCount; i++) //{ for (int Row = 0; Row < ySize; Row++) { float[] Values = new float[xSize]; Complex32[] c = new Complex32[xSize]; //读取DN到数组 InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { c[Col] = new Complex32(Values[Col], 0); } //M.Add(c); //写结果到新栅格 //DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); } //} Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
private static void TKData_(int index) { double pixel_x = Math.Abs(dsm_Transform[1]); double pixel_y = Math.Abs(dsm_Transform[5]); int xTimes = (dsm_Xsize - OverlapWeight) / CutWeight; int xRemainder = (dsm_Xsize - OverlapWeight) % CutWeight; int yTimes = (dsm_Ysize - OverlapWeight) / CutWeight; int yRemainder = (dsm_Ysize - OverlapWeight) % CutWeight; int ax = xTimes, by = yTimes; if (xRemainder > OverlapWeight) { ax++; } int x = index % ax; int y = index / ax; int xsize = CutWeight + OverlapWeight; int ysize = CutWeight + OverlapWeight; if (x * CutWeight + xsize > dsm_Xsize) { xsize = dsm_Xsize - x * CutWeight; } if (y * CutWeight + ysize > dsm_Ysize) { ysize = dsm_Ysize - y * CutWeight; } double[] buffer = new double[xsize * ysize]; dsmDataset.GetRasterBand(1).ReadRaster(x * CutWeight, y * CutWeight, xsize, ysize, buffer, xsize, ysize, 0, 0); BasicUnitSlp bunitSlp = new BasicUnitSlp(x * CutWeight, y * CutWeight, xsize, ysize, imgNodata, imgNodata, buffer, pixel_x, pixel_y); double[] resArr = bunitSlp.Calculate(); lock (slopeDataSet) { slopeDataSet.GetRasterBand(1).WriteRaster(x * CutWeight + 1, y * CutWeight + 1, xsize - 2, ysize - 2, resArr, xsize - 2, ysize - 2, 0, 0); } }
/// <summary> /// 模拟结束事件监听辅助函数 /// </summary> protected void SimulateEndHelper(BaseCa ca) { // 将模拟结果添加到系统中 double[] buffer = ca.BeginBuffer; int width = ca.Width; int height = ca.Height; //var map = GIS.FrameWork.Application.App.Map; // 保存输出结果 var path = Application.StartupPath + @"\log"; if (!Directory.Exists(path)) //如果不存在就创建file文件夹 { Directory.CreateDirectory(path); //创建该文件夹 } var outputPath = path + @"\" + (dateNow.ToString("MMddyyhhmmss")) + (this.uuid++) + ".tif"; OSGeo.GDAL.Driver driverSave = OSGeo.GDAL.Gdal.GetDriverByName("GTiff"); OSGeo.GDAL.Dataset datasetSave = driverSave.Create(outputPath, width, height, 1, OSGeo.GDAL.DataType.GDT_Byte, null); datasetSave.WriteRaster(0, 0, width, height, buffer, width, height, 1, new int[1] { 1 }, 0, 0, 0); datasetSave.SetProjection(ca.projStr); datasetSave.SetGeoTransform(ca.geoTransform); datasetSave.GetRasterBand(1).SetNoDataValue(ca.noDataVal); datasetSave.FlushCache(); datasetSave.Dispose(); driverSave.Dispose(); //// 翻转图像 ? //buffer = InvertImage(buffer, width, height); MessageBox.Show("模拟结束, 输出文件:" + outputPath); //// 新建 GDAL dataset //OSGeo.GDAL.Driver driver = OSGeo.GDAL.Gdal.GetDriverByName("MEM"); //OSGeo.GDAL.Dataset dataset = driver.Create("", width, height, 1, OSGeo.GDAL.DataType.GDT_Float64, null); //dataset.WriteRaster(0, 0, width, height, buffer, width, height, 1, new int[1] { 1 }, 0, 0, 0); //// 将GDAL dataset转化为IRaster数据集 //DotSpatial.Data.IRaster raster = GIS.GDAL.RasterConverter.Gdal2DSRaster(dataset, 1); //raster.Name = "Result"; //map.Layers.Add(raster); }
public override void Run() { OpenFileDialog openTiffDialog = new OpenFileDialog(); if (openTiffDialog.ShowDialog() == DialogResult.OK) { var tiffName = openTiffDialog.FileName; OSGeo.GDAL.Dataset tiffDataset = OSGeo.GDAL.Gdal.Open(tiffName, OSGeo.GDAL.Access.GA_ReadOnly); OSGeo.GDAL.Band band = tiffDataset.GetRasterBand(1); DotSpatial.Data.IRaster raster = GIS.GDAL.RasterConverter.Gdal2DSRaster(tiffDataset, 1); FileInfo fileInfo = new FileInfo(tiffName); raster.Name = fileInfo.Name; GIS.FrameWork.Application.App.Map.Layers.Add(raster); } }
private IRasterSet GetRasterSet(string fileName, OSGeo.GDAL.Dataset dataset) { IRasterSet rasterSet = null; if (dataset != null && dataset.RasterCount > 0) { using var band = dataset.GetRasterBand(1); if (band == null) { return(null); } switch (band.DataType) { case OSGeo.GDAL.DataType.GDT_Byte: rasterSet = new GdalRasterSet <byte>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_Int16: rasterSet = new GdalRasterSet <short>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_UInt16: rasterSet = new GdalRasterSet <ushort>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_Int32: rasterSet = new GdalRasterSet <int>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_UInt32: rasterSet = new GdalRasterSet <uint>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_CFloat32: rasterSet = new GdalRasterSet <float>(fileName, dataset); break; case OSGeo.GDAL.DataType.GDT_CFloat64: rasterSet = new GdalRasterSet <double>(fileName, dataset); break; default: throw new NotImplementedException(); } } return(rasterSet); }
protected override void SolveInstance(IGH_DataAccess DA) { string output = ""; try { GdalConfiguration.ConfigureOgr(); GdalConfiguration.ConfigureGdal(); output = "It works!"; } catch (Exception e) { output = "{0} Exception caught. " + e; } string input = ""; DA.GetData(0, ref input); string file = input; int pickBand = 1; DA.GetData(1, ref pickBand); OSGeo.GDAL.Dataset ds = OSGeo.GDAL.Gdal.Open(file, OSGeo.GDAL.Access.GA_ReadOnly); var band = ds.GetRasterBand(pickBand); var bandXSize = band.XSize; var bandYSize = band.YSize; var data = new float[bandXSize * bandYSize]; band.ReadRaster(0, 0, bandXSize, bandYSize, data, bandXSize, bandYSize, 0, 0); ds.GetMetadata(output); ds = null; DA.SetData(0, output); DA.SetDataList(1, data); }
/// <summary> /// 获取等高线 /// </summary> /// <returns></returns> static OSGeo.OGR.Layer getDZX_() { StaticTools.msgLine("createDZX..."); //分析数据源 double noDataValue; //无效值 int hasDataValue; //0不使用无效值,1使用无效值 dsmDataset.GetRasterBand(1).GetNoDataValue(out noDataValue, out hasDataValue); //WKT string wkt = dsmDataset.GetProjectionRef(); OSGeo.OSR.SpatialReference srs = wkt == "" ? null : new OSGeo.OSR.SpatialReference(wkt); //图像值属性,最大值、最小值、平均值 double min, max, mean, std; dsmDataset.GetRasterBand(1).GetStatistics(0, 1, out min, out max, out mean, out std); //计算每级线的值,加0.5是确保取到最接近的整数,不被四舍五入 int count = Convert.ToInt32((max - min) / jianG + 0.5); double[] shu = new double[count]; for (int i = 0; i < count; i++) { shu[i] = min + jianG * i; } //创建空的SHP,准备塞入数据 shpDataSet.deleteLayerByName("dzx"); OSGeo.OGR.Layer dzxLayer = shpDataSet.CreateLayer("dzx", srs, OSGeo.OGR.wkbGeometryType.wkbMultiLineString, null); //必须有这两个字段,函数要往里塞值,其实没毛用 OSGeo.OGR.FieldDefn fieldDf0 = new OSGeo.OGR.FieldDefn("LID", OSGeo.OGR.FieldType.OFTInteger); OSGeo.OGR.FieldDefn fieldDf1 = new OSGeo.OGR.FieldDefn("EVE", OSGeo.OGR.FieldType.OFTReal); dzxLayer.CreateField(fieldDf0, 1); //ID dzxLayer.CreateField(fieldDf1, 1); //Value //Band(1), 间隔, 起始高度, 分段数量, 分段值数组, 是否有无效值, 无效值, 预置图层. ID字段, 高度值字段, null , null OSGeo.GDAL.Gdal.ContourGenerate(dsmDataset.GetRasterBand(1), jianG, min, count, shu, hasDataValue, noDataValue, dzxLayer, 0, 1, null, null); if (dzxLayer.GetFeatureCount(0) > 0) { return(dzxLayer); } else { return(null); } }
private List <double[]> readImageCoordinatesBoundsInLonLat(OSGeo.GDAL.Dataset imageDataset) { var band = imageDataset.GetRasterBand(1); if (band == null) { return(null); } var width = band.XSize; var height = band.YSize; double[] geoTransformerData = new double[6]; imageDataset.GetGeoTransform(geoTransformerData); SpatialReference currentReference = new SpatialReference(imageDataset.GetProjectionRef()); SpatialReference newReference = GdalUtilities.getWgs84Reference(); CoordinateTransformation ct = new CoordinateTransformation(currentReference, newReference); double[] northWestPoint = new double[2] { geoTransformerData[0], geoTransformerData[3] }; ct.TransformPoint(northWestPoint); double[] southEastPoint = new double[2] { geoTransformerData[0] + geoTransformerData[1] * width, geoTransformerData[3] + geoTransformerData[5] * height }; ct.TransformPoint(southEastPoint); return(new List <double[]> { northWestPoint, southEastPoint }); }
public static bool ConvertToAAIGrid(OSGeo.GDAL.Dataset InputDS, string ConvertTo, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (InputDS.RasterCount != 1) { throw new ArgumentOutOfRangeException("重分类的影像不是灰度影像。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName(ConvertTo); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行格式转换...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); double NoDataValue = -9999; int HasNoDataValue = -1; InputDS.GetRasterBand(1).GetNoDataValue(out NoDataValue, out HasNoDataValue); OSGeo.GDAL.Dataset DS = Dri.CreateCopy(OutPath, InputDS, 0, null, null, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + DS.GetRasterBand(1).DataType.ToString() + "。"); if (HasNoDataValue == 1) { DS.GetRasterBand(1).SetNoDataValue(NoDataValue); } for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); //DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } DS.Dispose(); FP.Finish(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// NoData值替换。将非NoData值替换为指定值。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="NoDataValue">NoData值。</param> /// <param name="ReplaceValue">非NoData值替换为的值。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出数据集的路径。</param> /// <returns>操作成功或失败。</returns> public static bool ReplaceNoData(OSGeo.GDAL.Dataset InputDS, double NoDataValue, double ReplaceValue, OSGeo.GDAL.DataType OutDataType, string OutPath, double NewNoDataValue = -9999) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (InputDS.RasterCount != 1) { throw new ArgumentOutOfRangeException("替换值的影像不是灰度影像。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行非NoData值替换...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); DS.GetRasterBand(1).SetNoDataValue(NoDataValue); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { if (Math.Abs(Values[Col] - NoDataValue) > 1e-7) { //将ReplaceValue与NoDataValue的值设置为一样的可以仅更改NoData值 if (Math.Abs(ReplaceValue - NoDataValue) > 1e-7) { Values[Col] = ReplaceValue; } } else { Values[Col] = NewNoDataValue; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } DS.Dispose(); FP.Finish(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 重分类。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="ReplaceList">用于对照值替换的表。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出数据集的路径。</param> /// <param name="DefaultValue">若值不在ReplaceList中,则该像元的值设为。</param> /// <returns>操作成功或失败。</returns> public static bool Reclassify(OSGeo.GDAL.Dataset InputDS, List <double[]> ReplaceList, OSGeo.GDAL.DataType OutDataType, string OutPath, double DefaultValue = 0.03) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (InputDS.RasterCount != 1) { throw new ArgumentOutOfRangeException("重分类的影像不是灰度影像。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行重分类...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); double NoDataValue = -9999; int HasNoDataValue = -1; InputDS.GetRasterBand(1).GetNoDataValue(out NoDataValue, out HasNoDataValue); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); if (HasNoDataValue == 1) { DS.GetRasterBand(1).SetNoDataValue(NoDataValue); } Tools.Common.CopyMetadata(InputDS, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //值为NoData if (Math.Abs(Values[Col] - NoDataValue) < 1e-7) { continue; } int i = -1; //对照表进行值替换 for (i = 0; i < ReplaceList.Count; i++) { if (Values[Col] == ReplaceList[i][0]) { Values[Col] = ReplaceList[i][1]; break; } } if (i == ReplaceList.Count) { Values[Col] = 0.03; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } DS.Dispose(); FP.Finish(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
public static bool CutImage(OSGeo.GDAL.Dataset InputDS, int CutWidth, int CutHeight, OSGeo.GDAL.DataType OutDataType, string OutFolder) { try { if (InputDS == null) { throw new ArgumentNullException("输入的数据集不可为空。"); } if (String.IsNullOrWhiteSpace(OutFolder)) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } //取输入的宽、高、波段最小值创建输出数据集。 int Width = InputDS.RasterXSize; int Height = InputDS.RasterYSize; int Rows = Height / CutHeight; int Cols = Width / CutWidth; FrmProgress FP = new FrmProgress() { Text = "正在进行影像裁剪...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); FP.Output("输出的目录为:" + OutFolder); FP.Output("输出的数据类型为:" + OutDataType.ToString()); for (int row = 0; row < Rows; row++) { FP.SetProgress2("总进度:", row + 1, Rows, ""); string ParentPath = row.ToString(); Directory.CreateDirectory(Path.Combine(OutFolder, ParentPath)); for (int col = 0; col < Cols; col++) { FP.SetProgress1("当前行进度:", col + 1, Cols, ""); string OutName = row.ToString() + "_" + col.ToString() + ".tif"; OSGeo.GDAL.Dataset DS = Dri.Create(Path.Combine(OutFolder, ParentPath, OutName), CutWidth, CutHeight, InputDS.RasterCount, OutDataType, null); for (int band = 1; band <= InputDS.RasterCount; band++) { double[] buf = new double[CutWidth * CutHeight]; InputDS.GetRasterBand(band).ReadRaster(col * CutWidth, row * CutHeight, CutWidth, CutHeight, buf, CutWidth, CutHeight, 0, 0); DS.GetRasterBand(band).WriteRaster(0, 0, CutWidth, CutHeight, buf, CutWidth, CutHeight, 0, 0); } ////单行读取写入,防止爆内存。 //for (int cRow = 0; cRow < CutHeight; cRow++) //{ // double[] buf = new double[CutWidth]; // InputDS.GetRasterBand(band).ReadRaster(col * CutWidth, row * CutHeight + cRow, CutWidth, 1, buf, CutWidth, 1, 0, 0); // DS.GetRasterBand(band).WriteRaster(0, cRow, CutWidth, 1, buf, CutWidth, 1, 0, 0); // DS.FlushCache(); // Thread.Sleep(1); //} DS.FlushCache(); DS.Dispose(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); InputDS.Dispose(); Dri.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
public RasterClass(IRasterDataset dataset, string filename, IPolygon polygon) { try { FileInfo fi = new FileInfo(filename); _title = fi.Name; _filename = filename; _dataset = dataset; OSGeo.GDAL.Gdal.AllRegister(); _gDS = OSGeo.GDAL.Gdal.Open(fi.FullName, 0); if (_gDS == null && _gDS.RasterCount == 0) { _valid = false; return; } _iWidth = _gDS.RasterXSize; _iHeight = _gDS.RasterYSize; switch (fi.Extension.ToLower()) { case ".adf": case ".gsd": _type = RasterType.grid; break; //case ".jp2": // _type = RasterType.wavelet; // break; } using (OSGeo.GDAL.Band band = _gDS.GetRasterBand(1)) { if (_gDS.RasterCount == 1) { if (band.DataType != OSGeo.GDAL.DataType.GDT_Byte) { _type = RasterType.grid; } } band.GetMinimum(out _min, out _hasNoDataVal); band.GetMaximum(out _max, out _hasNoDataVal); band.GetNoDataValue(out _nodata, out _hasNoDataVal); } OSGeo.GDAL.Driver driver = _gDS.GetDriver(); double[] tfw = new double[6]; _gDS.GetGeoTransform(tfw); string tfwFilename = fi.FullName.Substring(0, fi.FullName.Length - fi.Extension.Length); switch (fi.Extension.ToLower()) { case ".jpg": case ".jpeg": tfwFilename += ".jgw"; break; case ".jp2": tfwFilename += ".j2w"; break; case ".tif": case ".tiff": tfwFilename += ".tfw"; break; case ".ecw": tfwFilename += ".eww"; break; default: break; } FileInfo tfwInfo = new FileInfo(tfwFilename); _tfw = new TFWFile(tfw[0], tfw[3], tfw[1], tfw[2], tfw[4], tfw[5]); if (tfwInfo.Exists) { _tfw.Filename = tfwFilename; } if (_tfw.X == 0.0 && _tfw.Y == 0.0 && Math.Abs(_tfw.dx_X) == 1.0 && _tfw.dx_Y == 0.0 && Math.Abs(_tfw.dy_Y) == 1.0 && _tfw.dy_X == 0.0 && driver != null) { if (tfwInfo.Exists) { _tfw = new TFWFile(tfwFilename); } else { _tfw.isValid = false; } } else { // Bei dem Driver schein es nicht Pixelmitte sein, oder ist das bei GDAL generell //if (driver.ShortName.ToLower() == "jp2openjpeg") { _tfw.X += (_tfw.dx_X / 2.0D + _tfw.dx_Y / 2.0D); _tfw.Y += (_tfw.dy_X / 2.0D + _tfw.dy_Y / 2.0D); } } FileInfo fiPrj = new FileInfo(fi.FullName.Substring(0, fi.FullName.Length - fi.Extension.Length) + ".prj"); if (fiPrj.Exists) { StreamReader sr = new StreamReader(fiPrj.FullName); string wkt = sr.ReadToEnd(); sr.Close(); _sRef = gView.Framework.Geometry.SpatialReference.FromWKT(wkt); } else { fiPrj = new FileInfo(fi.FullName.Substring(0, fi.FullName.Length - fi.Extension.Length) + ".wkt"); if (fiPrj.Exists) { StreamReader sr = new StreamReader(fiPrj.FullName); string wkt = sr.ReadToEnd(); sr.Close(); _sRef = gView.Framework.Geometry.SpatialReference.FromWKT(wkt); } } if (polygon != null) { _polygon = polygon; } else { calcPolygon(); } } catch (Exception ex) { string errMsg = ex.Message; _valid = false; } }
/// <summary> /// 辐射定标。 /// </summary> /// <param name="InputDS">输入的栅格数据集。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="Gain">增益倍数。</param> /// <param name="Offset">偏移量。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>返回操作成功或失败。</returns> public static bool ApplyGainAndOffset(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.DataType OutDataType, List <double> Gain, List <double> Offset, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if ((Gain.Count != InputDS.RasterCount) || (Offset.Count != InputDS.RasterCount)) { throw new IndexOutOfRangeException("增益数据或偏移数据与输入数据集波段数不符。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行辐射定标...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int i = 0; i < InputDS.RasterCount; i++) //遍历每个波段 { FP.SetProgress2("正在处理波段:", i + 1, InputDS.RasterCount, ""); for (int Row = 0; Row < ySize; Row++) //遍历每一行(y) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputDS.GetRasterBand(i + 1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) //对每一个值进行计算 { Values[Col] = GainOffset(Values[Col], Gain[i], Offset[i]); } //写结果到新栅格 DS.GetRasterBand(i + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
public static bool CalculateFloodArea(string InDir, string OutDir) { try { if (!Directory.Exists(InDir)) { throw new FileNotFoundException("输入路径不存在。"); } if (!Directory.Exists(OutDir)) { Directory.CreateDirectory(OutDir); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } FrmProgress FP = new FrmProgress() { Text = "正在处理洪水范围...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); bool createFlag = true; string[] ascFiles = Directory.GetFiles(InDir); int xSize = 0; int ySize = 0; OSGeo.GDAL.Dataset rangeDS = new OSGeo.GDAL.Dataset(IntPtr.Zero, false, null); OSGeo.GDAL.Dataset depthDS = new OSGeo.GDAL.Dataset(IntPtr.Zero, false, null); OSGeo.GDAL.Dataset timeDS = new OSGeo.GDAL.Dataset(IntPtr.Zero, false, null); for (int i = 0; i < ascFiles.Length; i++) { FP.SetProgress2("正在处理文件:", i + 1, ascFiles.Length, ""); string tmpPath = ascFiles[i]; FP.Output("正在处理:" + (i + 1).ToString() + ". " + tmpPath); if (tmpPath.Substring(tmpPath.LastIndexOf(".")) != ".txt") { FP.Output(tmpPath + "不是txt文件。"); continue; } OSGeo.GDAL.Dataset tmpDS = OSGeo.GDAL.Gdal.Open(tmpPath, OSGeo.GDAL.Access.GA_ReadOnly); if (createFlag) { xSize = tmpDS.RasterXSize; ySize = tmpDS.RasterYSize; string inDirName = Path.GetDirectoryName(tmpPath).Substring(Path.GetDirectoryName(tmpPath).LastIndexOf("\\") + 1); rangeDS = Dri.Create(Path.Combine(OutDir, inDirName + "_floodRange.tiff"), xSize, ySize, 1, OSGeo.GDAL.DataType.GDT_Float32, null); Tools.Common.CopyMetadata(tmpDS, rangeDS); FP.Output("已创建输出数据集\"" + Path.Combine(OutDir, inDirName + "_floodRange.tiff") + "\"。"); depthDS = Dri.Create(Path.Combine(OutDir, inDirName + "_floodDepth.tiff"), xSize, ySize, 1, OSGeo.GDAL.DataType.GDT_Float32, null); Tools.Common.CopyMetadata(tmpDS, depthDS); FP.Output("已创建输出数据集\"" + Path.Combine(OutDir, inDirName + "_floodDepth.tiff") + "\"。"); timeDS = Dri.Create(Path.Combine(OutDir, inDirName + "_floodTime.tiff"), xSize, ySize, 1, OSGeo.GDAL.DataType.GDT_Float32, null); Tools.Common.CopyMetadata(tmpDS, timeDS); FP.Output("已创建输出数据集\"" + Path.Combine(OutDir, inDirName + "_floodTime.tiff") + "\"。"); createFlag = false; } for (int Row = 0; Row < ySize; Row++) { double[] tmpValues = new double[xSize]; double[] rangeValues = new double[xSize]; double[] depthValues = new double[xSize]; double[] timeValues = new double[xSize]; tmpDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, tmpValues, xSize, 1, 0, 0); rangeDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, rangeValues, xSize, 1, 0, 0); depthDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, depthValues, xSize, 1, 0, 0); timeDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, timeValues, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //计算洪水范围 if (Math.Abs(tmpValues[Col]) <= 1e-7) //Nodata { continue; } else { rangeValues[Col] = 1; if (tmpValues[Col] > depthValues[Col]) { depthValues[Col] = tmpValues[Col]; } timeValues[Col] += 1; } } rangeDS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, rangeValues, xSize, 1, 0, 0); rangeDS.FlushCache(); depthDS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, depthValues, xSize, 1, 0, 0); depthDS.FlushCache(); timeDS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, timeValues, xSize, 1, 0, 0); timeDS.FlushCache(); } tmpDS.Dispose(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); rangeDS.Dispose(); depthDS.Dispose(); timeDS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 平滑锐化算法。 /// </summary> /// <param name="InputDS">输入的栅格数据集。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="Method">平滑锐化方法。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>返回操作成功或失败。</returns> public static bool SmoothSharpening(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.DataType OutDataType, SmoothShapeninngMethods Method, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行平滑锐化操作...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); FP.Output("选择的平滑/锐化方法为:\"" + (typeof(SmoothShapeninngMethods).GetField((Method).ToString()).GetCustomAttributes(false)[0] as DescriptionAttribute).Description + "\""); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int band = 0; band < InputDS.RasterCount; band++) //遍历每个波段 { FP.SetProgress1("正在处理", band + 1, InputDS.RasterCount, "波段"); for (int Row = 0; Row < ySize - 2; Row++) //从第1行遍历至倒数第三行 { FP.SetProgress2("正在处理", Row, ySize - 2, "行"); double[] Values = new double[3 * xSize]; //读取的数值 double[] Result = new double[xSize]; //结果数值 InputDS.GetRasterBand(band + 1).ReadRaster(0, Row, xSize, 3, Values, xSize, 3, 0, 0); //读取3行 Array.Copy(Values, xSize, Result, 0, xSize); // for (int Col = 0; Col < xSize - 2; Col++) //对每一个值进行计算 { double[,] Input = new double[3, 3]; for (int i = 0; i < 3; i++) { Input[i, 0] = Values[Col + i * xSize]; Input[i, 1] = Values[Col + i * xSize + 1]; Input[i, 2] = Values[Col + i * xSize + 2]; } Result[Col + 1] = SmoothSharpening(Input, Method); //计算输入数据中心像元的值 } //写结果到新栅格 DS.GetRasterBand(band + 1).WriteRaster(0, Row + 1, xSize, 1, Result, xSize, 1, 0, 0); } if ((Method.ToString()).Contains("Smooth")) { double[] row = new double[xSize]; InputDS.GetRasterBand(band + 1).ReadRaster(0, 0, xSize, 1, row, xSize, 1, 0, 0); //读取第一行 DS.GetRasterBand(band + 1).WriteRaster(0, 0, xSize, 1, row, xSize, 1, 0, 0); InputDS.GetRasterBand(band + 1).ReadRaster(0, ySize - 1, xSize, 1, row, xSize, 1, 0, 0); //读取最后一行 DS.GetRasterBand(band + 1).WriteRaster(0, ySize - 1, xSize, 1, row, xSize, 1, 0, 0); } DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
private void GetPreview(OSGeo.GDAL.Dataset dataset, System.Drawing.Size size, Graphics g, SharpMap.Geometries.BoundingBox bbox) { double[] geoTrans = new double[6]; dataset.GetGeoTransform(geoTrans); GeoTransform GT = new GeoTransform(geoTrans); int DsWidth = dataset.RasterXSize; int DsHeight = dataset.RasterYSize; Bitmap bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format24bppRgb); int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { /* * if ((float)size.Width / (float)size.Height > (float)DsWidth / (float)DsHeight) * size.Width = size.Height * DsWidth / DsHeight; * else * size.Height = size.Width * DsHeight / DsWidth; */ double left = Math.Max(bbox.Left, _Envelope.Left); double top = Math.Min(bbox.Top, _Envelope.Top); double right = Math.Min(bbox.Right, _Envelope.Right); double bottom = Math.Max(bbox.Bottom, _Envelope.Bottom); int x1 = (int)GT.PixelX(left); int y1 = (int)GT.PixelY(top); int x1width = (int)GT.PixelXwidth(right - left); int y1height = (int)GT.PixelYwidth(bottom - top); bitmap = new Bitmap(size.Width, size.Height, PixelFormat.Format24bppRgb); BitmapData bitmapData = bitmap.LockBits(new Rectangle(0, 0, size.Width, size.Height), ImageLockMode.ReadWrite, bitmap.PixelFormat); try { unsafe { for (int i = 1; i <= (dataset.RasterCount > 3 ? 3 : dataset.RasterCount); ++i) { byte[] buffer = new byte[size.Width * size.Height]; OSGeo.GDAL.Band band = dataset.GetRasterBand(i); //band.ReadRaster(x1, y1, x1width, y1height, buffer, size.Width, size.Height, (int)GT.HorizontalPixelResolution, (int)GT.VerticalPixelResolution); band.ReadRaster(x1, y1, x1width, y1height, buffer, size.Width, size.Height, 0, 0); int p_indx = 0; int ch = 0; //#warning Check correspondance between enum and integer values if (band.GetRasterColorInterpretation() == OSGeo.GDAL.ColorInterp.GCI_BlueBand) { ch = 0; } if (band.GetRasterColorInterpretation() == OSGeo.GDAL.ColorInterp.GCI_GreenBand) { ch = 1; } if (band.GetRasterColorInterpretation() == OSGeo.GDAL.ColorInterp.GCI_RedBand) { ch = 2; } if (band.GetRasterColorInterpretation() != OSGeo.GDAL.ColorInterp.GCI_PaletteIndex) { for (int y = 0; y < size.Height; y++) { byte *row = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < size.Width; x++, p_indx++) { row[x * iPixelSize + ch] = buffer[p_indx]; } } } else //8bit Grayscale { for (int y = 0; y < size.Height; y++) { byte *row = (byte *)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < size.Width; x++, p_indx++) { row[x * iPixelSize] = buffer[p_indx]; row[x * iPixelSize + 1] = buffer[p_indx]; row[x * iPixelSize + 2] = buffer[p_indx]; } } } } } } finally { bitmap.UnlockBits(bitmapData); } } g.DrawImage(bitmap, new System.Drawing.Point(0, 0)); }
/// <summary> /// 波段直方图匹配。 /// </summary> /// <param name="InputBand">输入的波段。</param> /// <param name="MatchBand">要匹配到的波段。</param> /// <param name="InputCumu">输入的数据集的累积概率表。</param> /// <param name="MatchingCumu">要匹配到的数据集的累积概率表。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <returns>操作成功或失败。</returns> public static OSGeo.GDAL.Band HistogramMatching(OSGeo.GDAL.Band InputBand, OSGeo.GDAL.Band MatchBand, double[] InputCumu, double[] MatchingCumu, OSGeo.GDAL.DataType OutDataType) { try { int[] LUT = HistogramMatching(InputCumu, MatchingCumu); //进行波段直方图匹配。 int xSize = InputBand.XSize; int ySize = InputBand.YSize; OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } string tmpFileName = Tools.Common.GetTempFileName(); FrmProgress FP = new FrmProgress() { Text = "正在进行波段直方图匹配...", CanCancel = false, }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(tmpFileName, xSize, ySize, 1, OutDataType, null); FP.Output("已创建临时输出数据集\"" + tmpFileName + "\""); Tools.Common.GetMinimum(InputBand, out double inputBandMin); Tools.Common.GetMinimum(MatchBand, out double matchBandMin); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputBand.ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //防止GDAL自带方法算出的统计数据越界。 if ((Values[Col] - inputBandMin) <= 0) { Values[Col] = matchBandMin + LUT[0]; continue; } if ((Values[Col] - inputBandMin) >= LUT.Length - 1) { Values[Col] = matchBandMin + LUT[LUT.Length - 1]; continue; } Values[Col] = matchBandMin + LUT[(int)(Values[Col] - inputBandMin)]; } //写结果到新栅格 DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); Dri.Dispose(); return(DS.GetRasterBand(1)); } catch (Exception err) { MessageBox.Show(err.ToString()); return(null); } }
/// <summary> /// 二值化。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="Threshold">分割阈值。</param> /// <param name="ZeroValue">小于阈值的像元值被设为...</param> /// <param name="OneValue">大于阈值的像元值被设为...</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>操作成功或失败。</returns> public static bool Binarize(OSGeo.GDAL.Dataset InputDS, double Threshold, double ZeroValue, double OneValue, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (InputDS == null) { throw new ArgumentNullException("输入数据集为空。"); } if (InputDS.RasterCount != 1) { throw new ArgumentException("输入的数据集波段大于1。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; FrmProgress FP = new FrmProgress() { Text = "正在进行二值化操作...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, 1, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理:", Row + 1, ySize, "行"); double[] Values = new double[xSize]; InputDS.GetRasterBand(1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //阈值应用 if (Values[Col] < Threshold) { Values[Col] = ZeroValue; } else { Values[Col] = OneValue; } } DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.Message); return(false); } }
/// <summary> /// 获取指定行列号的像元值。 /// </summary> /// <param name="x">列号。</param> /// <param name="y">行号。</param> /// <returns></returns> public double GetDN(OSGeo.GDAL.Dataset ds, int band, int x, int y) { double[] buf = new double[1]; ds.GetRasterBand(band).ReadRaster(x, y, 1, 1, buf, 1, 1, 0, 0); return(buf[0]); }
private void PaintImage(int x, int y, int wWidth, int wHeight, int iWidth, int iHeight, ICancelTracker cancelTracker) { if (CancelTracker.Canceled(cancelTracker) || _gDS == null) { return; } int pixelSpace = 3; _bitmap = new Bitmap(iWidth, iHeight, PixelFormat.Format24bppRgb); BitmapData bitmapData = _bitmap.LockBits(new Rectangle(0, 0, iWidth, iHeight), ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb); try { int stride = bitmapData.Stride; IntPtr buf = bitmapData.Scan0; List <Color> colors = new List <Color>(); for (int i = 1; i <= (_gDS.RasterCount > 3 ? 3 : _gDS.RasterCount); ++i) { using (OSGeo.GDAL.Band band = _gDS.GetRasterBand(i)) { int ch = 0; switch ((ColorInterp)band.GetRasterColorInterpretation()) { case ColorInterp.BlueBand: ch = 0; break; case ColorInterp.GreenBand: ch = 1; break; case ColorInterp.RedBand: ch = 2; break; case ColorInterp.GrayIndex: for (int iColor = 0; iColor < 256; iColor++) { colors.Add(Color.FromArgb(255, iColor, iColor, iColor)); } break; case ColorInterp.PaletteIndex: OSGeo.GDAL.ColorTable colTable = band.GetRasterColorTable(); if (colTable == null) { break; } int colCount = colTable.GetCount(); for (int iColor = 0; iColor < colCount; iColor++) { OSGeo.GDAL.ColorEntry colEntry = colTable.GetColorEntry(iColor); colors.Add(Color.FromArgb( colEntry.c4, colEntry.c1, colEntry.c2, colEntry.c3)); } break; } band.ReadRaster(x, y, wWidth, wHeight, new IntPtr(buf.ToInt64() + ch), iWidth, iHeight, OSGeo.GDAL.DataType.GDT_Byte, pixelSpace, stride); band.Dispose(); } } if (colors.Count > 0) { unsafe { byte *ptr = (byte *)(bitmapData.Scan0); for (int i = 0; i < bitmapData.Height; i++) { if (CancelTracker.Canceled(cancelTracker)) { return; } for (int j = 0; j < bitmapData.Width; j++) { // write the logic implementation here byte c = ptr[0]; Color col = colors[(int)c]; ptr[0] = col.B; ptr[1] = col.G; ptr[2] = col.R; ptr += pixelSpace; } ptr += bitmapData.Stride - bitmapData.Width * pixelSpace; } } } } catch (Exception ex) { string msg = ex.Message; } finally { if (_bitmap != null) { _bitmap.UnlockBits(bitmapData); } } }
/// <summary> /// 数据集相除。 /// </summary> /// <param name="D1">被除数据集。</param> /// <param name="D2">除数据集。</param> /// <param name="OutDataType">输出数据集的数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>操作成功或失败。</returns> public static bool Divide(OSGeo.GDAL.Dataset D1, OSGeo.GDAL.Dataset D2, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (D1 == null || D2 == null) { throw new ArgumentNullException("输入的数据集不可为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } //取输入的宽、高、波段最小值创建输出数据集。 int Width = Math.Min(D1.RasterXSize, D2.RasterXSize); int Height = Math.Min(D1.RasterYSize, D2.RasterYSize); int band = Math.Min(D1.RasterCount, D2.RasterCount); FrmProgress FP = new FrmProgress() { Text = "正在进行数据集除法运算...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, Width, Height, band, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(D1, DS); for (int bandcount = 1; bandcount <= band; bandcount++) { FP.SetProgress2("正在处理", bandcount, band, "波段"); for (int row = 0; row < Height; row++) { FP.SetProgress1("正在处理:", row + 1, Height, "行"); double[] d1Tmp = new double[Width]; double[] d2Tmp = new double[Width]; double[] dsTmp = new double[Width]; D1.GetRasterBand(bandcount).ReadRaster(0, row, Width, 1, d1Tmp, Width, 1, 0, 0); D2.GetRasterBand(bandcount).ReadRaster(0, row, Width, 1, d2Tmp, Width, 1, 0, 0); for (long i = 0; i < Width; i++) { if (d2Tmp[i] == 0) { dsTmp[i] = 0; } else { dsTmp[i] = d1Tmp[i] / d2Tmp[i]; } } DS.GetRasterBand(bandcount).WriteRaster(0, row, Width, 1, dsTmp, Width, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 影像直方图匹配。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="MatchDS">要匹配到的数据集。</param> /// <param name="InputCumu">输入的数据集的累积概率表。</param> /// <param name="MatchingCumu">要匹配到的数据集的累积概率表。</param> /// <param name="OutDataType">输出的数据类型。</param> /// <param name="OutPath">输出栅格数据集的位置。</param> /// <returns>操作成功或失败。</returns> public static bool HistogramMatching(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.Dataset MatchDS, double[][] InputCumu, double[][] MatchingCumu, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (InputDS.RasterCount != MatchDS.RasterCount) { throw new ArgumentException("数据集波段数不一致。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行影像直方图匹配...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); int[][] LUT = new int[InputDS.RasterCount][]; FP.Output("正在计算查找表..."); for (int i = 0; i < InputDS.RasterCount; i++) { LUT[i] = HistogramMatching(InputCumu[i], MatchingCumu[i]); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputDS.RasterXSize; int ySize = InputDS.RasterYSize; OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, xSize, ySize, InputDS.RasterCount, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputDS, DS); for (int bandcount = 0; bandcount < InputDS.RasterCount; bandcount++) { FP.SetProgress2("正在处理", bandcount + 1, InputDS.RasterCount, "波段"); Tools.Common.GetMinimum(InputDS.GetRasterBand(bandcount + 1), out double inputDSBandMin); Tools.Common.GetMinimum(MatchDS.GetRasterBand(bandcount + 1), out double matchDSBandMin); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputDS.GetRasterBand(bandcount + 1).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //防止GDAL自带方法算出的统计数据越界。 if ((Values[Col] - inputDSBandMin) <= 0) { Values[Col] = matchDSBandMin + LUT[bandcount][0]; continue; } if ((Values[Col] - inputDSBandMin) >= LUT[bandcount].Length - 1) { Values[Col] = matchDSBandMin + LUT[bandcount][LUT[bandcount].Length - 1]; continue; } Values[Col] = matchDSBandMin + LUT[bandcount][(int)(Values[Col] - inputDSBandMin)]; } //写结果到新栅格 DS.GetRasterBand(bandcount + 1).WriteRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// 以前的代码 /// </summary> /// <param name="dsmDs"></param> /// <param name="oriFeat"></param> /// <param name="bufFeat"></param> /// <param name="subRasterOff_Size"></param> private static void getMaxMinValue_(OSGeo.GDAL.Dataset dsmDs, OSGeo.OGR.Feature oriFeat, OSGeo.OGR.Feature bufFeat, int[] subRasterOff_Size) { //拿到当前Feature对应的栅格值(数组) double[] rastValue = new double[subRasterOff_Size[2] * subRasterOff_Size[3]]; //拿到全局Transfrom double[] Transfrom = new double[6]; dsmDs.GetGeoTransform(Transfrom); //把SUBimg的值读进数组 dsmDs.GetRasterBand(1).ReadRaster( subRasterOff_Size[0], subRasterOff_Size[1], subRasterOff_Size[2], subRasterOff_Size[3], rastValue, subRasterOff_Size[2], subRasterOff_Size[3], 0, 0); OSGeo.OGR.Geometry oriGeom = oriFeat.GetGeometryRef(); string ddd = oriFeat.GetFieldAsString("MAX"); while (oriFeat.GetFieldAsString("MAX") == "") { //拿到数组中最大值的索引 int maxId = Array.IndexOf(rastValue, rastValue.Max()); //通过索引拿到空间坐标 double maxX, maxY; StaticTools.indexToGeoSpace(maxId, subRasterOff_Size, Transfrom, out maxX, out maxY); //把空间坐标写进Geomtry OSGeo.OGR.Geometry maxGeom = new OSGeo.OGR.Geometry(OSGeo.OGR.wkbGeometryType.wkbPoint); maxGeom.AddPoint_2D(maxX, maxY); //判断坐标是否在Feature中,在则把值写入对应字段,不在则把当前值改为平均值 if (maxGeom.Within(oriGeom)) { oriFeat.SetField("MAX", rastValue.Max()); } else { rastValue[maxId] = rastValue.Average(); } } string dd = oriFeat.GetFieldAsString("MIN"); while (oriFeat.GetFieldAsString("MIN") == "") { //拿到数组中最小值的索引 double ffdf = rastValue.Min(); int minId = Array.IndexOf(rastValue, rastValue.Min()); //通过索引拿到空间坐标 double minX, minY; StaticTools.indexToGeoSpace(minId, subRasterOff_Size, Transfrom, out minX, out minY); //把空间坐标写进Geomtry OSGeo.OGR.Geometry minGeom = new OSGeo.OGR.Geometry(OSGeo.OGR.wkbGeometryType.wkbPoint); minGeom.AddPoint_2D(minX, minY); //判断坐标是否在Feature中,在则把值写入对应字段,不在则把当前值改为平均值 OSGeo.OGR.Geometry bufGeom = bufFeat.GetGeometryRef(); if (minGeom.Within(bufGeom)) { oriFeat.SetField("MIN", rastValue.Min()); } else { rastValue[minId] = rastValue.Average(); } } double max = oriFeat.GetFieldAsDouble("MAX"); double min = oriFeat.GetFieldAsDouble("MIN"); oriFeat.SetField("HIGHT", max - min); }