ArcEngine和GDAL读写栅格数据机制对比(二)—— IPixelBlock读写栅格
1.ArcEngine和GDAL读写栅格数据机制对比(一)2.[GDAL]1.GDAL1.8.1编译与第一个程序3.C#+GDAL读取影像(1)4.[GDAL]4.影像的读取和显示5.[GDAL]3.影像金字塔构建6.[GDAL]2.读取栅格和矢量数据7.[GDAL]读取HDF格式的calipso数据8.[GDAL]写入shp
9.ArcEngine和GDAL读写栅格数据机制对比(二)—— IPixelBlock读写栅格
10.[GDAL]GEOS和Proj4编译11.[GDAL]在三维场景中显示DEM12.[转载]C#下使用GDAL将dem转换为灰度图13.[GDAL]编译64位GDAL1.1014.C#+GDAL读写文件以下是设定一个矩形框,用IPixelBlock将256*256瓦片tile拼接成一个整块影像的代码,row1, col1, row2, col2是一个矩形框行列号范围。level是瓦片的金字塔等级。这里的瓦片已经下载完毕,位于domSavePath文件夹下。
1 //选择的Google瓦块的行列号范围
2 int row1, col1, row2, col2;
3 int nTileSize = 256;
4 row1 = topLeft.Row;
5 col1 = topLeft.Col;
6 row2 = bottomRight.Row;
7 col2 = bottomRight.Col;
8 //拼接影像大小
9 int nImgSizeX = (col2 - col1 + 1) * nTileSize;
10 int nImgSizeY = (row2 - row1 + 1) * nTileSize;
11
12 double leftlon = (((col1 * 20037508.343) * 2.0) / (Math.Pow(2.0, (double)level - 1.0))) - 20037508.343;
13 double toplat = 20037508.343 - (((row1 * 20037508.343) * 2.0) / (Math.Pow(2.0, (double)level - 1.0)));
14 double pixel = 40075016.686 / (nTileSize * Math.Pow(2.0, (double)level - 1.0));
15 //拼接图像的左上角点,WebMecator投影
16 IPoint origin = new PointClass();
17 origin.PutCoords(leftlon, toplat);
18 //创建拼接图像
19 IRasterDataset mergeRasterDs = CreateRasterDataset(domSavePath, "Full.tif", origin, nImgSizeX, nImgSizeY, pixel, pixel, 3);
20
21 for (int ii = row1; ii <= row2; ii++)
22 {
23 for (int jj = col1; jj <= col2; jj++)
24 {
25 //瓦片的名称
26 string tileName = ii.ToString().PadLeft(8, '0') + "_" + jj.ToString().PadLeft(8, '0') + "." + _fileEndExtent;
27 string FilePath = domSavePath + @"\" + tileName;
28 if (!File.Exists(FilePath))
29 {
30 continue;
31 }
32 //读取瓦片数据集
33 IRasterDataset tileRasterDs = OpenFileRasterDataset(domSavePath, tileName);
34 IRasterDataset2 tileRasterDs2 = tileRasterDs as IRasterDataset2;
35 IRaster tileRaster = tileRasterDs2.CreateFullRaster();
36 //设置瓦片像素快大小
37 IPnt tileBlockSize = new PntClass();
38 tileBlockSize.SetCoords(256, 256);
39 IPixelBlock3 readPixelblock = tileRaster.CreatePixelBlock(tileBlockSize) as IPixelBlock3;
40 //瓦块的左上角点
41 IPnt tileTopleftCorner = new PntClass();
42 tileTopleftCorner.SetCoords(0, 0);
43 tileRaster.Read(tileTopleftCorner, readPixelblock as IPixelBlock);
44
45 //If you need to set NoData for some of the pixels, you need to set it on band
46 //to get the raster band.
47 //IRasterBandCollection rasterBands = (IRasterBandCollection)rasterDataset;
48 //IRasterBand rasterBand;
49 //IRasterProps rasterProps;
50 //rasterBand = rasterBands.Item(0);
51 //rasterProps = (IRasterProps)rasterBand;
52 //Set NoData if necessary. For a multiband image, a NoData value needs to be set for each band.
53 //rasterProps.NoDataValue = 255;
54
55 //从数据集中读取IRaster
56 IRasterDataset2 mergeRasterDs2 = mergeRasterDs as IRasterDataset2;
57 IRaster mergeRaster = mergeRasterDs2.CreateFullRaster();
58
59 //Create a pixel block using the weight and height of the raster dataset.
60 //If the raster dataset is large, a smaller pixel block should be used.
61 //Refer to the topic "How to access pixel data using a raster cursor".
62 IPnt blocksize2 = new PntClass();
63 blocksize2.SetCoords(256, 256);
64 IPixelBlock3 writePixelblock = mergeRaster.CreatePixelBlock(tileBlockSize) as IPixelBlock3;
65
66 System.Array pixelsTarget;
67 System.Array pixelsOrigin;//瓦块的像素坐标
68 for (int iplane = 0; iplane < 3; iplane++)
69 {
70 pixelsOrigin = (System.Array)readPixelblock.get_PixelData(iplane);
71 pixelsTarget = (System.Array)writePixelblock.get_PixelData(iplane);
72 for (int i = 0; i < 256; i++)
73 {
74 for (int j = 0; j < 256; j++)
75 {
76 object obj = pixelsOrigin.GetValue(i, j);
77 pixelsTarget.SetValue(obj, i, j);
78 }
79 }
80 writePixelblock.set_PixelData(iplane, (System.Array)pixelsOrigin);
81 }
82 //瓦块偏移左上角的像素值
83 int nOffsetX = (jj - col1) * nTileSize;
84 int nOffsetY = (ii - row1) * nTileSize;
85 //定义pixel block左上角点坐标,执行写入.
86 IPnt upperLeft = new PntClass();
87 upperLeft.SetCoords(nOffsetX, nOffsetY);
88
89 //写入拼接影像中
90 IRasterEdit mergeRasterEdit = (IRasterEdit)mergeRaster;
91 mergeRasterEdit.Write(upperLeft, (IPixelBlock)writePixelblock);
92
93 //释放mergeRasterEdit引用.
94 System.Runtime.InteropServices.Marshal.ReleaseComObject(mergeRasterEdit);
95 }
96 }
调用的CreateRasterDataset方法的代码如下:(这里注意:上面调用的时候出现了一个错误,Origin是左下角点坐标)

