ArcEngine和GDAL读写栅格数据机制对比(二)—— IPixelBlock读写栅格

时间:2022-04-05 07:09:11

以下是设定一个矩形框,用IPixelBlock将256*256瓦片tile拼接成一个整块影像的代码,row1, col1, row2, col2是一个矩形框行列号范围。level是瓦片的金字塔等级。这里的瓦片已经下载完毕,位于domSavePath文件夹下。

             //选择的Google瓦块的行列号范围
int row1, col1, row2, col2;
int nTileSize = ;
row1 = topLeft.Row;
col1 = topLeft.Col;
row2 = bottomRight.Row;
col2 = bottomRight.Col;
//拼接影像大小
int nImgSizeX = (col2 - col1 + ) * nTileSize;
int nImgSizeY = (row2 - row1 + ) * nTileSize; double leftlon = (((col1 * 20037508.343) * 2.0) / (Math.Pow(2.0, (double)level - 1.0))) - 20037508.343;
double toplat = 20037508.343 - (((row1 * 20037508.343) * 2.0) / (Math.Pow(2.0, (double)level - 1.0)));
double pixel = 40075016.686 / (nTileSize * Math.Pow(2.0, (double)level - 1.0));
//拼接图像的左上角点,WebMecator投影
IPoint origin = new PointClass();
origin.PutCoords(leftlon, toplat);
//创建拼接图像
IRasterDataset mergeRasterDs = CreateRasterDataset(domSavePath, "Full.tif", origin, nImgSizeX, nImgSizeY, pixel, pixel, ); for (int ii = row1; ii <= row2; ii++)
{
for (int jj = col1; jj <= col2; jj++)
{
//瓦片的名称
string tileName = ii.ToString().PadLeft(, '') + "_" + jj.ToString().PadLeft(, '') + "." + _fileEndExtent;
string FilePath = domSavePath + @"\" + tileName;
if (!File.Exists(FilePath))
{
continue;
}
//读取瓦片数据集
IRasterDataset tileRasterDs = OpenFileRasterDataset(domSavePath, tileName);
IRasterDataset2 tileRasterDs2 = tileRasterDs as IRasterDataset2;
IRaster tileRaster = tileRasterDs2.CreateFullRaster();
//设置瓦片像素快大小
IPnt tileBlockSize = new PntClass();
tileBlockSize.SetCoords(, );
IPixelBlock3 readPixelblock = tileRaster.CreatePixelBlock(tileBlockSize) as IPixelBlock3;
//瓦块的左上角点
IPnt tileTopleftCorner = new PntClass();
tileTopleftCorner.SetCoords(, );
tileRaster.Read(tileTopleftCorner, readPixelblock as IPixelBlock); //If you need to set NoData for some of the pixels, you need to set it on band
//to get the raster band.
//IRasterBandCollection rasterBands = (IRasterBandCollection)rasterDataset;
//IRasterBand rasterBand;
//IRasterProps rasterProps;
//rasterBand = rasterBands.Item(0);
//rasterProps = (IRasterProps)rasterBand;
//Set NoData if necessary. For a multiband image, a NoData value needs to be set for each band.
//rasterProps.NoDataValue = 255; //从数据集中读取IRaster
IRasterDataset2 mergeRasterDs2 = mergeRasterDs as IRasterDataset2;
IRaster mergeRaster = mergeRasterDs2.CreateFullRaster(); //Create a pixel block using the weight and height of the raster dataset.
//If the raster dataset is large, a smaller pixel block should be used.
//Refer to the topic "How to access pixel data using a raster cursor".
IPnt blocksize2 = new PntClass();
blocksize2.SetCoords(, );
IPixelBlock3 writePixelblock = mergeRaster.CreatePixelBlock(tileBlockSize) as IPixelBlock3; System.Array pixelsTarget;
System.Array pixelsOrigin;//瓦块的像素坐标
for (int iplane = ; iplane < ; iplane++)
{
pixelsOrigin = (System.Array)readPixelblock.get_PixelData(iplane);
pixelsTarget = (System.Array)writePixelblock.get_PixelData(iplane);
for (int i = ; i < ; i++)
{
for (int j = ; j < ; j++)
{
object obj = pixelsOrigin.GetValue(i, j);
pixelsTarget.SetValue(obj, i, j);
}
}
writePixelblock.set_PixelData(iplane, (System.Array)pixelsOrigin);
}
//瓦块偏移左上角的像素值
int nOffsetX = (jj - col1) * nTileSize;
int nOffsetY = (ii - row1) * nTileSize;
//定义pixel block左上角点坐标,执行写入.
IPnt upperLeft = new PntClass();
upperLeft.SetCoords(nOffsetX, nOffsetY); //写入拼接影像中
IRasterEdit mergeRasterEdit = (IRasterEdit)mergeRaster;
mergeRasterEdit.Write(upperLeft, (IPixelBlock)writePixelblock); //释放mergeRasterEdit引用.
System.Runtime.InteropServices.Marshal.ReleaseComObject(mergeRasterEdit);
}
}
调用的CreateRasterDataset方法的代码如下:(这里注意:上面调用的时候出现了一个错误,Origin是左下角点坐标)
  public static IRasterDataset CreateRasterDataset(string path, string fileName, IPoint origin, int width, int height, double xCell, double yCell, int NumBand)
{
try
{
IRasterWorkspace2 rasterWs = OpenRasterWorkspace(path);
//定义空间参考
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]]"; ISpatialReference sr = CreateWebMector();
if (sr == null)
{
sr = new UnknownCoordinateSystemClass();
}
IRasterDataset rasterDataset = null;
if (!File.Exists(string.Format(@"{0}\{1}", path, fileName)))
{
//创建TIFF格式栅格数据.
rasterDataset = rasterWs.CreateRasterDataset(fileName, "TIFF",
origin, width, height, xCell, yCell, NumBand, rstPixelType.PT_UCHAR, sr,
true);
}
else
{
throw new ArgumentException("栅格数据已经存在");
}
return rasterDataset;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
}

