public static string SaveDataInFile(string filename, IEnumerable data, int width, int height, DataType dataType, double[] argin = null, string shapeSrs = null) { OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); using (Dataset outputDataset = outputDriver.Create(filename, width, height, 1, dataType, null)) { if (argin != null) { outputDataset.SetGeoTransform(argin); } Band outputband = outputDataset.GetRasterBand(1); switch (dataType) { case DataType.GDT_UInt16: outputband.WriteRaster(0, 0, width, height, (short[])data, width, height, 0, 0); break; case DataType.GDT_Byte: outputband.WriteRaster(0, 0, width, height, (byte[])data, width, height, 0, 0); break; } if (!string.IsNullOrEmpty(shapeSrs)) { outputDataset.SetProjection(shapeSrs); } outputDataset.FlushCache(); outputband.FlushCache(); } return(filename); }
private Dataset CreatePngDataset(int idOverview, int xoff, int yoff, int tileSize, bool hasAlpha) { string[] aryOption = { "" }; OSGeo.GDAL.Driver drv = Gdal.GetDriverByName("MEM"); int nBand = hasAlpha ? _ds.RasterCount + 1 : _ds.RasterCount; Dataset dsReturn = drv.Create("filememory", tileSize, tileSize, nBand, _ds.GetRasterBand(1).DataType, aryOption); dsReturn.SetProjection(_ds.GetProjection()); double[] _gt = new double[6]; _ds.GetGeoTransform(_gt); if (idOverview != -1) { _gt[1] *= Math.Pow(2, (double)(idOverview + 1)); _gt[5] *= Math.Pow(2, (double)(idOverview + 1)); } _gt[0] += xoff * _gt[1]; // X origin _gt[3] += yoff * _gt[5]; // Y origin dsReturn.SetGeoTransform(_gt); return(dsReturn); }
/// <summary> /// 栅格重建,srPath输入,dsPath输出,1为1=>1, 2为1=>4, 3为1=>9, /// </summary> /// <param name="srPath"></param> /// <param name="dsPath"></param> /// <param name="level"></param> public static void ImgReProject(string srPath, string dsPath, int level = 2) { Console.WriteLine("ReprojectImage开始,lever 2"); double[] geoTran = new double[6]; double[] geoTran2 = new double[6]; //读 OSGeo.GDAL.Gdal.AllRegister(); Dataset ds = Gdal.Open(srPath, Access.GA_ReadOnly); ds.GetGeoTransform(geoTran); geoTran2 = geoTran; geoTran2[1] = geoTran[1] / level; geoTran2[5] = geoTran[5] / level; //建 OSGeo.GDAL.Driver gdalDriver = Gdal.GetDriverByName("HFA"); Dataset ods = gdalDriver.Create(dsPath, ds.RasterXSize * level, ds.RasterYSize * level, 1, DataType.GDT_Float32, null); ods.SetProjection(ds.GetProjection()); ods.SetGeoTransform(geoTran2); ods.GetRasterBand(1).SetNoDataValue(-999999); //写 Gdal.ReprojectImage(ds, ods, null, null, ResampleAlg.GRA_NearestNeighbour, 0, 0.02, null, null); ds.Dispose(); ods.Dispose(); Console.WriteLine("ReprojectImage完成"); }
public static List <string> GetSupportRasterExtensions() { int driverCount = Gdal.GetDriverCount(); List <string> extensions = new List <string>(); for (int i = 0; i < driverCount; i++) { using (OSGeo.GDAL.Driver driver = Gdal.GetDriver(i)) { string[] metadata = driver.GetMetadata(""); var str = metadata.FirstOrDefault(x => x.Contains("DMD_EXTENSION=")); if (str != null) { var extension = str.Split('=')[1]; bool isRaster = metadata.Any(x => x == "DCAP_RASTER=YES"); extension = $".{extension}"; if (!extensions.Contains(extension)) { extensions.Add(extension); } } } } return(extensions); }
/// <summary> /// Prints initialized Gdal drivers. /// </summary> private static void PrintDriversGdal() { if (!Usable) { throw new Exception(string.Format(Strings.UnableToPrintDrivers, "GDAL")); } int driverCount = Gdal.GetDriverCount(); for (int index = 0; index < driverCount; index++) { try { using (OSGeo.GDAL.Driver driver = Gdal.GetDriver(index)) { Console.WriteLine($"GDAL {index}: {driver.ShortName}-{driver.LongName}"); } } catch (Exception exception) { throw new Exception(string.Format(Strings.UnableToPrintDrivers), exception); } } }
public DriverInfo(Driver gdalDriver) { shortName = gdalDriver.ShortName; longName = gdalDriver.LongName; hasCreate = GetMetadataItem(gdalDriver, "DCAP_CREATE") == "YES"; hasCreateCopy = GetMetadataItem(gdalDriver, "DCAP_CREATECOPY") == "YES"; }
public static void PrintMetadata(Driver driver, string prefix) { string[] metadata = driver.GetMetadata(""); foreach (string metadataItem in metadata) Console.WriteLine("{0}{1}", prefix, metadataItem); }
/// <summary> /// 从影像拿到帖图 /// </summary> /// <param name="inMapPath"></param> /// <param name="saveMapPath"></param> void getDom(string inMapPath, string saveMapPath) { Gdal.AllRegister(); Dataset ds = Gdal.Open(inMapPath, Access.GA_ReadOnly); double[] geoTran = new double[6]; ds.GetGeoTransform(geoTran); Envelope enve = new Envelope(); geom.GetEnvelope(enve); int xoff, yoff, xend, yend, xSize, ySize; Tools.geoToImageSpace(geoTran, enve.MinX, enve.MaxY, out xoff, out yoff); Tools.geoToImageSpace(geoTran, enve.MaxX, enve.MinY, out xend, out yend); xSize = xend - xoff; ySize = yend - yoff; if (File.Exists(saveMapPath)) { File.Delete(saveMapPath); } OSGeo.GDAL.Driver dr = Gdal.GetDriverByName("GTiff"); Dataset outDs = dr.Create(saveMapPath, xSize, ySize, 3, DataType.GDT_UInt16, null); for (int i = 1; i <= ds.RasterCount; i++) { double[] values = new double[xSize * ySize]; ds.GetRasterBand(i).ReadRaster(xoff, yoff, xSize, ySize, values, xSize, ySize, 0, 0); outDs.GetRasterBand(i).WriteRaster(0, 0, xSize, ySize, values, xSize, ySize, 0, 0); } ds.Dispose(); outDs.Dispose(); }
public void WriterRasterResult(string nFileName, ResultInfo resultInfo) { try { _fileName = nFileName; _resultInfo = resultInfo; OSGeo.GDAL.Gdal.AllRegister(); OSGeo.GDAL.Driver nDriver = OSGeo.GDAL.Gdal.GetDriverByName("GTiff"); double[] inGeo = _resultInfo.InGeo; string[] strs = new string[] { "INTERLEAVE = PIXEL" }; string prjWGS84 = "GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0,AUTHORITY[\"EPSG\",\"8901\"]],UNIT[\"degree\",0.0174532925199433,AUTHORITY[\"EPSG\",\"912\"]],AUTHORITY[\"EPSG\",\"4326\"]]"; _dataSet = nDriver.Create(_fileName, _resultInfo.Width, _resultInfo.Height, 1, OSGeo.GDAL.DataType.GDT_Byte, strs); _pixels1 = new double[_resultInfo.Width * _resultInfo.Height]; _dataSet.SetGeoTransform(inGeo); _dataSet.SetProjection(prjWGS84); _dataSet.Dispose(); } catch (System.Exception err) { throw new Exception("数据写入失败。" + err.Message); } }
/// <summary> /// 从影像拿到帖图 /// </summary> /// <param name="inMapPath"></param> /// <param name="saveMapPath"></param> void getDom(string inMapPath, string saveMapPath) { Gdal.AllRegister(); OSGeo.GDAL.Gdal.SetConfigOption("GDAL_FILENAME_IS_UTF8", "YES"); //打开DOM Dataset ds = Gdal.Open(inMapPath, Access.GA_ReadOnly); double[] geoTran = new double[6]; ds.GetGeoTransform(geoTran); //拿边界 Envelope enve = new Envelope(); geom.GetEnvelope(enve); int xoff, yoff, xend, yend, xSize, ySize; Tools.geoToImageSpace(geoTran, enve.MinX, enve.MaxY, out xoff, out yoff); Tools.geoToImageSpace(geoTran, enve.MaxX, enve.MinY, out xend, out yend); xSize = xend - xoff; ySize = yend - yoff; //创建新文件 if (File.Exists(saveMapPath)) { File.Delete(saveMapPath); } OSGeo.GDAL.Driver dr = Gdal.GetDriverByName("GTIFF"); Dataset outDs = dr.Create(saveMapPath, xSize, ySize, 3, DataType.GDT_Byte, null);// --------------------for test geoTran[0] = enve.MinX; geoTran[3] = enve.MaxY; outDs.SetGeoTransform(geoTran); for (int i = 1; i <= ds.RasterCount; i++) { int[] values = new int[xSize * ySize]; ds.GetRasterBand(i).ReadRaster(xoff, yoff, xSize, ySize, values, xSize, ySize, 0, 0); Band band = outDs.GetRasterBand(i); band.WriteRaster(0, 0, xSize, ySize, values, xSize, ySize, 0, 0); band.FlushCache(); outDs.FlushCache(); } for (int b = 1; b < 4; b++) { double min, max, mean, std; Band oriBand = ds.GetRasterBand(b); Band band = outDs.GetRasterBand(b); //P1 是否接受小误差 --------------------for test oriBand.ComputeStatistics(true, out min, out max, out mean, out std, null, ""); band.SetStatistics(min, max, mean, std); band.FlushCache(); } outDs.Dispose(); ds.Dispose(); }
private void _DatasetPng2File(Dataset ds, string sFileName) { OSGeo.GDAL.Driver drv = Gdal.GetDriverByName("PNG"); string[] aryOption = { "" }; Dataset dsOut = drv.CreateCopy(sFileName, ds, 0, aryOption, null, null); dsOut.FlushCache(); dsOut.Dispose(); }
private static void StartClippingProcess(Layer layer, string rasterName, double rasterCellSize, out Dataset outAlignedRaster) { DriverUtils.RegisterGdalOgrDrivers(); //Extrac srs from input feature string inputShapeSrs; SpatialReference spatialRefrence = layer.GetSpatialRef(); spatialRefrence.ExportToWkt(out inputShapeSrs); Envelope envelope = new Envelope(); layer.GetExtent(envelope, 0); //Compute the out raster cell resolutions int x_res = Convert.ToInt32((envelope.MaxX - envelope.MinX) / rasterCellSize); int y_res = Convert.ToInt32((envelope.MaxY - envelope.MinY) / rasterCellSize); Dataset oldRasterDataset = Gdal.Open(rasterName, Access.GA_ReadOnly); //No of bands in older dataset int rasterBands = oldRasterDataset.RasterCount; //Create new tiff in disk string tempRaster = "tempValueRaster.tif"; if (File.Exists(tempRaster)) { File.Delete(tempRaster); } OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); outAlignedRaster = outputDriver.Create(tempRaster, x_res, y_res, rasterBands, DataType.GDT_Float32, null); //Geotransform double[] argin = new double[] { envelope.MinX, rasterCellSize, 0, envelope.MaxY, 0, -rasterCellSize }; outAlignedRaster.SetGeoTransform(argin); //Set no data for (int rasBand = 1; rasBand <= rasterBands; rasBand++) { Band band = outAlignedRaster.GetRasterBand(rasBand); band.Fill(GdalUtilConstants.NoDataValue, 0.0); } //band.SetNoDataValue(GdalUtilConstants.NoDataValue); outAlignedRaster.SetProjection(inputShapeSrs); string[] reprojectOptions = { "NUM_THREADS = ALL_CPUS", "WRITE_FLUSH = YES" }; Gdal.ReprojectImage(oldRasterDataset, outAlignedRaster, null, inputShapeSrs, ResampleAlg.GRA_NearestNeighbour, 0.0, 0.0, null, null, reprojectOptions); //flush cache oldRasterDataset.FlushCache(); oldRasterDataset.Dispose(); }
/// <summary> /// Prints available GDAL drivers in DEBUG mode. /// </summary> private static void PrintDriversGdal() { int count = Gdal.GetDriverCount(); for (int i = 0; i < count; i++) { OSGeo.GDAL.Driver driver = Gdal.GetDriver(i); Console.WriteLine($"GDAL {i}: {driver.ShortName}-{driver.LongName}"); } }
/// <summary> /// 改变栅格值 /// </summary> /// <param name="dsm"></param> /// <param name="savePath"></param> public static void editRasterValue(string dsm, string savePath, double doubles = 2) { Gdal.AllRegister(); Dataset inData = Gdal.Open(dsm, Access.GA_ReadOnly); int xSize = inData.RasterXSize; int ySize = inData.RasterYSize; OSGeo.GDAL.Driver dr = Gdal.GetDriverByName("HFA"); Dataset newDs = dr.Create(savePath, xSize, ySize, 1, inData.GetRasterBand(1).DataType, null); double[] GeoTrans = new double[6]; inData.GetGeoTransform(GeoTrans); newDs.SetGeoTransform(GeoTrans); int userSetX = 1000; int userSetY = 1000; int pixelCount = xSize / userSetX + 1; int lineCount = ySize / userSetY + 1; Console.WriteLine("起动单线编辑栅格值,Size为{0}*{1}", xSize, ySize); Console.WriteLine("分块为为{0}*{1},改变值为原来的{2}倍", userSetX, userSetY, doubles); for (int iline = 0; iline < lineCount; iline++) { for (int ipixel = 0; ipixel < pixelCount; ipixel++) { int subXsize = userSetX; int subYsize = userSetY; int offx = subXsize * ipixel; int offy = subYsize * iline; if (ipixel == pixelCount - 1) { subXsize = xSize - subXsize * ipixel - 1; } if (iline == lineCount - 1) { subYsize = ySize - subYsize * iline - 1; } double[] rasterValue = new double[subXsize * subYsize]; inData.GetRasterBand(1).ReadRaster(offx, offy, subXsize, subYsize, rasterValue, subXsize, subYsize, 0, 0); for (int v = 0; v < rasterValue.Length; v++) { rasterValue[v] = rasterValue[v] * doubles; } newDs.GetRasterBand(1).WriteRaster(offx, offy, subXsize, subYsize, rasterValue, subXsize, subYsize, 0, 0); Console.WriteLine("编辑栅格值,已完成:{0}/{1}", iline * ipixel, lineCount * pixelCount); } } newDs.Dispose(); inData.Dispose(); }
public static HandleRef getCPtrAndSetReference(Driver obj, object parent) { if (obj != null) { obj.swigParentRef = parent; return obj.swigCPtr; } else { return new HandleRef(null, IntPtr.Zero); } }
public static HandleRef getCPtrAndDisown(Driver obj, object parent) { if (obj != null) { obj.swigCMemOwn = false; obj.swigParentRef = parent; return obj.swigCPtr; } else { return new HandleRef(null, IntPtr.Zero); } }
public bool LatLon_TiffToUTM_Tiff(string inPut, string outPut, int band = 1) { FileInfo inPutFile = new FileInfo(inPut); //입력 파일이 없다면 종료 if (!inPutFile.Exists) { return(false); } else { //입력 파일이 tif / tiff 파일이 아니라면 종료 if (inPutFile.Extension != ".tif" && inPutFile.Extension != ".tiff") { return(false); } } #region Create Tiff Gdal.AllRegister(); Dataset dataset = Gdal.Open(inPut, Access.GA_ReadOnly); //SpatialReference dstt_srs = new SpatialReference(""); //dstt_srs.SetFromUserInput("+proj=utm +zone=21 +ellps=WGS84 +datum=WGS84 +units=m +no_defs"); string t_srs_wkt = "GEOGCS[\"WGS84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.01745329251994328]]"; //dstt_srs.ExportToWkt(out t_srs_wkt); //SpatialReference src_srs = new SpatialReference(""); //src_srs.SetFromUserInput("+proj=longlat"); string s_srs_wkt = dataset.GetProjectionRef(); //src_srs.ExportToWkt(out s_srs_wkt); Dataset dswarp = Gdal.AutoCreateWarpedVRT(dataset, s_srs_wkt, t_srs_wkt, ResampleAlg.GRA_NearestNeighbour, 0.125); string[] options = null; OSGeo.GDAL.Driver srcDrv = Gdal.GetDriverByName("GTiff"); Dataset dstDs = srcDrv.CreateCopy(outPut, dswarp, 0, options, null, null); //dstDs.SetProjection(dataset.GetProjection()); //double[] geot = new double[6]; //dataset.GetGeoTransform(geot); //dstDs.SetGeoTransform(geot); dstDs.FlushCache(); dstDs.Dispose(); srcDrv.Dispose(); #endregion return(true); }
// 将给定Tif转换为Web Mercator投影 public void TransformTiff(Dataset ds, double[] VerticeX, double[] VerticeY, string FilePath, ResampleAlg eResampleMethod) { //获取Web墨卡托坐标系 SpatialReference Mercator = new SpatialReference(""); Mercator.ImportFromEPSG(3857); // Web Mercator Mercator.SetMercator(0d, 0d, 1d, 0d, 0d); string MercatorWkt; Mercator.ExportToWkt(out MercatorWkt); //原栅格坐标信息 SpatialReference Raster_spf = new SpatialReference(ds.GetProjectionRef()); //影像四个顶点投影转换 CoordinateTransformation coordinateTrans = Osr.CreateCoordinateTransformation(Raster_spf, Mercator); coordinateTrans.TransformPoints(4, VerticeX, VerticeY, null); //VerticeX和VerticeY存储的是影像四个顶点坐标 coordinateTrans.Dispose(); //计算重投影后栅格顶点坐标 double dbMinx = 0; double dbMaxx = 0; double dbMiny = 0; double dbMaxy = 0; dbMinx = Math.Min(Math.Min(Math.Min(VerticeX[0], VerticeX[1]), VerticeX[2]), VerticeX[3]); dbMaxx = Math.Max(Math.Max(Math.Max(VerticeX[0], VerticeX[1]), VerticeX[2]), VerticeX[3]); dbMiny = Math.Min(Math.Min(Math.Min(VerticeY[0], VerticeY[1]), VerticeY[2]), VerticeY[3]); dbMaxy = Math.Max(Math.Max(Math.Max(VerticeY[0], VerticeY[1]), VerticeY[2]), VerticeY[3]); //计算新的仿射变换参数 double[] newTransform = new double[6]; newTransform[0] = dbMinx; //左上角点x坐标 newTransform[3] = dbMaxy; //左上角点y坐标 newTransform[1] = 100; //像素宽度 newTransform[5] = -100; //像素高度 //计算大小 int width = (int)Math.Ceiling(Math.Abs(dbMaxx - dbMinx) / 100.0); int height = (int)Math.Ceiling(Math.Abs(dbMaxy - dbMiny) / 100.0); //创建新的栅格影像 OSGeo.GDAL.Driver pGDalDriver = Gdal.GetDriverByName("GTiff"); Dataset poDataset = pGDalDriver.Create(FilePath, width, height, 1, DataType.GDT_Float32, null); poDataset.SetGeoTransform(newTransform); poDataset.SetProjection(MercatorWkt); //重投影 Gdal.ReprojectImage(ds, poDataset, ds.GetProjectionRef(), MercatorWkt, eResampleMethod, 0, 0, new Gdal.GDALProgressFuncDelegate(ProgressFunc), null, null); //设置NoData值 Band band = poDataset.GetRasterBand(1); band.SetNoDataValue(-10000000); poDataset.FlushCache(); poDataset.Dispose(); }
/// <summary>初始数据源 /// </summary> /// <param name="strFilename">文件名</param> /// <param name="oFileEncoding">文件编码类型</param> /// <param name="nLayerindex">层序号</param> /// <param name="bUpdata">是否可以修改</param> /// <returns></returns> public bool CreateDataset(string strFilename, Encoding oFileEncoding, int nLayerindex = 0, bool bUpdata = false) { int bXSize, bYSize; int w, h; w = 100; h = 100; bXSize = w; bYSize = 1; Gdal.AllRegister(); OSGeo.GDAL.Driver drv = Gdal.GetDriverByName("GTiff"); if (drv == null) { Console.WriteLine("Can't get driver."); System.Environment.Exit(-1); } Console.WriteLine("Using driver " + drv.LongName); string[] options = new string[] { "BLOCKXSIZE=" + bXSize, "BLOCKYSIZE=" + bYSize }; Dataset ds = drv.Create(strFilename, w, h, 1, DataType.GDT_Byte, options); if (ds == null) { Console.WriteLine("Can't open " + strFilename); System.Environment.Exit(-1); } 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, ""); Band ba = ds.GetRasterBand(1); byte[] buffer = new byte[w * h]; for (int i = 0; i < w; i++) { for (int j = 0; j < h; j++) { buffer[i * w + j] = (byte)(i * 256 / w); } } ba.WriteRaster(0, 0, w, h, buffer, w, h, 0, 0); ba.FlushCache(); ds.FlushCache(); return(true); }
public bool TransToGrid(double[] padfX, double[] padfY, double[] padfZ, double[] dEnvelopes, string outFilename, double dPixCellSize = 0.0005, double dEnvelope_offsetX = 0, double dEnvelope_offsetY = 0, DataType typeData = DataType.GDT_Float64) { if (padfX.Length != padfY.Length && padfX.Length != padfZ.Length) { return(false); } //计算图像大小-按数据边界(dEnvelopes:MinX,MaxX,MinY,MaxY) int nNumPoints = padfX.Length; int nXSize = (int)((dEnvelopes[1] - dEnvelopes[0] + 2 * dEnvelope_offsetX) / dPixCellSize); int nYSize = (int)((dEnvelopes[3] - dEnvelopes[2] + 2 * dEnvelope_offsetY) / dPixCellSize); // 创建输出数据集,格式为GeoTiff格式 OSGeo.GDAL.Driver poDriver = Gdal.GetDriverByName(_DstDriverName); Dataset poDataset = poDriver.Create(outFilename, nXSize, nYSize, 1, typeData, null); if (_SpatialWKT != "") { poDataset.SetProjection(_SpatialWKT); } // 离散点内插方法,参数生成 string poOptions = _GdalAlg.InitOptions(); double[] pData = new double[nXSize * nYSize]; Gdal.GridCreate(poOptions, nNumPoints, padfX, padfY, padfZ, dEnvelopes[0], dEnvelopes[1], dEnvelopes[2], dEnvelopes[3], nXSize, nYSize, typeData, pData, nXSize * nYSize * 8, null, null); // 设置六参数 double[] adfGeoTransform = new double[] { dEnvelopes[0] - dEnvelope_offsetX, dPixCellSize, 0, dEnvelopes[3] + dEnvelope_offsetY, 0, -dPixCellSize }; poDataset.SetGeoTransform(adfGeoTransform); // 写入影像 Band poBand = poDataset.GetRasterBand(1); poBand.WriteRaster(0, 0, nXSize, nYSize, pData, nXSize, nYSize, 0, 0); poBand.SetNoDataValue(_NoDataValue); poBand.FlushCache(); poDataset.FlushCache(); // 释放资源 关闭图像 poBand.Dispose(); poDriver.Dispose(); poDataset.Dispose(); return(true); }
public void Sloping(string DemPath, string OutSlpPath) { Gdal.AllRegister(); Stopwatch sw = new Stopwatch(); sw.Start(); Console.WriteLine("【开始创建SlopeMap!】"); int hasVal; double demNodata; double[] geoTransform = new double[6]; //打开 Dataset InDataset = Gdal.Open(DemPath, Access.GA_Update); InDataset.GetRasterBand(1).GetNoDataValue(out demNodata, out hasVal); InDataset.GetGeoTransform(geoTransform); //调用GDal创建影像,声明影像格式 OSGeo.GDAL.Driver gdalDriver = Gdal.GetDriverByName("HFA"); slopeDs = gdalDriver.Create(OutSlpPath, InDataset.RasterXSize, InDataset.RasterYSize, 1, DataType.GDT_Float32, null); slopeDs.SetProjection(InDataset.GetProjection()); slopeDs.SetGeoTransform(geoTransform); if (hasVal == 0) { InDataset.GetRasterBand(1).SetNoDataValue(-100000); slopeDs.GetRasterBand(1).SetNoDataValue(-100000); slpNodata = -100000; } else { slopeDs.GetRasterBand(1).SetNoDataValue(demNodata); slpNodata = demNodata; } InDataset.Dispose(); asyRE = new AutoResetEvent(false); Thread th = new Thread(() => { MySloping(DemPath); }); th.Start(); asyRE.WaitOne(); InDataset = Gdal.Open(DemPath, Access.GA_ReadOnly); //FixOutLineRaster(InDataset.GetRasterBand(1), demNodata); //处理外围的Raster BufferOnePixel(slopeDs.GetRasterBand(1)); slopeDs.Dispose(); sw.Stop(); Console.WriteLine("【SlopeMap完成,用时:" + sw.Elapsed.ToString() + "】"); }
private Dataset multi(Dataset oriDs, Dataset maskDs, string outPath) { int blockSize = 10240; int xSize = oriDs.RasterXSize; int leftXSize = xSize; int xOffset = 0; int ySize = oriDs.RasterYSize; int leftYSize = ySize; int yOffset = 0; progressInfo.SubTitle = "正在裁剪"; while (leftYSize > 0) { int readYSize = (leftYSize > blockSize) ? blockSize : leftYSize; leftYSize = leftYSize - readYSize; xOffset = 0; leftXSize = xSize; while (leftXSize > 0) { int readXSize = (leftXSize > blockSize) ? blockSize : leftXSize; leftXSize = leftXSize - readXSize; int totalSize = readXSize * readYSize; byte[] oriData = new byte[totalSize]; byte[] maskData = new byte[totalSize]; oriDs.ReadRaster(xOffset, yOffset, readXSize, readYSize, oriData, readXSize, readYSize, 1, null, 0, 0, 0); maskDs.ReadRaster(xOffset, yOffset, readXSize, readYSize, maskData, readXSize, readYSize, 1, null, 0, 0, 0); for (int i = 0; i < totalSize; i++) { oriData[i] = (byte)(oriData[i] * maskData[i]); } oriDs.WriteRaster(xOffset, yOffset, readXSize, readYSize, oriData, readXSize, readYSize, 1, null, 0, 0, 0); xOffset = xOffset + readXSize; } yOffset = yOffset + readYSize; } progressInfo.SubTitle = "写入影像"; OSGeo.GDAL.Driver driver = Gdal.GetDriverByName("GTiff"); string[] options = new string[] { "-co", "COMPRESS=LZW", "-co", "TILED=YES" }; return(driver.CreateCopy(outPath, oriDs, 0, options, gdalProgressFunc, null)); }
public RasterRepair(string imgPath, string shpPath, Action callback = null) { _imgPath = imgPath; _shpPath = shpPath; double[] geoTransform = new double[6]; Dataset imgDs = Gdal.Open(_imgPath, Access.GA_Update); imgDs.GetGeoTransform(geoTransform); Band _band = imgDs.GetRasterBand(1); OSGeo.GDAL.Driver d = Gdal.GetDriverByName("HFA"); //Dataset dsout = d.Create(_orderPath, _band.XSize, _band.YSize, 1, DataType.GDT_Float32, null); OSGeo.OGR.Driver dr = OSGeo.OGR.Ogr.GetDriverByName("ESRI shapefile"); DataSource ds = dr.Open(_shpPath, 0); Layer lyr = ds.GetLayerByIndex(0); thr tr = new thr(imgDs, imgPath, geoTransform, lyr); tr.Repair(callback); }
//矢量转栅格 private void RasterizeLayer(Layer layer, string outRaster, string field, float resolution, int xSize, int ySize) { const double noDataValue = -9999; // NoData值 string outputRasterFile = outRaster; Envelope envelope = new Envelope(); //原图层外接矩形 layer.GetExtent(envelope, 0); //新建栅格图层 OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); Dataset outputDataset = outputDriver.Create(outputRasterFile, xSize, ySize, 1, DataType.GDT_Int32, null);//DataType.GDT_Float64 //获取原矢量图层坐标系 string inputShapeSrs; OSGeo.OSR.SpatialReference spatialRefrence = layer.GetSpatialRef(); spatialRefrence.ExportToWkt(out inputShapeSrs); outputDataset.SetProjection(inputShapeSrs); double[] argin = new double[] { envelope.MinX, resolution, 0, envelope.MaxY, 0, -resolution }; outputDataset.SetGeoTransform(argin); Band band = outputDataset.GetRasterBand(1); band.SetNoDataValue(noDataValue); outputDataset.FlushCache(); outputDataset.Dispose(); //矢量转栅格 int[] bandlist = new int[] { 1 }; double[] burnValues = new double[] { 10.0 }; Dataset myDataset = Gdal.Open(outputRasterFile, Access.GA_Update); string[] rasterizeOptions; rasterizeOptions = new string[] { "ATTRIBUTE=" + field, "ALL_TOUCHED=TRUE" }; int tets = Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, rasterizeOptions, new Gdal.GDALProgressFuncDelegate(ProgressFunc), "Raster conversion"); myDataset.FlushCache(); myDataset.Dispose(); }
public static void Rasterize(string inputFeature, string referRaster, string outRaster, string fieldName = "") { //Register the raster drivers Gdal.AllRegister(); //Register the vector drivers Ogr.RegisterAll(); //Open referRaster Dataset _referRaster = Gdal.Open(referRaster, Access.GA_ReadOnly); //Get geoTransform Args double[] _geoTransform = new double[6]; _referRaster.GetGeoTransform(_geoTransform); // Define pixel_size and NoData value of new raster //int rasterCellSize = cellSize; double _xCellSize = _geoTransform[1]; double _yCellSize = -_geoTransform[5]; const double noDataValue = -10000; string outputRasterFile = outRaster; //Reading the vector data DataSource dataSource = Ogr.Open(inputFeature, 0); Layer layer = dataSource.GetLayerByIndex(0); Envelope envelope = new Envelope(); layer.GetExtent(envelope, 0); //Compute the out raster cell resolutions int x_res = _referRaster.RasterXSize; int y_res = _referRaster.RasterYSize; //Console.WriteLine("Extent: " + envelope.MaxX + " " + envelope.MinX + " " + envelope.MaxY + " " + envelope.MinY); //Console.WriteLine("X resolution: " + x_res); //Console.WriteLine("X resolution: " + y_res); //Check if output raster exists & delete (optional) if (File.Exists(outputRasterFile)) { File.Delete(outputRasterFile); } //Create new tiff DataType dType = _referRaster.GetRasterBand(1).DataType; //OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("HFA"); Dataset outputDataset = outputDriver.Create(outputRasterFile, x_res, y_res, 1, dType, null); //Extrac srs from input feature string inputShapeSrs; OSGeo.OSR.SpatialReference spatialRefrence = layer.GetSpatialRef(); if (spatialRefrence != null) { spatialRefrence.ExportToWkt(out inputShapeSrs); //Assign input feature srs to outpur raster outputDataset.SetProjection(inputShapeSrs); } //Geotransform outputDataset.SetGeoTransform(_geoTransform); //Set no data Band band = outputDataset.GetRasterBand(1); band.SetNoDataValue(noDataValue); //close tiff outputDataset.FlushCache(); outputDataset.Dispose(); //Feature to raster rasterize layer options //No of bands (1) int[] bandlist = new int[] { 1 }; //Values to be burn on raster (10.0) double[] burnValues = new double[] { 10.0 }; Dataset myDataset = Gdal.Open(outputRasterFile, Access.GA_Update); //additional options string[] rasterizeOptions; //rasterizeOptions = new string[] { "ALL_TOUCHED=TRUE", "ATTRIBUTE=" + fieldName }; //To set all touched pixels into raster pixel //rasterizeOptions = new string[] { "ATTRIBUTE=" + fieldName }; rasterizeOptions = new string[] { }; //Rasterize layer //Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, null, null, null); // To burn the given burn values instead of feature attributes //Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, rasterizeOptions, new Gdal.GDALProgressFuncDelegate(ProgressFunc), "Raster conversion"); Gdal.RasterizeLayer( myDataset, //NEW inDS 1, //BAND bandlist, //int[] bandlist = new int[] { 1 };Band数量 layer, // 待转 IntPtr.Zero, IntPtr.Zero, 1, burnValues, //Values to be burn on raster (10.0) rasterizeOptions, new Gdal.GDALProgressFuncDelegate(ProgressFunc), "Raster conversion" ); myDataset.FlushCache(); myDataset.Dispose(); }
public static GeoBitmap LoadImageInfo(string file) { using (var ds = OSGeo.GDAL.Gdal.Open(file, OSGeo.GDAL.Access.GA_ReadOnly)) { log.InfoFormat("Raster dataset parameters:"); log.InfoFormat(" Projection: " + ds.GetProjectionRef()); log.InfoFormat(" RasterCount: " + ds.RasterCount); log.InfoFormat(" RasterSize (" + ds.RasterXSize + "," + ds.RasterYSize + ")"); OSGeo.GDAL.Driver drv = ds.GetDriver(); log.InfoFormat("Using driver " + drv.LongName); string[] metadata = ds.GetMetadata(""); if (metadata.Length > 0) { log.InfoFormat(" Metadata:"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { // log.InfoFormat(" " + iMeta + ": " + metadata[iMeta]); } log.InfoFormat(""); } metadata = ds.GetMetadata("IMAGE_STRUCTURE"); if (metadata.Length > 0) { log.InfoFormat(" Image Structure Metadata:"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { log.InfoFormat(" " + iMeta + ": " + metadata[iMeta]); } log.InfoFormat(""); } metadata = ds.GetMetadata("SUBDATASETS"); if (metadata.Length > 0) { log.InfoFormat(" Subdatasets:"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { log.InfoFormat(" " + iMeta + ": " + metadata[iMeta]); } log.InfoFormat(""); } metadata = ds.GetMetadata("GEOLOCATION"); if (metadata.Length > 0) { log.InfoFormat(" Geolocation:"); for (int iMeta = 0; iMeta < metadata.Length; iMeta++) { log.InfoFormat(" " + iMeta + ": " + metadata[iMeta]); } log.InfoFormat(""); } log.InfoFormat("Corner Coordinates:"); log.InfoFormat(" Upper Left (" + GDALInfoGetPosition(ds, 0.0, 0.0) + ")"); log.InfoFormat(" Lower Left (" + GDALInfoGetPosition(ds, 0.0, ds.RasterYSize) + ")"); log.InfoFormat(" Upper Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, 0.0) + ")"); log.InfoFormat(" Lower Right (" + GDALInfoGetPosition(ds, ds.RasterXSize, ds.RasterYSize) + ")"); log.InfoFormat(" Center (" + GDALInfoGetPosition(ds, ds.RasterXSize / 2, ds.RasterYSize / 2) + ")"); log.InfoFormat(""); 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); log.InfoFormat("Coordinate System is:"); log.InfoFormat(wkt); } else { log.InfoFormat("Coordinate System is:"); log.InfoFormat(projection); } } if (ds.GetGCPCount() > 0) { log.InfoFormat("GCP Projection: ", ds.GetGCPProjection()); GCP[] GCPs = ds.GetGCPs(); for (int i = 0; i < ds.GetGCPCount(); i++) { log.InfoFormat("GCP[" + i + "]: Id=" + GCPs[i].Id + ", Info=" + GCPs[i].Info); log.InfoFormat(" (" + GCPs[i].GCPPixel + "," + GCPs[i].GCPLine + ") -> (" + GCPs[i].GCPX + "," + GCPs[i].GCPY + "," + GCPs[i].GCPZ + ")"); log.InfoFormat(""); } log.InfoFormat(""); double[] transform = new double[6]; Gdal.GCPsToGeoTransform(GCPs, transform, 0); log.InfoFormat("GCP Equivalent geotransformation parameters: ", ds.GetGCPProjection()); for (int i = 0; i < 6; i++) { log.InfoFormat("t[" + i + "] = " + transform[i].ToString()); } log.InfoFormat(""); } var TL = GDALInfoGetPositionDouble(ds, 0.0, 0.0); var BR = GDALInfoGetPositionDouble(ds, ds.RasterXSize, ds.RasterYSize); var resolution = Math.Abs(BR[0] - TL[0]) / ds.RasterXSize; if (resolution == 1) { throw new Exception("Invalid coords"); } return(new GeoBitmap(file, resolution, ds.RasterXSize, ds.RasterYSize, TL[0], TL[1], BR[0], BR[1])); } }
//http://www.gisremotesensing.com/2015/09/vector-to-raster-conversion-using-gdal-c.html public static void Rasterize(string inputFeature, string outRaster, string fieldName, int cellSize) { // Define pixel_size and NoData value of new raster int rasterCellSize = cellSize; const double noDataValue = -9999; string outputRasterFile = outRaster; //Register the vector drivers Ogr.RegisterAll(); //Reading the vector data DataSource dataSource = Ogr.Open(inputFeature, 0); var count = dataSource.GetLayerCount(); Layer layer = dataSource.GetLayerByIndex(0); var litems = layer.GetFeatureCount(0); var lname = layer.GetName(); Envelope envelope = new Envelope(); layer.GetExtent(envelope, 0); //Compute the out raster cell resolutions int x_res = Convert.ToInt32((envelope.MaxX - envelope.MinX) / rasterCellSize); int y_res = Convert.ToInt32((envelope.MaxY - envelope.MinY) / rasterCellSize); Console.WriteLine("Extent: " + envelope.MaxX + " " + envelope.MinX + " " + envelope.MaxY + " " + envelope.MinY); Console.WriteLine("X resolution: " + x_res); Console.WriteLine("X resolution: " + y_res); //Register the raster drivers Gdal.AllRegister(); //Check if output raster exists & delete (optional) if (File.Exists(outputRasterFile)) { File.Delete(outputRasterFile); } //Create new tiff OSGeo.GDAL.Driver outputDriver = Gdal.GetDriverByName("GTiff"); Dataset outputDataset = outputDriver.Create(outputRasterFile, x_res, y_res, 1, DataType.GDT_Float64, null); //Extrac srs from input feature string inputShapeSrs; SpatialReference spatialRefrence = layer.GetSpatialRef(); spatialRefrence.ExportToWkt(out inputShapeSrs); //Assign input feature srs to outpur raster outputDataset.SetProjection(inputShapeSrs); //Geotransform double[] argin = new double[] { envelope.MinX, rasterCellSize, 0, envelope.MaxY, 0, -rasterCellSize }; outputDataset.SetGeoTransform(argin); //Set no data Band band = outputDataset.GetRasterBand(1); band.SetNoDataValue(noDataValue); //close tiff outputDataset.FlushCache(); outputDataset.Dispose(); //Feature to raster rasterize layer options //No of bands (1) int[] bandlist = new int[] { 1 }; //Values to be burn on raster (10.0) double[] burnValues = new double[] { 10.0 }; Dataset myDataset = Gdal.Open(outputRasterFile, Access.GA_Update); //additional options string[] rasterizeOptions; //rasterizeOptions = new string[] { "ALL_TOUCHED=TRUE", "ATTRIBUTE=" + fieldName }; //To set all touched pixels into raster pixel rasterizeOptions = new string[] { "ATTRIBUTE=" + fieldName }; //Rasterize layer //Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, null, null, null); // To burn the given burn values instead of feature attributes Gdal.RasterizeLayer(myDataset, 1, bandlist, layer, IntPtr.Zero, IntPtr.Zero, 1, burnValues, rasterizeOptions, new Gdal.GDALProgressFuncDelegate(ProgressFunc), "Raster conversion"); }
public static void Test() { try { // Register Gdal.AllRegister(); // Only works for reading data but not for creating datasets. // string strFilePath = @"C:\Users\Administrator\minigis2\data\gdal_data\092b05.tif"; string strFilePath = @"C:\1.bmp"; //String strFormatCode = "GTiff"; //Driver driver=Gdal.GetDriverByName(strFormatCode); //driver.Register(); // Works for reading and creating datasets. // Open dataset Dataset ds = Gdal.Open(strFilePath, Access.GA_ReadOnly); if (ds != null) { // Get Raster Parameters int xSize = ds.RasterXSize; int ySize = ds.RasterYSize; int bands = ds.RasterCount; string strProjectionRef = ds.GetProjectionRef(); MessageBox.Show("image width=" + xSize + ",height=" + ySize + ", bands=" + bands); // Get Transform double[] adfGeoTransform = new double[6]; ds.GetGeoTransform(adfGeoTransform); double originX = adfGeoTransform[0]; double originY = adfGeoTransform[3]; double pixelWidth = adfGeoTransform[1]; double pixelHeight = adfGeoTransform[5]; // xOffset=int((x-originX)/pixelWidth) // yOffset=int((y-originY)/pixelHeight) } // Get Driver OSGeo.GDAL.Driver driver = ds.GetDriver(); if (driver != null) { string strDescription = driver.GetDescription(); string strLongName = driver.LongName; string strShortName = driver.ShortName; } // Get Raster Band for (int iBand = 1; iBand <= ds.RasterCount; iBand++) { // 1-based Band band = ds.GetRasterBand(iBand); string dataType = band.DataType.ToString(); int xSize = band.XSize; int ySize = band.YSize; string colorInterp = band.GetRasterColorInterpretation().ToString(); for (int iOver = 0; iOver < band.GetOverviewCount(); iOver++) { Band over = band.GetOverview(iOver); string overDataType = over.DataType.ToString(); int overXSize = over.XSize; int overYSize = over.YSize; string overColorInterp = over.GetRasterColorInterpretation().ToString(); } } // Processing the raster data //SaveBitmapBuffered(ds, @"C:\1new.jpg"); } catch (Exception err) { MessageBox.Show(err.Message); } }
private void buttonOk_Click(object sender, EventArgs e) { int width = 0; int height = 0; int times = 0; double threshold = 0.0; if (this.comboBoxInitialUrbanImage.SelectedItem == null || this.comboBoxLandSuitable.SelectedItem == null || this.comboBoxPg.SelectedItem == null) { MessageBox.Show("清先选择图层"); return; } string initialUrbanImageLayerName = this.comboBoxInitialUrbanImage.SelectedItem.ToString(); string pgLayerName = this.comboBoxPg.SelectedItem.ToString(); string landSuitableLayerName = this.comboBoxLandSuitable.SelectedItem.ToString(); try { times = Convert.ToInt32(this.textBoxTimes.Text); threshold = Convert.ToDouble(this.textBoxThreshold.Text); } catch { MessageBox.Show("请输入正确的times 和 threshold参数"); return; } double[] imageBuffer = GetData(initialUrbanImageLayerName, ref width, ref height); double[] pg = GetData(pgLayerName, ref width, ref height); double[] suitableBuffer = GetData(landSuitableLayerName, ref width, ref height); if (imageBuffer == null || pg == null || suitableBuffer == null) { MessageBox.Show("图层名无效,图层不是栅格图层,将图层转化为GDAL dataset失败,从GDAL dataset中读取数据失败"); return; } unsafe { fixed(double *pImageBuffer = imageBuffer, pSuitableBuffer = suitableBuffer, pPg = pg) { // 调用c++接口得到模拟后的数据 SWIGTYPE_p_double result = simple_ca.simple_ca_logistic(new SWIGTYPE_p_double(new IntPtr(pImageBuffer), false), new SWIGTYPE_p_double(new IntPtr(pSuitableBuffer), false), new SWIGTYPE_p_double(new IntPtr(pPg), false), width, height, threshold, times); //simple_ca.draw_image(new SWIGTYPE_p_double(new IntPtr(pImageBuffer), false), width, height); //// 从指针中得到模拟结果,并纵向翻转 IntPtr resultPointer = HandleRef.ToIntPtr(SWIGTYPE_p_double.getCPtr(result)); double *pResultImg = (double *)resultPointer.ToPointer(); double[] resultImg = new double[width * height]; for (int row = 0; row < height; row++) { for (int col = 0; col < width; col++) { resultImg[row * width + col] = pResultImg[(height - row - 1) * width + col]; } } // 新建 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, resultImg, 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"; this.Map.Layers.Add(raster); } } }
public static HandleRef getCPtr(Driver obj) { return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; }
private string GetMetadataItem(Driver gdalDriver, string itemName) { string itemValue = gdalDriver.GetMetadataItem(itemName, ""); return itemValue; }
protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> boundary = new List <Curve>(); DA.GetDataList <Curve>(0, boundary); string IMG_file = ""; DA.GetData <string>("IMG Location", ref IMG_file); /* * //Does not work with HGT files * * byte[] imageBuffer; * * using (FileStream fs = new FileStream(IMG_file, FileMode.Open, FileAccess.Read)) * { * using (BinaryReader br = new BinaryReader(fs)) * { * long numBytes = new FileInfo(IMG_file).Length; * imageBuffer = br.ReadBytes((int)numBytes); * br.Close(); * fs.Close(); * } * } */ RESTful.GdalConfiguration.ConfigureGdal(); OSGeo.GDAL.Gdal.AllRegister(); //string memFilename = "/vsimem/inmemfile"; //Gdal.FileFromMemBuffer(memFilename, imageBuffer); Dataset ds = Gdal.Open(IMG_file, Access.GA_ReadOnly); OSGeo.GDAL.Driver drv = ds.GetDriver(); if (ds == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "The vector datasource was unreadable by this component. It may not a valid file type for this component or otherwise null/empty."); return; } ///Get the spatial reference of the input raster file and set to WGS84 if not known ///Set up transform from source to WGS84 OSGeo.OSR.SpatialReference sr = new SpatialReference(Osr.SRS_WKT_WGS84); if (ds.GetProjection() == null) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is missing. CRS set automatically set to WGS84."); } else { sr = new SpatialReference(ds.GetProjection()); if (sr.Validate() != 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Coordinate Reference System (CRS) is unknown or unsupported. CRS set automatically set to WGS84."); sr.SetWellKnownGeogCS("WGS84"); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Remark, "Data source SRS: EPSG:" + sr.GetAttrValue("AUTHORITY", 1)); } } //OSGeo.OSR.SpatialReference sr = new SpatialReference(ds.GetProjection()); OSGeo.OSR.SpatialReference dst = new OSGeo.OSR.SpatialReference(""); dst.SetWellKnownGeogCS("WGS84"); OSGeo.OSR.CoordinateTransformation coordTransform = new OSGeo.OSR.CoordinateTransformation(sr, dst); OSGeo.OSR.CoordinateTransformation revTransform = new OSGeo.OSR.CoordinateTransformation(dst, sr); double[] adfGeoTransform = new double[6]; double[] invTransform = new double[6]; ds.GetGeoTransform(adfGeoTransform); Gdal.InvGeoTransform(adfGeoTransform, invTransform); Band band = ds.GetRasterBand(1); int width = ds.RasterXSize; int height = ds.RasterYSize; //Dataset bounding box double oX = adfGeoTransform[0] + adfGeoTransform[1] * 0 + adfGeoTransform[2] * 0; double oY = adfGeoTransform[3] + adfGeoTransform[4] * 0 + adfGeoTransform[5] * 0; double eX = adfGeoTransform[0] + adfGeoTransform[1] * width + adfGeoTransform[2] * height; double eY = adfGeoTransform[3] + adfGeoTransform[4] * width + adfGeoTransform[5] * height; ///Transform to WGS84 double[] extMinPT = new double[3] { oX, eY, 0 }; double[] extMaxPT = new double[3] { eX, oY, 0 }; coordTransform.TransformPoint(extMinPT); coordTransform.TransformPoint(extMaxPT); Point3d dsMin = new Point3d(extMinPT[0], extMinPT[1], extMinPT[2]); Point3d dsMax = new Point3d(extMaxPT[0], extMaxPT[1], extMaxPT[2]); //Point3d dsMin = new Point3d(oX, eY, 0); //Point3d dsMax = new Point3d(eX, oY, 0); Rectangle3d dsbox = new Rectangle3d(Plane.WorldXY, Heron.Convert.WGSToXYZ(dsMin), Heron.Convert.WGSToXYZ(dsMax)); //Declare trees GH_Structure <GH_Point> pointcloud = new GH_Structure <GH_Point>(); GH_Structure <GH_Integer> rCount = new GH_Structure <GH_Integer>(); GH_Structure <GH_Integer> cCount = new GH_Structure <GH_Integer>(); GH_Structure <GH_Mesh> tMesh = new GH_Structure <GH_Mesh>(); for (int i = 0; i < boundary.Count; i++) { if (dsbox.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Min) && (dsbox.BoundingBox.Contains(boundary[i].GetBoundingBox(true).Max))) { Point3d min = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Corner(true, false, true)); Point3d max = Heron.Convert.XYZToWGS(boundary[i].GetBoundingBox(true).Corner(false, true, true)); ///Transform to source SRS double[] minR = new double[3] { min.X, min.Y, min.Z }; double[] maxR = new double[3] { max.X, max.Y, max.Z }; revTransform.TransformPoint(minR); revTransform.TransformPoint(maxR); GH_Path path = new GH_Path(i); // http://gis.stackexchange.com/questions/46893/how-do-i-get-the-pixel-value-of-a-gdal-raster-under-an-ogr-point-without-numpy double ur, uc, lr, lc; Gdal.ApplyGeoTransform(invTransform, minR[0], minR[1], out uc, out ur); Gdal.ApplyGeoTransform(invTransform, maxR[0], maxR[1], out lc, out lr); //Gdal.ApplyGeoTransform(invTransform, min.X, min.Y, out uc, out ur); //Gdal.ApplyGeoTransform(invTransform, max.X, max.Y, out lc, out lr); int Urow = System.Convert.ToInt32(ur); int Ucol = System.Convert.ToInt32(uc); int Lrow = System.Convert.ToInt32(lr) + 1; int Lcol = System.Convert.ToInt32(lc) + 1; rCount.Append(new GH_Integer(Lrow - Urow), path); cCount.Append(new GH_Integer(Lcol - Ucol), path); Mesh mesh = new Mesh(); List <Point3d> verts = new List <Point3d>(); //var vertsParallel = new System.Collections.Concurrent.ConcurrentDictionary<double[][], Point3d>(Environment.ProcessorCount, ((Urow - 1) * (Lrow - 1))); double[] bits = new double[width * height]; band.ReadRaster(0, 0, width, height, bits, width, height, 0, 0); for (int col = Ucol; col < Lcol; col++) { for (int row = Urow; row < Lrow; row++) { // equivalent to bits[col][row] if bits is 2-dimension array double pixel = bits[col + row * width]; if (pixel < -10000) { pixel = 0; } double gcol = adfGeoTransform[0] + adfGeoTransform[1] * col + adfGeoTransform[2] * row; double grow = adfGeoTransform[3] + adfGeoTransform[4] * col + adfGeoTransform[5] * row; ///convert to WGS84 double[] wgsPT = new double[3] { gcol, grow, pixel }; coordTransform.TransformPoint(wgsPT); Point3d pt = new Point3d(wgsPT[0], wgsPT[1], wgsPT[2]); //Point3d pt = new Point3d(gcol, grow, pixel); verts.Add(Heron.Convert.WGSToXYZ(pt)); } /*Parallel.For(Urow, Lrow - 1, rowP => * { * // equivalent to bits[col][row] if bits is 2-dimension array * double pixel = bits[col + rowP * width]; * if (pixel < -10000) * { * pixel = 0; * } * * double gcol = adfGeoTransform[0] + adfGeoTransform[1] * col + adfGeoTransform[2] * rowP; * double grow = adfGeoTransform[3] + adfGeoTransform[4] * col + adfGeoTransform[5] * rowP; * * Point3d pt = new Point3d(gcol, grow, pixel); * vertsParallel[] = Heron.Convert.ToXYZ(pt); * }); * */ } //Create meshes //non Parallel mesh.Vertices.AddVertices(verts); //Parallel //mesh.Vertices.AddVertices(vertsParallel.Values); for (int u = 1; u < cCount[path][0].Value; u++) { for (int v = 1; v < rCount[path][0].Value; v++) { mesh.Faces.AddFace(v - 1 + (u - 1) * (Lrow - Urow), v - 1 + u * (Lrow - Urow), v - 1 + u * (Lrow - Urow) + 1, v - 1 + (u - 1) * (Lrow - Urow) + 1); //(k - 1 + (j - 1) * num2, k - 1 + j * num2, k - 1 + j * num2 + 1, k - 1 + (j - 1) * num2 + 1) } } //mesh.Flip(true, true, true); tMesh.Append(new GH_Mesh(mesh), path); } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "One or more boundaries may be outside the bounds of the topo dataset."); //return; } } DA.SetDataTree(0, tMesh); DA.SetData(1, dsbox); }
/// <summary> /// 切分图像|| /// 解决图像过大导致的计算缓慢|| /// 输入图像路径,输出分幅路径|| /// 重叠区根据图像分辨率确定,约为实地100~200米 /// </summary> /// <param name="inPaht"></param> /// <returns></returns> public static List <string> getSubImg(string inPaht) { //注册插件 OSGeo.GDAL.Gdal.AllRegister(); OSGeo.GDAL.Driver gdalDriver = OSGeo.GDAL.Gdal.GetDriverByName("HFA"); //读进数据 OSGeo.GDAL.Dataset inDS = OSGeo.GDAL.Gdal.Open(inPaht, OSGeo.GDAL.Access.GA_ReadOnly); //根据栅格分辨率确定重叠区大小 double[] dsTraansform = new double[6]; inDS.GetGeoTransform(dsTraansform); if (dsTraansform[1] < 0.16) { xBuf = 1000; yBuf = 1000; } //1000*0.1=>100M if (dsTraansform[1] < 0.3) { xBuf = 500; yBuf = 500; } //500*0.25=>125M else if (dsTraansform[1] < 0.6) { xBuf = 300; yBuf = 300; } //300*0.5=>150M else if (dsTraansform[1] < 1.1) { xBuf = 200; yBuf = 150; } //150*1=>200M else if (dsTraansform[1] < 2.1) { xBuf = 100; yBuf = 100; } //100*2=>200M else { xBuf = 50; yBuf = 50; } //50*5=>250M //获取数据XY相元数量 int oriXcount = inDS.RasterXSize; int oriYcount = inDS.RasterYSize; //用来返回的文件路径列表 List <string> imgFilePaths = new List <string>(); if (oriXcount > userSetX || oriYcount > userSetY) { //确定文件行列数 int u, v; u = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriXcount) / userSetX)); //行文件数 v = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(oriYcount) / userSetY)); //列文件数 //循环列 for (int i = 0; i < v; i++) { //循环行 for (int j = 0; j < u; j++) { //////////// 定义起点 ///////////// int offX = j * userSetX; int offY = i * userSetY; //////////////定义边缘栅格大小///////////////// int thinkJ = userSetX * (j + 1) + xBuf; int thinkI = userSetY * (i + 1) + yBuf; int subXcount = oriXcount - thinkJ > 0 ? userSetX + xBuf : oriXcount - userSetX * j; int subYcount = oriYcount - thinkI > 0 ? userSetY + yBuf : oriYcount - userSetY * i; //////////// 把原栅格读进内存,内容为oriValue ///////////// OSGeo.GDAL.Band oriBand = inDS.GetRasterBand(1); double[] oriValue = new double[subXcount * subYcount]; oriBand.ReadRaster ( offX, //起点X索引 offY, //起点Y索引 subXcount, //X方向相元数量 subYcount, //Y方向相元数量 oriValue, //各相元值 subXcount, //执行读入的X方向数量 subYcount, //执行读入的Y方向数量 0, //执行读入的起点X索引 0 //执行读入的起点Y索引 ); //////////// 创建子栅格 ///////////// string imgFilePath = StaticTools.tempFilePath("img", i.ToString() + "_" + j.ToString()); OSGeo.GDAL.Dataset subDs = gdalDriver.Create ( imgFilePath, subXcount, subYcount, 1, OSGeo.GDAL.DataType.GDT_Float32, null ); subDs.SetProjection(inDS.GetProjectionRef()); //获取数据Transfrom double[] oriTransFrom = new double[6]; inDS.GetGeoTransform(oriTransFrom); oriTransFrom[0] = oriTransFrom[0] + offX * oriTransFrom[1] + offY * oriTransFrom[2]; oriTransFrom[3] = oriTransFrom[3] + offX * oriTransFrom[4] + offY * oriTransFrom[5]; subDs.SetGeoTransform(oriTransFrom); //////////// 把值写入子栅格 ///////////// subDs.GetRasterBand(1).WriteRaster ( 0, 0, subXcount, subYcount, oriValue, subXcount, subYcount, 0, 0 ); ///////////////// 返回子栅格路径 //////////////////// imgFilePaths.Add(imgFilePath); subDs.Dispose(); } } } else { imgFilePaths.Add(inPaht); } inDS.Dispose(); return(imgFilePaths); }
/// <summary> /// RGB转灰度显示。 /// </summary> /// <param name="InputImg">影像对象。</param> /// <param name="RGBWeight">RGB权重数组,长度为3。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool RGB2GrayScale(Img InputImg, double[] RGBWeight, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (OutPath == InputImg.Path) { throw new Exception("输出路径与源文件相同。"); } if (InputImg.GDALDataset == null) { throw new ArgumentNullException("输入数据集为空。"); } if (String.IsNullOrWhiteSpace(OutPath.Trim())) { throw new ArgumentNullException("输出路径为空或非法。"); } if (RGBWeight.Length != 3) { throw new ArgumentException("权重数组长度无效,应为3。"); } if (Math.Abs(RGBWeight[0] + RGBWeight[1] + RGBWeight[2] - 1) > 1E-7) { throw new ArgumentOutOfRangeException("RGB分量权重设置错误。总和应为1。"); } OSGeo.GDAL.Driver Dri = OSGeo.GDAL.Gdal.GetDriverByName("Gtiff"); if (Dri == null) { throw new Exception("无法获取GDAL Driver。"); } int xSize = InputImg.Width; int ySize = InputImg.Height; 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(InputImg.GDALDataset, DS); for (int Row = 0; Row < ySize; Row++) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] RValues = new double[xSize]; double[] GValues = new double[xSize]; double[] BValues = new double[xSize]; double[] GrayValues = new double[xSize]; InputImg.GDALDataset.GetRasterBand(InputImg.BandList[0]).ReadRaster(0, Row, xSize, 1, RValues, xSize, 1, 0, 0); InputImg.GDALDataset.GetRasterBand(InputImg.BandList[1]).ReadRaster(0, Row, xSize, 1, GValues, xSize, 1, 0, 0); InputImg.GDALDataset.GetRasterBand(InputImg.BandList[2]).ReadRaster(0, Row, xSize, 1, BValues, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) { //拉伸到0~255后再加权计算。 RValues[Col] = LinearStretch(RValues[Col], InputImg.Min[InputImg.BandList[0] - 1], InputImg.Max[InputImg.BandList[0] - 1]); GValues[Col] = LinearStretch(GValues[Col], InputImg.Min[InputImg.BandList[1] - 1], InputImg.Max[InputImg.BandList[1] - 1]); BValues[Col] = LinearStretch(BValues[Col], InputImg.Min[InputImg.BandList[2] - 1], InputImg.Max[InputImg.BandList[2] - 1]); GrayValues[Col] = RGBWeight[0] * RValues[Col] + RGBWeight[1] * GValues[Col] + RGBWeight[2] * BValues[Col]; } //写结果到新栅格 DS.GetRasterBand(1).WriteRaster(0, Row, xSize, 1, GrayValues, xSize, 1, 0, 0); DS.FlushCache(); } FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.Message); return(false); } }
/// <summary> /// Brovey变换融合。融合前会将多光谱数据集的每一波段与全色数据集做直方图匹配。 /// </summary> /// <param name="PanDS">全色数据集。</param> /// <param name="MSDS">多光谱数据集</param> /// <param name="PanCumu">全色数据集的累积概率表。</param> /// <param name="MSCumu">多光谱数据集的累积概率表。</param> /// <param name="MSBandList">多光谱数据集的波段组合。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool Brovey(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (PanDS == null) { throw new ArgumentNullException("输入的全色数据集为空。"); } if (PanDS.RasterCount > 1) { throw new RankException("全色数据集波段大于1。"); } if (MSDS == 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 panWidth = PanDS.RasterXSize; int panHeight = PanDS.RasterYSize; int msWidth = MSDS.RasterXSize; int msHeight = MSDS.RasterYSize; //int rat = (int)Math.Ceiling((double)panHeight / msHeight); if (panWidth < msWidth) { throw new RankException("全色数据集宽度小于多光谱数据集宽度。"); } if (panHeight < msHeight) { throw new RankException("全色数据集高度小于多光谱数据集高度。"); } //if (rat <= 0) // throw new ArgumentOutOfRangeException("全色高度:多光谱高度小于1。"); FrmProgress FP = new FrmProgress() { Text = "正在进行Brovey融合...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); #region 预处理 //创建临时文件,进行直方图匹配。 string HisMatFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset MatchingDS = Dri.CreateCopy(HisMatFileName, MSDS, 0, null, null, null); FP.Output("已创建直方图匹配临时文件\"" + HisMatFileName + "\""); for (int band = 1; band <= MSDS.RasterCount; band++) { FP.Output("正在进行直方图匹配(" + band.ToString() + "/" + MSDS.RasterCount.ToString() + ")..."); Band b = Tools.BaseProcess.HistogramMatching(MSDS.GetRasterBand(band), PanDS.GetRasterBand(1), MSCumu[band - 1], PanCumu[0], OutDataType); if (b == null) { throw new ArgumentNullException("直方图匹配返回波段为空。"); } for (int row = 0; row < b.YSize; row++) { double[] tmp = new double[b.XSize]; b.ReadRaster(0, row, b.XSize, 1, tmp, b.XSize, 1, 0, 0); MatchingDS.GetRasterBand(band).WriteRaster(0, row, MatchingDS.GetRasterBand(band).XSize, 1, tmp, MatchingDS.GetRasterBand(band).XSize, 1, 0, 0); MatchingDS.FlushCache(); Thread.Sleep(1); } } //创建临时文件,进行重采样。 double[] resamptmp; string ResampFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset ResampDS = Dri.Create(ResampFileName, panWidth, panHeight, 3, MSDS.GetRasterBand(1).DataType, null); FP.Output("已创建重采样临时文件\"" + ResampFileName + "\""); //Tools.Common.CopyMetadata(PanDS, tmpDS); //Gdal.ReprojectImage(MSDS, tmpDS, null, null, 0, 0, 0, null, null); //将直方图匹配后的图像重采样。 for (int i = 0; i < 3; i++) { FP.Output("正在对直方图匹配后影像进行重采样(" + (i + 1).ToString() + "/" + "3)..."); resamptmp = new double[panWidth * panHeight]; MatchingDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放直方图匹配图像资源。 MatchingDS.Dispose(); if (File.Exists(HisMatFileName)) { File.Delete(HisMatFileName); } FP.Output("已删除直方图匹配临时文件"); #endregion //创建输出数据集。 OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(PanDS, DS); double[] p; double[][] ms; double[] ds; for (int row = 0; row < panHeight; row++) { FP.SetProgress2("正在处理", row + 1, panHeight, "行"); //将全色波段行读取进数组。 p = new double[panWidth]; PanDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, p, panWidth, 1, 0, 0); //将重采样后的多光谱行读取进数组。 ms = new double[3][]; ms[0] = new double[panWidth]; ms[1] = new double[panWidth]; ms[2] = new double[panWidth]; ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, ms[0], panWidth, 1, 0, 0); ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, ms[1], panWidth, 1, 0, 0); ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, ms[2], panWidth, 1, 0, 0); //遍历三波段 for (int bandcount = 0; bandcount < 3; bandcount++) { FP.SetProgress1("正在处理", bandcount + 1, 3, "波段"); ds = new double[panWidth]; //临时数组 for (long i = 0; i < panWidth; i++) { ds[i] = p[i] * ms[bandcount][i] / (ms[0][i] + ms[1][i] + ms[2][i]); //Brovey公式 } DS.GetRasterBand(bandcount + 1).WriteRaster(0, row, panWidth, 1, ds, panWidth, 1, 0, 0); //计算完后的数据写入 DS.FlushCache(); } Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放重采样图像资源。 ResampDS.Dispose(); if (File.Exists(ResampFileName)) { File.Delete(ResampFileName); } FP.Output("已删除重采样临时文件"); /*一次性读取一时爽,遇到大文件爆内存。 * 一次性读取一时爽,遇到大文件爆内存。 * 一次性读取一时爽,遇到大文件爆内存。*/ //p = new double[panWidth * panHeight]; //ms = new double[3][]; //ms[0] = new double[panWidth * panHeight]; //ms[1] = new double[panWidth * panHeight]; //ms[2] = new double[panWidth * panHeight]; //PanDS.GetRasterBand(1).ReadRaster(0, 0, panWidth, panHeight, p, panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[0]).ReadRaster(0, 0, msWidth, msHeight, ms[0], panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[1]).ReadRaster(0, 0, msWidth, msHeight, ms[1], panWidth, panHeight, 0, 0); //MSDS.GetRasterBand(MSBandList[2]).ReadRaster(0, 0, msWidth, msHeight, ms[2], panWidth, panHeight, 0, 0); //for (int bandcount = 0; bandcount < 3; bandcount++) //{ // ds = new double[panWidth * panHeight]; // for (int row = 0; row < panHeight; row++) // { // for (int col = 0; col < panWidth; col++) // { // ds[row * panWidth + col] = p[row * panWidth + col] * ms[bandcount][row * panWidth + col] / (ms[0][row * panWidth + col] + ms[1][row * panWidth + col] + ms[2][row * panWidth + col]); // } // } // DS.GetRasterBand(bandcount + 1).WriteRaster(0, 0, panWidth, panHeight, ds, panWidth, panHeight, 0, 0); // DS.FlushCache(); //} FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }
/// <summary> /// IHS融合。融合前会将全色数据集与多光谱数据集转换到IHS空间下的I波段做直方图匹配。 /// </summary> /// <param name="PanDS">全色数据集。</param> /// <param name="MSDS">多光谱数据集</param> /// <param name="PanCumu">全色数据集的累积概率表。</param> /// <param name="MSCumu">多光谱数据集的累积概率表。</param> /// <param name="MSBandList">多光谱数据集的波段组合。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool IHSFusion(OSGeo.GDAL.Dataset PanDS, OSGeo.GDAL.Dataset MSDS, double[][] PanCumu, double[][] MSCumu, int[] MSBandList, OSGeo.GDAL.DataType OutDataType, string OutPath) { try { if (PanDS == null) { throw new ArgumentNullException("输入的全色数据集为空。"); } if (PanDS.RasterCount > 1) { throw new RankException("全色数据集波段大于1。"); } if (MSDS == 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 panWidth = PanDS.RasterXSize; int panHeight = PanDS.RasterYSize; int msWidth = MSDS.RasterXSize; int msHeight = MSDS.RasterYSize; if (panWidth < msWidth) { throw new RankException("全色数据集宽度小于多光谱数据集宽度。"); } if (panHeight < msHeight) { throw new RankException("全色数据集高度小于多光谱数据集高度。"); } FrmProgress FP = new FrmProgress() { Text = "正在进行IHS融合...", }; Thread t = new Thread(() => { FP.ShowDialog(); }); t.SetApartmentState(ApartmentState.STA); t.Start(); #region 预处理 //创建临时文件,进行重采样。 double[] resamptmp; string ResampFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset ResampDS = Dri.Create(ResampFileName, panWidth, panHeight, MSDS.RasterCount, MSDS.GetRasterBand(1).DataType, null); FP.Output("已创建重采样临时文件\"" + ResampFileName + "\""); //将多光谱影像重采样。 for (int i = 0; i < 3; i++) { FP.Output("正在进行重采样(" + (i + 1).ToString() + "/" + "3)..."); resamptmp = new double[panWidth * panHeight]; MSDS.GetRasterBand(MSBandList[i]).ReadRaster(0, 0, msWidth, msHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.GetRasterBand(i + 1).WriteRaster(0, 0, panWidth, panHeight, resamptmp, panWidth, panHeight, 0, 0); ResampDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } double[] BandMax = new double[3]; double[] BandMin = new double[3]; for (int i = 0; i < 3; i++) { FP.Output("正在计算重采样影像统计数据(" + (i + 1).ToString() + "/" + "3)..."); Common.ComputeRasterMinMax(ResampDS.GetRasterBand(i + 1), out BandMin[i], out BandMax[i]); } #endregion //多光谱RGB转IHS。 string MSIHSFileName = Tools.Common.GetTempFileName(); OSGeo.GDAL.Dataset MSIHSDS = Dri.Create(MSIHSFileName, panWidth, panHeight, 3, OSGeo.GDAL.DataType.GDT_Float32, null); FP.Output("已创建IHS临时文件\"" + MSIHSFileName + "\""); //按行读入,进行拉伸后再IHS转换,写入。 for (int row = 0; row < panHeight; row++) { FP.SetProgress1("正在处理IHS临时文件(", row + 1, panHeight, ")"); double[] iArr = new double[panWidth]; double[] hArr = new double[panWidth]; double[] sArr = new double[panWidth]; double[][] MSRGBArr = new double[3][]; MSRGBArr[0] = new double[panWidth]; MSRGBArr[1] = new double[panWidth]; MSRGBArr[2] = new double[panWidth]; //读。 ResampDS.GetRasterBand(1).ReadRaster(0, row, panWidth, 1, MSRGBArr[0], panWidth, 1, 0, 0); ResampDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, MSRGBArr[1], panWidth, 1, 0, 0); ResampDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, MSRGBArr[2], panWidth, 1, 0, 0); //按行逐像元转IHS。 for (long i = 0; i < panWidth; i++) { double[] tmp = Common.RGB2IHS( new double[3] { Common.LinearStretchDouble(MSRGBArr[0][i], BandMin[0], BandMax[0]), Common.LinearStretchDouble(MSRGBArr[1][i], BandMin[1], BandMax[1]), Common.LinearStretchDouble(MSRGBArr[2][i], BandMin[2], BandMax[2]) }); iArr[i] = tmp[0]; hArr[i] = tmp[1]; sArr[i] = tmp[2]; } //写。 MSIHSDS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, iArr, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, hArr, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, sArr, panWidth, 1, 0, 0); MSIHSDS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放重采样数据集资源。 ResampDS.Dispose(); if (File.Exists(ResampFileName)) { File.Delete(ResampFileName); } FP.Output("已删除重采样临时文件"); //全色匹配多光谱I FP.Output("正在计算IHS统计数据..."); Common.GetStatistics(MSIHSDS.GetRasterBand(1), out double Imin, out double Imax, out double Imean, out double Istddev); //多光谱统计信息。 int[] IHis = new int[(int)(Imax - Imin) + 1]; MSIHSDS.GetRasterBand(1).GetHistogram(Imin, Imax, (int)(Imax - Imin) + 1, IHis, 1, 0, null, null); double[] ICumu = new double[IHis.Length]; for (int i = 0; i < IHis.Length; i++) { ICumu[i] = (double)IHis[i] / (MSIHSDS.RasterXSize * MSIHSDS.RasterYSize); if (i > 0) { ICumu[i] += ICumu[i - 1]; //累积概率 } } FP.Output("正在进行I波段直方图匹配..."); Band PanMatIBand = Tools.BaseProcess.HistogramMatching(PanDS.GetRasterBand(1), MSIHSDS.GetRasterBand(1), PanCumu[0], ICumu, OSGeo.GDAL.DataType.GDT_Float32); if (PanMatIBand == null) { throw new ArgumentNullException("直方图匹配返回波段为空。"); } //全色融合。 //创建输出数据集。 OSGeo.GDAL.Dataset DS = Dri.Create(OutPath, panWidth, panHeight, 3, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(PanDS, DS); for (int row = 0; row < panHeight; row++) { FP.SetProgress1("正在融合(", row + 1, panHeight, ")"); //读取匹配多光谱I后的全色波段。 double[] Itmp = new double[panWidth]; PanMatIBand.ReadRaster(0, row, panWidth, 1, Itmp, panWidth, 1, 0, 0); //读入IHS变换后的多光谱影像的H、S波段。 double[] Htmp = new double[panWidth]; double[] Stmp = new double[panWidth]; MSIHSDS.GetRasterBand(2).ReadRaster(0, row, panWidth, 1, Htmp, panWidth, 1, 0, 0); MSIHSDS.GetRasterBand(3).ReadRaster(0, row, panWidth, 1, Stmp, panWidth, 1, 0, 0); double[] Rtmp = new double[panWidth]; double[] Gtmp = new double[panWidth]; double[] Btmp = new double[panWidth]; for (long i = 0; i < panWidth; i++) { double[] tmp = Common.IHS2RGB(new double[3] { Itmp[i], Htmp[i], Stmp[i] }); Rtmp[i] = tmp[0]; Gtmp[i] = tmp[1]; Btmp[i] = tmp[2]; } DS.GetRasterBand(1).WriteRaster(0, row, panWidth, 1, Rtmp, panWidth, 1, 0, 0); DS.GetRasterBand(2).WriteRaster(0, row, panWidth, 1, Gtmp, panWidth, 1, 0, 0); DS.GetRasterBand(3).WriteRaster(0, row, panWidth, 1, Btmp, panWidth, 1, 0, 0); DS.FlushCache(); Thread.Sleep(1); if (FP.Canceled) { Thread.Sleep(500); FP.Finish(); throw new OperationCanceledException("操作被用户取消。"); } } //释放IHS图像资源。 MSIHSDS.Dispose(); PanMatIBand.Dispose(); if (File.Exists(MSIHSFileName)) { File.Delete(MSIHSFileName); } FP.Output("已删除IHS临时文件"); FP.Finish(); Dri.Dispose(); DS.Dispose(); return(true); } catch (Exception err) { MessageBox.Show(err.ToString()); return(false); } }