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); }
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); }
/// <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); } }
/// <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> /// 导出当前视图。 /// </summary> /// <param name="InputImg">影像对象。</param> /// <param name="OutDataType">输出数据类型。</param> /// <param name="OutPath">输出路径。</param> /// <returns>返回操作成功或失败。</returns> public static bool ExportView(Img InputImg, 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("输出路径为空或非法。"); } 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; int Bandnum = 3; if (InputImg.IsGrayscale) { Bandnum = 1; } else { Bandnum = 3; } 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, Bandnum, OutDataType, null); FP.Output("已创建输出数据集\"" + OutPath + "\",数据类型为" + OutDataType.ToString() + "。"); Tools.Common.CopyMetadata(InputImg.GDALDataset, DS); for (int i = 0; i < Bandnum; i++) //遍历每个波段 { FP.SetProgress2("正在处理", i + 1, Bandnum, "波段"); for (int Row = 0; Row < ySize; Row++) //遍历每一行(y) { FP.SetProgress1("正在处理", Row + 1, ySize, "行"); double[] Values = new double[xSize]; //读取DN到数组 InputImg.GDALDataset.GetRasterBand(InputImg.BandList[i]).ReadRaster(0, Row, xSize, 1, Values, xSize, 1, 0, 0); for (int Col = 0; Col < xSize; Col++) //对每一个值进行计算 { //无拉伸不做处理直接导出 if (InputImg.StretchMode == 0) { break; } //已经有处理的情形 switch (InputImg.StretchMode) { case 1: case 2: case 3: case 4: case 9: { //线性 Values[Col] = LinearStretch(Values[Col], InputImg.StretchInfo[InputImg.BandList[i] - 1].Item1, InputImg.StretchInfo[InputImg.BandList[i] - 1].Item2); break; } case 5: { //直方图均衡 Values[Col] = EqualizationStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } case 6: { //高斯 Values[Col] = GaussianStretch(Values[Col], InputImg.CumulativeProbability[InputImg.BandList[i] - 1], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Mean[InputImg.BandList[i] - 1], InputImg.Stddev[InputImg.BandList[i] - 1]); break; } case 7: { //平方根 Values[Col] = SquarerootStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } case 8: { //对数 Values[Col] = LinearStretch(LogarithmicStretch(Values[Col], InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]), InputImg.Min[InputImg.BandList[i] - 1], InputImg.Max[InputImg.BandList[i] - 1]); break; } default: { //不是0-9还能是啥? throw new Exception("拉伸模式未知。"); } } } //写结果到新栅格 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.Message); return(false); } }
public bool TiffToKml(string inPut, string outPut, int band = 1) { FileInfo inPutFile = new FileInfo(inPut); bool isExtif = false; bool isExtiff = false; //입력 파일이 없다면 종료 if (!inPutFile.Exists) { return(false); } else { //입력 파일이 tif / tiff 파일이 아니라면 종료 if (inPutFile.Extension != ".tif" && inPutFile.Extension != ".tiff") { return(false); } if (inPutFile.Extension == ".tif") { isExtif = true; } if (inPutFile.Extension == ".tiff") { isExtiff = true; } } Gdal.AllRegister(); try { #region Get Coordinate double north = 36.16465526448886; //북 double south = 35.97362616042732; //남 double east = 127.5672085281825; //동 double west = 127.3435070025512; //서 Dataset dataset = Gdal.Open(inPut, Access.GA_ReadOnly); string t_srs_wkt = "GEOGCS[\"WGS84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.01745329251994328]]"; string s_srs_wkt = dataset.GetProjectionRef(); 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"); FileInfo outPutFile = new FileInfo(outPut); string testPath = string.Empty; if (isExtif) { testPath = string.Format("{0}\\test_Png_{1}", outPutFile.DirectoryName, inPutFile.Name.Replace(".tif", ".png")); } else if (isExtiff) { testPath = string.Format("{0}\\test_Png_{1}", outPutFile.DirectoryName, inPutFile.Name.Replace(".tiff", ".png")); } Dataset dstDs = srcDrv.CreateCopy(testPath, dswarp, 0, options, null, null); dstDs.FlushCache(); #endregion #region Create PNG string file_name = Path.GetFileNameWithoutExtension(inPutFile.Name) + "_kml.png"; string pngPath = string.Format("{0}\\{1}", outPutFile.DirectoryName, file_name); Band band1 = dstDs.GetRasterBand(band); //특정 벤드 가져오기 int startX = 0; int startY = 0; int width = band1.XSize; int height = band1.YSize; double[] geot = new double[6]; dstDs.GetGeoTransform(geot); double Xp = geot[0] + width * geot[1] + height * geot[2]; //우하단 double Yp = geot[3] + width * geot[4] + height * geot[5]; //우하단 north = geot[3]; //북 west = geot[0]; //서 south = Yp; //남 east = Xp; //동 int nBandSpace = Gdal.GetDataTypeSize(DataType.GDT_Byte) / 8; int nPixelSpace = nBandSpace * dataset.RasterCount; int nLineSpace = nPixelSpace * width; double[] buffer = new double[width * height]; CPLErr d = band1.ReadRaster(startX, startY, width, height, buffer, width, height, 0, 0); double[] minmax = new double[2]; band1.ComputeRasterMinMax(minmax, 0); Bitmap bitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double value = buffer[x + y * width]; if (!Double.IsNaN(value)) { if (value >= minmax[0] && value <= minmax[1] && value != 0) { double colorValue = (value - minmax[0]) * 255 / (minmax[1] - minmax[0]); Color newColor = Color.FromArgb(Convert.ToInt32(colorValue), Convert.ToInt32(colorValue), Convert.ToInt32(colorValue)); bitmap.SetPixel(x, y, newColor); } else { Color newColor = Color.FromArgb(0, 0, 0, 0); bitmap.SetPixel(x, y, newColor); } } } } bitmap.Save(pngPath, System.Drawing.Imaging.ImageFormat.Png); #endregion #region Create KML StreamWriter sw = new StreamWriter(outPut); sw.WriteLine("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); sw.WriteLine("<kml xmlns=\"http://www.opengis.net/kml/2.2\" xmlns:gx=\"http://www.google.com/kml/ext/2.2\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.opengis.net/kml/2.2 http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd http://www.google.com/kml/ext/2.2 http://code.google.com/apis/kml/schema/kml22gx.xsd\">"); sw.WriteLine("<Document id=\"radar\">"); sw.WriteLine("\t<name>" + inPutFile.Name + "</name>"); sw.WriteLine("\t<Snippet></Snippet>"); sw.WriteLine("\t<GroundOverlay id=\"0\">"); sw.WriteLine("\t\t<Snippet></Snippet>"); sw.WriteLine("\t\t<drawOrder>1000</drawOrder>"); sw.WriteLine("\t\t<name>" + inPutFile.Name + "</name>"); sw.WriteLine("\t\t<Icon>\r\t\t\t<href>" + file_name + "</href>\r\t\t\t<viewBoundScale>1.0</viewBoundScale>\r\t\t</Icon>"); sw.WriteLine("\t\t<LatLonBox>"); sw.WriteLine("\t\t\t<north>" + north.ToString() + "</north>"); //북 sw.WriteLine("\t\t\t<south>" + south.ToString() + "</south>"); //남 sw.WriteLine("\t\t\t<east>" + east.ToString() + "</east>"); //동 sw.WriteLine("\t\t\t<west>" + west.ToString() + "</west>"); //서 sw.WriteLine("\t\t\t<rotation>0</rotation>"); //회전 sw.WriteLine("\t\t</LatLonBox>"); sw.WriteLine("\t</GroundOverlay>"); sw.WriteLine("</Document>"); sw.WriteLine("</kml>"); sw.Flush(); sw.Close(); sw.Dispose(); #endregion dataset.Dispose(); bitmap.Dispose(); dstDs.Dispose(); srcDrv.Dispose(); dswarp.Dispose(); File.Delete(testPath); } catch (Exception e) { return(false); } return(true); }
public bool ChangeProjectionByUTM(string inPut, string outPut, int band = 1) { FileInfo inPutFile = new FileInfo(inPut); bool isExtif = false; bool isExtiff = false; //입력 파일이 없다면 종료 if (!inPutFile.Exists) { return(false); } else { //입력 파일이 tif / tiff 파일이 아니라면 종료 if (inPutFile.Extension != ".tif" && inPutFile.Extension != ".tiff") { return(false); } if (inPutFile.Extension == ".tif") { isExtif = true; } if (inPutFile.Extension == ".tiff") { isExtiff = true; } } Gdal.AllRegister(); try { #region Change projection string strWorldSinusoidal = "PROJCS[\"World_Sinusoidal\",GEOGCS[\"WGS 84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS 84\",6378137,298.257223563,AUTHORITY[\"EPSG\",\"7030\"]],AUTHORITY[\"EPSG\",\"6326\"]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.0174532925199433],AUTHORITY[\"EPSG\",\"4326\"]],PROJECTION[\"Sinusoidal\"],PARAMETER[\"longitude_of_center\",0],PARAMETER[\"false_easting\",0],PARAMETER[\"false_northing\",0],UNIT[\"metre\",1,AUTHORITY[\"EPSG\",\"9001\"]]]"; string t_srs_wkt = "GEOGCS[\"WGS84\",DATUM[\"WGS_1984\",SPHEROID[\"WGS84\",6378137,298.257223563]],PRIMEM[\"Greenwich\",0],UNIT[\"degree\",0.01745329251994328]]"; Dataset dataset = Gdal.Open(inPut, Access.GA_ReadOnly); dataset.SetProjection(strWorldSinusoidal); string s_srs_wkt = dataset.GetProjectionRef(); Dataset dswarp = Gdal.AutoCreateWarpedVRT(dataset, s_srs_wkt, t_srs_wkt, ResampleAlg.GRA_NearestNeighbour, 0); string[] options = null; OSGeo.GDAL.Driver srcDrv = Gdal.GetDriverByName("GTiff"); FileInfo outPutFile = new FileInfo(outPut); string testPath = string.Empty; if (isExtif) { testPath = string.Format("{0}\\test_Png_{1}", outPutFile.DirectoryName, inPutFile.Name.Replace(".tif", ".png")); } else if (isExtiff) { testPath = string.Format("{0}\\test_Png_{1}", outPutFile.DirectoryName, inPutFile.Name.Replace(".tiff", ".png")); } Dataset dstDs = srcDrv.CreateCopy(testPath, dswarp, 0, options, null, null); #endregion #region Create PNG string file_name = Path.GetFileNameWithoutExtension(inPutFile.Name) + ".png"; //string pngPath = string.Format("{0}\\{1}", outPutFile.DirectoryName, file_name); _strPngFile = string.Format("{0}\\{1}", outPutFile.DirectoryName, file_name); Band band1 = dstDs.GetRasterBand(band); //특정 벤드 가져오기 int startX = 0; int startY = 0; int width = band1.XSize; int height = band1.YSize; int nBandSpace = Gdal.GetDataTypeSize(DataType.GDT_Byte) / 8; int nPixelSpace = nBandSpace * dataset.RasterCount; int nLineSpace = nPixelSpace * width; double[] buffer = new double[width * height]; CPLErr d = band1.ReadRaster(startX, startY, width, height, buffer, width, height, 0, 0); double[] minmax = new double[2]; band1.ComputeRasterMinMax(minmax, 0); Bitmap bitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double value = buffer[x + y * width]; if (!Double.IsNaN(value)) { if (value >= minmax[0] && value <= minmax[1] && value != 0) { double colorValue = (value - minmax[0]) * 255 / (minmax[1] - minmax[0]); Color newColor = Color.FromArgb(Convert.ToInt32(colorValue), Convert.ToInt32(colorValue), Convert.ToInt32(colorValue)); bitmap.SetPixel(x, y, newColor); } else { Color newColor = Color.FromArgb(0, 0, 0, 0); bitmap.SetPixel(x, y, newColor); } } } } bitmap.Save(_strPngFile, System.Drawing.Imaging.ImageFormat.Png); #endregion #region Create a GeoTiff double north = 36.16465526448886; //북 double south = 35.97362616042732; //남 double east = 127.5672085281825; //동 double west = 127.3435070025512; //서 CheckGeoTransform(ref north, ref south, ref east, ref west, inPutFile); double[] newGeot = CalcGeoTransform(dstDs, north, south, east, west); OSGeo.GDAL.Driver driver = Gdal.GetDriverByName("GTiff"); Dataset oldDataSet = Gdal.Open(_strPngFile, Access.GA_ReadOnly); Dataset newDataSet = srcDrv.CreateCopy(outPut, oldDataSet, 0, null, null, null); newDataSet.SetProjection(dswarp.GetProjectionRef()); newDataSet.SetGeoTransform(newGeot); #endregion oldDataSet.Dispose(); newDataSet.Dispose(); driver.Dispose(); dataset.Dispose(); bitmap.Dispose(); dstDs.Dispose(); srcDrv.Dispose(); dswarp.Dispose(); File.Delete(testPath); //File.Delete(pngPath); } catch (Exception e) { return(false); } return(true); }
public bool ImgToGeoTiff(string inPut, string outPut, int band = 1) { FileInfo inPutFile = new FileInfo(inPut); //입력 파일이 없다면 종료 if (!inPutFile.Exists) { return(false); } else { //입력 파일이 img 파일이 아니라면 종료 if (inPutFile.Extension != ".img") { return(false); } } try { #region Create Tiff Gdal.AllRegister(); Dataset dataset = Gdal.Open(inPut, Access.GA_ReadOnly); Band band1 = dataset.GetRasterBand(band); //특정 벤드 가져오기 int width = band1.XSize; int height = band1.YSize; int startX = 0; int startY = 0; int nBandSpace = Gdal.GetDataTypeSize(DataType.GDT_Byte) / 8; int nPixelSpace = nBandSpace * dataset.RasterCount; int nLineSpace = nPixelSpace * width; double[] buffer = new double[width * height]; CPLErr d = band1.ReadRaster(startX, startY, width, height, buffer, width, height, 0, 0); double[] minmax = new double[2]; band1.ComputeRasterMinMax(minmax, 0); #region 복사할 이미지 생성 Bitmap bitmap = new Bitmap(width, height); for (int x = 0; x < width; x++) { for (int y = 0; y < height; y++) { double value = buffer[x + y * width]; if (!Double.IsNaN(value)) { if (value >= minmax[0] && value <= minmax[1] && value != 0) { double colorValue = (value - minmax[0]) * 255 / (minmax[1] - minmax[0]); Color newColor = Color.FromArgb(Convert.ToInt32(colorValue), Convert.ToInt32(colorValue), Convert.ToInt32(colorValue)); bitmap.SetPixel(x, y, newColor); } else { Color newColor = Color.FromArgb(0, 0, 0, 0); bitmap.SetPixel(x, y, newColor); } } } } FileInfo outPutFile = new FileInfo(outPut); string pngPath = string.Format("{0}\\{1}", outPutFile.DirectoryName, inPutFile.Name.Replace(".img", ".png")); bitmap.Save(pngPath, System.Drawing.Imaging.ImageFormat.Png); #endregion string[] options = null; OSGeo.GDAL.Driver srcDrv = Gdal.GetDriverByName("GTiff"); Dataset srcDs = Gdal.Open(pngPath, Access.GA_ReadOnly); Dataset dstDs = srcDrv.CreateCopy(outPut, srcDs, 0, options, null, null); dstDs.SetProjection(dataset.GetProjection()); double[] geot = new double[6]; dataset.GetGeoTransform(geot); dstDs.SetGeoTransform(geot); dstDs.FlushCache(); dstDs.Dispose(); srcDs.Dispose(); srcDrv.Dispose(); bitmap.Dispose(); File.Delete(pngPath); #endregion } catch (Exception e) { return(false); } return(true); }