CreateRasterDataset

调用的OpenRasterWorkspace方法代码:

  public static IRasterWorkspace2 OpenRasterWorkspace(string PathName)
{
//This function opens a raster workspace.
try
{
IWorkspaceFactory workspaceFact = new RasterWorkspaceFactoryClass();
return workspaceFact.OpenFromFile(PathName, ) as IRasterWorkspace2;
}
catch (Exception ex)
{
System.Diagnostics.Debug.WriteLine(ex.Message);
return null;
}
}

总结:

  • 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结构在里面

ArcEngine和GDAL读写栅格数据机制对比(二)—— IPixelBlock读写栅格的更多相关文章

  1. ArcEngine和GDAL读写栅格数据机制对比(一)

    最近应用AE开发插值和栅格转等值线的程序,涉及到栅格读写的有关内容.联想到ArcGIS利用了GDAL的某些东西,从AE的OMD中也发现RasterDataset和RasterBand这些命名和GDAL ...

  2. &lbrack;评测&rsqb;低配环境下,PostgresQL和Mysql读写性能简单对比(欢迎大家提出Mysql优化意见)

    [评测]低配环境下,PostgresQL和Mysql读写性能简单对比 原文链接:https://www.cnblogs.com/blog5277/p/10658426.html 原文作者:博客园--曲 ...

  3. 脑残式网络编程入门&lpar;二&rpar;:我们在读写Socket时,究竟在读写什么?

    1.引言 本文接上篇<脑残式网络编程入门(一):跟着动画来学TCP三次握手和四次挥手>,继续脑残式的网络编程知识学习 ^_^. 套接字socket是大多数程序员都非常熟悉的概念,它是计算机 ...

  4. &lbrack;转帖&rsqb;脑残式网络编程入门&lpar;二&rpar;:我们在读写Socket时,究竟在读写什么?

    脑残式网络编程入门(二):我们在读写Socket时,究竟在读写什么?     http://www.52im.net/thread-1732-1-1.html   1.引言 本文接上篇<脑残式网 ...

  5. 基于Keepalived高可用集群的MariaDB读写分离机制实现

    一 MariaDB读写分离机制 在实现读写分离机制之前先理解一下三种主从复制方式:1.异步复制:MariaDB默认的复制即是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库 ...

  6. 浅谈:Redis持久化机制(二)AOF篇

    浅谈:Redis持久化机制(二)AOF篇 ​ 上一篇我们提及到了redis的默认持久化方式RDB,是一种通过存储快照数据方式持久化的机制,它在宕机后会丢失掉最后一次更新RDB文件后的数据,这也是由于它 ...

  7. IM消息送达保证机制实现&lpar;二&rpar;:保证离线消息的可靠投递

    1.前言 本文的上篇<IM消息送达保证机制实现(一):保证在线实时消息的可靠投递>中,我们讨论了在线实时消息的投递可以通过应用层的确认.发送方的超时重传.接收方的去重等手段来保证业务层面消 ...

  8. Apache与Nginx对客户端请求的处理机制对比

    Apache与Nginx对客户端请求的处理机制对比 模块 大致为四个模块,核心模块.HTTP模块.邮件模块,以及第三方模块 核心模块主要包含两类功能的支持,一类是主体功能,包括进程管理,权限管理,错误 ...

  9. Android Priority Job Queue &lpar;Job Manager&rpar;:线程任务的容错重启机制(二)

     Android Priority Job Queue (Job Manager):线程任务的容错重启机制(二) 附录文章4简单介绍了如何启动一个后台线程任务,Android Priority J ...