1 public static IRasterDataset CreateRasterDataset(string path, string fileName, IPoint origin, int width, int height, double xCell, double yCell, int NumBand)
2 {
3 try
4 {
5 IRasterWorkspace2 rasterWs = OpenRasterWorkspace(path);
6 //定义空间参考
7 string prj = "PROJCS[\"Popular Visualisation CRS / Mercator\",GEOGCS[\"Popular Visualisation CRS\",DATUM[\"Popular_Visualisation_Datum\",SPHEROID[\"Popular_Visualisation_Sphere\",6378137.0,0.0]],PRIMEM[\"Greenwich\",0.0],UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator_1SP\"],PARAMETER[\"false_easting\",0.0],PARAMETER[\"false_northing\",0.0],PARAMETER[\"central_meridian\",0.0],PARAMETER[\"scale_factor\",1.0],UNIT[\"Meter\",1.0]]";
8
9 ISpatialReference sr = CreateWebMector();
10 if (sr == null)
11 {
12 sr = new UnknownCoordinateSystemClass();
13 }
14 IRasterDataset rasterDataset = null;
15 if (!File.Exists(string.Format(@"{0}\{1}", path, fileName)))
16 {
17 //创建TIFF格式栅格数据.
18 rasterDataset = rasterWs.CreateRasterDataset(fileName, "TIFF",
19 origin, width, height, xCell, yCell, NumBand, rstPixelType.PT_UCHAR, sr,
20 true);
21 }
22 else
23 {
24 throw new ArgumentException("栅格数据已经存在");
25 }
26 return rasterDataset;
27 }
28 catch (Exception ex)
29 {
30 System.Diagnostics.Debug.WriteLine(ex.Message);
31 return null;
32 }
33 }
调用的OpenRasterWorkspace方法代码:

1 public static IRasterWorkspace2 OpenRasterWorkspace(string PathName)
2 {
3 //This function opens a raster workspace.
4 try
5 {
6 IWorkspaceFactory workspaceFact = new RasterWorkspaceFactoryClass();
7 return workspaceFact.OpenFromFile(PathName, 0) as IRasterWorkspace2;
8 }
9 catch (Exception ex)
10 {
11 System.Diagnostics.Debug.WriteLine(ex.Message);
12 return null;
13 }
14 }
总结:
- IRaster.CreatePixelBlock() Allocates a PixelBlock of requested size.用这个获取特定大小的块
- IRaster.CreateCursor Allocates a Raster Cursor for fast raster scanning.
The IRasterCursor interface controls enumeration through the PixelBlocks in a Raster. It is useful for rasters that are too large to be brought into
memory at once.The RasterCursor divides the Raster into blocks 128 pixels high that span the full width of the raster. Each successive PixelBlock
is read128 lines below the previous PixelBlock.To create a RasterCursor, use the IRaster::CreateCursor or IRaster2::CreateCursorEx method.
RasterCursor 是AE默认的块大小读取
- RawBlocks Raster pixels can be accessed through the IRasterEdit and IPixelBlock3 interfaces. These interfaces read and edit pixels on raster objects. The RawBlocks object, new at ArcGIS 10, works with pixels on a raster band. It reads pixels using an internal tiling structure and loops through the pixel blocks without resampling. 是有Tile结构在里面
作者:太一吾鱼水
文章未经说明均属原创,学习笔记可能有大段的引用,一般会注明参考文献。
欢迎大家留言交流,转载请注明出处。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
2013-11-11 C#+GDAL读写文件
2013-11-11 投影知识点
2012-11-11 [C++学习]C++内存管理