private void ReadHeader() { try { _dataset = Gdal.Open(Filename, Access.GA_Update); } catch { try { _dataset = Gdal.Open(Filename, Access.GA_ReadOnly); } catch (Exception ex) { throw new GdalException(ex.ToString()); } } Init(_dataset.RasterXSize, _dataset.RasterYSize); NumBands = _dataset.RasterCount; WorldFile = new WorldFile { Affine = new double[6] }; double[] test = new double[6]; _dataset.GetGeoTransform(test); Bounds = new RasterBounds(Height, Width, test); WorldFile.Affine = test; DoClose(); }
private static void GDALInfoGetPosition(Dataset ds, double x, double y, out double dfGeoX, out double dfGeoY) { double[] adfGeoTransform = new double[6]; ds.GetGeoTransform(adfGeoTransform); dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y; dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y; }
private void ReadHeader() { _dataset = Helpers.Open(Filename); Init(_dataset.RasterXSize, _dataset.RasterYSize); NumBands = _dataset.RasterCount; WorldFile = new WorldFile { Affine = new double[6] }; double[] test = new double[6]; _dataset.GetGeoTransform(test); Bounds = new RasterBounds(Height, Width, test); WorldFile.Affine = test; Close(); }
/// <summary> /// 拷贝元数据至新的数据集。 /// </summary> /// <param name="InputDS">输入的数据集。</param> /// <param name="TargetDS">要将元数据拷贝到的数据集。</param> public static void CopyMetadata(OSGeo.GDAL.Dataset InputDS, OSGeo.GDAL.Dataset TargetDS) { if (InputDS == null || TargetDS == null) { throw new ArgumentNullException("数据集不能为空。"); } //写入投影和变换信息 double[] TransformArgs = new double[6]; InputDS.GetGeoTransform(TransformArgs); TargetDS.SetGeoTransform(TransformArgs); TargetDS.SetProjection(InputDS.GetProjection()); //DS.SetMetadata(InputDS.GetMetadata()); }
public GDALTerrainTileService(OSGeo.GDAL.Dataset dataset, string datasetName, double lztsd, int nlevels, string tiledir) : base(null, datasetName, lztsd, 256, ".bil", nlevels, tiledir, new TimeSpan(), "") { m_dataset = dataset; m_lines = dataset.RasterYSize; m_pixels = dataset.RasterXSize; dataset.GetGeoTransform(m_transform); if (dataset.GetRasterBand(1).DataType == (DataType)OSGeo.GDAL.GdalConst.GDT_Int16) { this.m_dataType = "Int16"; } else if (dataset.GetRasterBand(1).DataType == (DataType)OSGeo.GDAL.GdalConst.GDT_Float32) { this.m_dataType = "Float32"; } }
///// <summary> ///// 根据栅格图层名字返回栅格图层数据数组 ///// </summary> ///// <param name="layerName">图层名字</param> ///// <param name="width">ref类型,数据的宽度</param> ///// <param name="height">ref类型,数据的高度</param> ///// <returns>数据数组,按行优先</returns> //private double[] GetData(string layerName, ref int width, ref int height) //{ // var map = GIS.FrameWork.Application.App.Map; // var layers = map.Layers; // ILayer selectedLayer = null; // for (int i = 0; i < layers.Count; i++) // { // var layer = layers[i]; // if (layer.LegendText == layerName) // { // selectedLayer = layer; // break; // } // } // if (selectedLayer == null) // { // return null; // 图层名无效 // } // try // { // RasterLayer rasterLayer = selectedLayer as RasterLayer; // IRaster rasterDataSet = rasterLayer.DataSet; // Dataset dataset = GIS.GDAL.RasterConverter.Ds2GdalRaster(rasterDataSet, null, new int[] { 1 }); // width = dataset.RasterXSize; // height = dataset.RasterYSize; // double[] imageBuffer = new double[width * height]; // Band band = dataset.GetRasterBand(1); // band.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); // return imageBuffer; // } // catch // { // return null; // 图层不是栅格图层或将图层转化为GDAL dataset失败或从GDAL dataset中读取数据失败 // } //} /// <summary> /// 和GetData功能相同,但是使用GDAL直接从文件中读取数据。 /// 获取空间参照信息 /// </summary> /// <param name="fileName">文件名字</param> /// <param name="width">ref用于返回数据的宽度</param> /// <param name="height">ref用于返回数据的高度</param> /// <returns>一维数据数组,按行优先</returns> protected double[] GdalGetData(string fileName, ref int width, ref int height) { OSGeo.GDAL.Dataset dataset = OSGeo.GDAL.Gdal.Open(fileName, OSGeo.GDAL.Access.GA_ReadOnly); width = dataset.RasterXSize; height = dataset.RasterYSize; this.geoTransform = new double[6]; dataset.GetGeoTransform(geoTransform); this.projStr = dataset.GetProjection(); this.tiffType = dataset.GetType(); double[] imageBuffer = new double[width * height]; OSGeo.GDAL.Band b = dataset.GetRasterBand(1); b.ReadRaster(0, 0, width, height, imageBuffer, width, height, 0, 0); double noDataVal; int hasVal; b.GetNoDataValue(out noDataVal, out hasVal); this.noDataVal = noDataVal; return(imageBuffer); }
private void GetNonRotatedPreview(Dataset dataset, Size size, Graphics g, Envelope bbox, ProjectionInfo mapProjection) #endif { double[] geoTrans = new double[6]; dataset.GetGeoTransform(geoTrans); // default transform if (!_useRotation && !HaveSpot || (geoTrans[0] == 0 && geoTrans[3] == 0)) geoTrans = new[] { 999.5, 1, 0, 1000.5, 0, -1 }; Bitmap bitmap = null; var geoTransform = new GeoTransform(geoTrans); int DsWidth = 0; int DsHeight = 0; BitmapData bitmapData = null; double[] intVal = new double[Bands]; int p_indx; double bitScalar = 1.0; double dblImginMapW = 0, dblImginMapH = 0, dblLocX = 0, dblLocY = 0; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((bbox.MinX > _envelope.MaxX) || (bbox.MaxX < _envelope.MinX) || (bbox.MaxY < _envelope.MinY) || (bbox.MinY > _envelope.MaxY)) return; DsWidth = _imageSize.Width; DsHeight = _imageSize.Height; Histogram = new List<int[]>(); for (int i = 0; i < Bands + 1; i++) Histogram.Add(new int[256]); double left = Math.Max(bbox.MinX, _envelope.MinX); double top = Math.Min(bbox.MaxY, _envelope.MaxY); double right = Math.Min(bbox.MaxX, _envelope.MaxX); double bottom = Math.Max(bbox.MinY, _envelope.MinY); double x1 = Math.Abs(geoTransform.PixelX(left)); double y1 = Math.Abs(geoTransform.PixelY(top)); double imgPixWidth = geoTransform.PixelXwidth(right - left); double imgPixHeight = geoTransform.PixelYwidth(bottom - top); //get screen pixels image should fill double dblBBoxW = bbox.Width; double dblBBoxtoImgPixX = imgPixWidth / dblBBoxW; dblImginMapW = size.Width * dblBBoxtoImgPixX * geoTransform.HorizontalPixelResolution; double dblBBoxH = bbox.Height; double dblBBoxtoImgPixY = imgPixHeight / dblBBoxH; dblImginMapH = size.Height * dblBBoxtoImgPixY * -geoTransform.VerticalPixelResolution; if ((dblImginMapH == 0) || (dblImginMapW == 0)) return; // ratios of bounding box to image ground space double dblBBoxtoImgX = size.Width / dblBBoxW; double dblBBoxtoImgY = size.Height / dblBBoxH; // set where to display bitmap in Map if (bbox.MinX != left) { if (bbox.MaxX != right) dblLocX = (_envelope.MinX - bbox.MinX) * dblBBoxtoImgX; else dblLocX = size.Width - dblImginMapW; } if (bbox.MaxY != top) { if (bbox.MinY != bottom) dblLocY = (bbox.MaxY - _envelope.MaxY) * dblBBoxtoImgY; else dblLocY = size.Height - dblImginMapH; } bitScalar = GetBitScalar(); try { bitmap = new Bitmap((int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), PixelFormat.Format24bppRgb); bitmapData = bitmap.LockBits( new Rectangle(0, 0, (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH)), ImageLockMode.ReadWrite, bitmap.PixelFormat); byte cr = _noDataInitColor.R; byte cg = _noDataInitColor.G; byte cb = _noDataInitColor.B; // Double[] noDataValues = new Double[Bands]; Double[] scales = new Double[Bands]; ColorTable colorTable = null; unsafe { double[][] buffer = new double[Bands][]; Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // get data from image for (int i = 0; i < Bands; i++) { buffer[i] = new double[(int)Math.Round(dblImginMapW) * (int)Math.Round(dblImginMapH)]; band[i] = dataset.GetRasterBand(i + 1); //get nodata value if present Int32 hasVal = 0; band[i].GetNoDataValue(out noDataValues[i], out hasVal); if (hasVal == 0) noDataValues[i] = Double.NaN; band[i].GetScale(out scales[i], out hasVal); if (hasVal == 0) scales[i] = 1.0; band[i].ReadRaster((int)Math.Round(x1), (int)Math.Round(y1), (int)Math.Round(imgPixWidth), (int)Math.Round(imgPixHeight), buffer[i], (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), 0, 0); switch (band[i].GetRasterColorInterpretation()) { case ColorInterp.GCI_BlueBand: ch[i] = 0; break; case ColorInterp.GCI_GreenBand: ch[i] = 1; break; case ColorInterp.GCI_RedBand: ch[i] = 2; break; case ColorInterp.GCI_Undefined: if (Bands > 1) ch[i] = 3; // infrared else { ch[i] = 4; if (_colorBlend == null) { Double dblMin, dblMax; band[i].GetMinimum(out dblMin, out hasVal); if (hasVal == 0) dblMin = Double.NaN; band[i].GetMaximum(out dblMax, out hasVal); if (hasVal == 0) dblMax = double.NaN; if (Double.IsNaN(dblMin) || Double.IsNaN(dblMax)) { double dblMean, dblStdDev; band[i].GetStatistics(0, 1, out dblMin, out dblMax, out dblMean, out dblStdDev); //double dblRange = dblMax - dblMin; //dblMin -= 0.1*dblRange; //dblMax += 0.1*dblRange; } Single[] minmax = new float[] { Convert.ToSingle(dblMin), 0.5f * Convert.ToSingle(dblMin + dblMax), Convert.ToSingle(dblMax) }; Color[] colors = new Color[] { Color.Blue, Color.Yellow, Color.Red }; _colorBlend = new ColorBlend(colors, minmax); } intVal = new Double[3]; } break; case ColorInterp.GCI_GrayIndex: ch[i] = 0; break; case ColorInterp.GCI_PaletteIndex: colorTable = band[i].GetRasterColorTable(); ch[i] = 5; intVal = new Double[3]; break; default: ch[i] = -1; break; } } if (BitDepth == 32) ch = new[] { 0, 1, 2 }; p_indx = 0; for (int y = 0; y < Math.Round(dblImginMapH); y++) { byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < Math.Round(dblImginMapW); x++, p_indx++) { for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][p_indx]/bitScalar; Double imageVal = intVal[i] = intVal[i]/bitScalar; if (ch[i] == 4) { if (imageVal != noDataValues[i]) { Color color = _colorBlend.GetColor(Convert.ToSingle(imageVal)); intVal[0] = color.B; intVal[1] = color.G; intVal[2] = color.R; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else if (ch[i] == 5 && colorTable != null) { if (imageVal != noDataValues[i]) { ColorEntry ce = colorTable.GetColorEntry(Convert.ToInt32(imageVal)); intVal[0] = ce.c3; intVal[1] = ce.c2; intVal[2] = ce.c1; //intVal[3] = ce.c4; } else { intVal[0] = cb; intVal[1] = cg; intVal[2] = cr; } } else { if (ColorCorrect) { intVal[i] = ApplyColorCorrection(intVal[i], 0, ch[i], 0, 0); if (Bands >= 3) Histogram[Bands][ (int) (intVal[2]*0.2126 + intVal[1]*0.7152 + intVal[0]*0.0722)]++; } } if (intVal[i] > 255) intVal[i] = 255; } WritePixel(x, intVal, iPixelSize, ch, row); } } } } catch { return; } finally { if (bitmapData != null) bitmap.UnlockBits(bitmapData); } } if (TransparentColor != Color.Empty) bitmap.MakeTransparent(TransparentColor); g.DrawImage(bitmap, new Point((int)Math.Round(dblLocX), (int)Math.Round(dblLocY))); }
/// <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); }
private static string GDALInfoGetPosition(Dataset ds, double x, double y) { double[] adfGeoTransform = new double[6]; double dfGeoX, dfGeoY; ds.GetGeoTransform(adfGeoTransform); dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y; dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y; return dfGeoX.ToString() + ", " + dfGeoY.ToString(); }
// faster than rotated display private void GetNonRotatedPreview(Dataset dataset, Size size, Graphics g, BoundingBox bbox, ICoordinateSystem mapProjection) { double[] geoTrans = new double[6]; dataset.GetGeoTransform(geoTrans); // default transform if (!_useRotation && !_haveSpot || (geoTrans[0] == 0 && geoTrans[3] == 0)) geoTrans = new double[] { 999.5, 1, 0, 1000.5, 0, -1 }; Bitmap bitmap = null; GT = new GeoTransform(geoTrans); int DsWidth = 0; int DsHeight = 0; BitmapData bitmapData = null; double[] intVal = new double[Bands]; int p_indx; double bitScalar = 1.0; double dblImginMapW = 0, dblImginMapH = 0, dblLocX = 0, dblLocY = 0; int iPixelSize = 3; //Format24bppRgb = byte[b,g,r] if (dataset != null) { //check if image is in bounding box if ((bbox.Left > _Envelope.Right) || (bbox.Right < _Envelope.Left) || (bbox.Top < _Envelope.Bottom) || (bbox.Bottom > _Envelope.Top)) return; DsWidth = _imagesize.Width; DsHeight = _imagesize.Height; _histogram = new List<int[]>(); for (int i = 0; i < _lbands + 1; i++) _histogram.Add(new int[256]); double left = Math.Max(bbox.Left, _Envelope.Left); double top = Math.Min(bbox.Top, _Envelope.Top); double right = Math.Min(bbox.Right, _Envelope.Right); double bottom = Math.Max(bbox.Bottom, _Envelope.Bottom); double x1 = Math.Abs(GT.PixelX(left)); double y1 = Math.Abs(GT.PixelY(top)); double imgPixWidth = GT.PixelXwidth(right - left); double imgPixHeight = GT.PixelYwidth(bottom - top); //get screen pixels image should fill double dblBBoxW = bbox.Right - bbox.Left; double dblBBoxtoImgPixX = (double)imgPixWidth / (double)dblBBoxW; dblImginMapW = (double)size.Width * dblBBoxtoImgPixX * GT.HorizontalPixelResolution; double dblBBoxH = bbox.Top - bbox.Bottom; double dblBBoxtoImgPixY = (double)imgPixHeight / (double)dblBBoxH; dblImginMapH = (double)size.Height * dblBBoxtoImgPixY * -GT.VerticalPixelResolution; if ((dblImginMapH == 0) || (dblImginMapW == 0)) return; // ratios of bounding box to image ground space double dblBBoxtoImgX = (double)size.Width / dblBBoxW; double dblBBoxtoImgY = (double)size.Height / dblBBoxH; // set where to display bitmap in Map if (bbox.Left != left) { if (bbox.Right != right) dblLocX = (_Envelope.Left - bbox.Left) * dblBBoxtoImgX; else dblLocX = (double)size.Width - dblImginMapW; } if (bbox.Top != top) { if (bbox.Bottom != bottom) dblLocY = (bbox.Top - _Envelope.Top) * dblBBoxtoImgY; else dblLocY = (double)size.Height - dblImginMapH; } // scale if (_bitDepth == 12) bitScalar = 16.0; else if (_bitDepth == 16) bitScalar = 256.0; else if (_bitDepth == 32) bitScalar = 16777216.0; try { bitmap = new Bitmap((int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), PixelFormat.Format24bppRgb); bitmapData = bitmap.LockBits(new Rectangle(0, 0, (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH)), ImageLockMode.ReadWrite, bitmap.PixelFormat); unsafe { double[][] buffer = new double[Bands][]; Band[] band = new Band[Bands]; int[] ch = new int[Bands]; // get data from image for (int i = 0; i < Bands; i++) { buffer[i] = new double[(int)Math.Round(dblImginMapW) * (int)Math.Round(dblImginMapH)]; band[i] = dataset.GetRasterBand(i + 1); band[i].ReadRaster((int)Math.Round(x1), (int)Math.Round(y1), (int)Math.Round(imgPixWidth), (int)Math.Round(imgPixHeight), buffer[i], (int)Math.Round(dblImginMapW), (int)Math.Round(dblImginMapH), 0, 0); if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_BlueBand) ch[i] = 0; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GreenBand) ch[i] = 1; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_RedBand) ch[i] = 2; else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_Undefined) ch[i] = 3; // infrared else if (band[i].GetRasterColorInterpretation() == ColorInterp.GCI_GrayIndex) ch[i] = 4; else ch[i] = -1; } if (_bitDepth == 32) ch = new int[] { 0, 1, 2 }; p_indx = 0; for (int y = 0; y < Math.Round(dblImginMapH); y++) { byte* row = (byte*)bitmapData.Scan0 + (y * bitmapData.Stride); for (int x = 0; x < Math.Round(dblImginMapW); x++, p_indx++) { for (int i = 0; i < Bands; i++) { intVal[i] = buffer[i][p_indx] / bitScalar; if (_colorCorrect) { intVal[i] = ApplyColorCorrection(intVal[i], 0, ch[i], 0, 0); if (_lbands >= 3) _histogram[_lbands][(int)(intVal[2] * 0.2126 + intVal[1] * 0.7152 + intVal[0] * 0.0722)]++; } if (intVal[i] > 255) intVal[i] = 255; } WritePixel(x, intVal, iPixelSize, ch, row); } } } } catch { return; } finally { if (bitmapData != null) bitmap.UnlockBits(bitmapData); } } if (_transparentColor != Color.Empty) bitmap.MakeTransparent(_transparentColor); g.DrawImage(bitmap, new System.Drawing.Point((int)Math.Round(dblLocX), (int)Math.Round(dblLocY))); }
private static double[] GDALInfoGetPositionDouble(Dataset ds, double x, double y) { double[] adfGeoTransform = new double[6]; double dfGeoX, dfGeoY; ds.GetGeoTransform(adfGeoTransform); dfGeoX = adfGeoTransform[0] + adfGeoTransform[1] * x + adfGeoTransform[2] * y; dfGeoY = adfGeoTransform[3] + adfGeoTransform[4] * x + adfGeoTransform[5] * y; return new double[] { dfGeoX, dfGeoY }; }