随机推荐

  1. IIS7&period;5配置SSL

    1,首先需要准备两个证书(CA证书,服务器证书). CA证书由公共的CA机构提供,widnow系统内部已经内置了很多这类证书,如图(日文系统). 服务器证书是导入到IIS里面用的. 2,有了上面的认识 ...

  2. c语言小程序

    这是一个用c语言写的小程序,功能是随机输出30道100以内的四则运算,先生成两个随机数,再通过随机数确定四则运算符号,最后输出题目. #include<iostream> using na ...

  3. Codeforces Canada Cup 2016

    A. Jumping Ball time limit per test 2 seconds memory limit per test 256 megabytes input standard inp ...

  4. Anchor和Dock的区别

    Dock的Bottom,整个控件填充下半部分,控件会被横向拉长 Anchor,仅仅是控件固定在下方,位置不会发生移动,自动锚定了此控件和父容器的底部的间隔 Anchor可以确定控件的相对位置不发生变化

  5. 腾讯2013笔试题—web前端笔试题 (老题练手)

    问题描述(web前端开发附加题1): 编写一个javascript的函数把url解析为与页面的javascript.location对象相似的实体对象,如:url :'http://www.qq.co ...

  6. grpc-gateway:grpc对外提供http服务的解决方案

    我所在公司的项目是采用基于Restful的微服务架构,随着微服务之间的沟通越来越频繁,就希望可以做成用rpc来做内部的通讯,对外依然用Restful.于是就想到了google的grpc. 使用grpc ...

  7. ●BZOJ 1185 &lbrack;HNOI2007&rsqb;最小矩形覆盖

    题链: http://www.lydsy.com/JudgeOnline/problem.php?id=1185 题解: 计算几何,凸包,旋转卡壳 结论:矩形的某一条边在凸包的一条边所在的直线上. ( ...

  8. Loader转换器

    一.简介 webpack本身只能处理js模块,Loader可以理解为模块和资源的转换器,它本身是一个函数,接受文件作为参数,返回转换的结果.因此,我们就能通过require来加载任何类型的模块和文件. ...

  9. vue 安装及使用

    一,  vue.js 2.0 1, cnpm install vue-cli -g 全局安装 2, 运行vue查看安装是否成功(创建vue-cli目录: vue init webpack demo) ...

  10. Bomb 数位dp

    ---恢复内容开始--- 不能有49 数位dp模板题: #include<bits/stdc++.h> using namespace std; //input by bxd #defin ...