缘起

GDAL的栅格化算法中有GDALRasterizeLayersGDALRasterizeLayersBufGDALRasterizeGeometries函数,但是没有GDALRasterizeGeometriesBuf函数(GDAL项目不打算添加这个函数,因为增加一个函数会增加维护成本)。而栅格化算法的实际实现函数gv_rasterize_one_shape并不导出,所以在使用的时候造成了一定的不便。

虽然可以通过MEMDataset的方式,调用GDALRasterizeGeometries达到目的,但是不够直接和高效,所以我写了GDALRasterizeGeometriesBuf函数。

个人认为比较灵活的方式,还是将gv_rasterize_one_shape函数导出,以便自由使用。

代码

修改gdal/alg/gdal_alg.h头文件,在GDALRasterizeGeometries函数声明下添加GDALRasterizeGeometriesBuf函数声明。

CPLErr CPL_DLL
GDALRasterizeGeometriesBuf( void *pData, int nBufXSize, int nBufYSize,
GDALDataType eBufType, int nPixelSpace, int nLineSpace,
int nGeomCount, OGRGeometryH *pahGeometries,
const char *pszGeomProjection,
const char *pszDstProjection,
double *padfDstGeoTransform,
GDALTransformerFunc pfnTransformer,
void *pTransformArg, double dfBurnValue,
char **papszOptions, GDALProgressFunc pfnProgress,
void *pProgressArg );

修改gdal/alg/gdalrasterize.cpp文件,添加GDALRasterizeGeometriesBuf函数的实现,代码如下:

/************************************************************************/
/* GDALRasterizeGeometriesBuf() */
/************************************************************************/ /**
* Burn geometries into raster.
*
* Rasterize a list of geometric objects into a raster dataset. The
* geometries are passed as an array of OGRGeometryH handlers.
*
* If the geometries are in the georeferenced coordinates of the raster
* dataset, then the pfnTransform may be passed in NULL and one will be
* derived internally from the geotransform of the dataset. The transform
* needs to transform the geometry locations into pixel/line coordinates
* of the target raster.
*
* The output raster may be of any GDAL supported datatype, though currently
* internally the burning is done either as GDT_Byte or GDT_Float32. This
* may be improved in the future.
*
* @param pData pointer to the output data array.
* @param nBufXSize width of the output data array in pixels.
* @param nBufYSize height of the output data array in pixels.
* @param eBufType data type of the output data array.
*
* @param nPixelSpace The byte offset from the start of one pixel value in
* pData to the start of the next pixel value within a scanline. If defaulted
* (0) the size of the datatype eBufType is used.
*
* @param nLineSpace The byte offset from the start of one scanline in
* pData to the start of the next. If defaulted the size of the datatype
* eBufType * nBufXSize is used.
*
* @param nGeomCount the number of geometries being passed in pahGeometries.
* @param pahGeometries the array of geometries to burn in.
* @param pszGeomProjection WKT defining the coordinate system of the geometries.
*
* @param pszDstProjection WKT defining the coordinate system of the target
* raster.
*
* @param padfDstGeoTransform geotransformation matrix of the target raster.
*
* @param pfnTransformer transformation to apply to geometries to put into
* pixel/line coordinates on raster. If NULL a geotransform based one will
* be created internally.
*
* @param pTransformArg callback data for transformer.
* @param dfBurnValue the value to burn into the raster.
*
* @param papszOptions special options controlling rasterization:
* <ul>
* <li>"ALL_TOUCHED": May be set to TRUE to set all pixels touched
* by the line or polygons, not just those whose center is within the polygon
* or that are selected by brezenhams line algorithm. Defaults to FALSE.</li>
* <li>"BURN_VALUE_FROM": May be set to "Z" to use
* the Z values of the geometries. dfBurnValue or the attribute field value is
* added to this before burning. In default case dfBurnValue is burned as it
* is. This is implemented properly only for points and lines for now. Polygons
* will be burned using the Z value from the first point. The M value may
* be supported in the future.</li>
* <li>"MERGE_ALG": May be REPLACE (the default) or ADD. REPLACE
* results in overwriting of value, while ADD adds the new value to the
* existing raster, suitable for heatmaps for instance.</li>
* </ul>
*
* @param pfnProgress the progress function to report completion.
*
* @param pProgressArg callback data for progress function.
*
*
* @return CE_None on success or CE_Failure on error.
*/ CPLErr GDALRasterizeGeometriesBuf( void *pData, int nBufXSize, int nBufYSize,
GDALDataType eBufType, int nPixelSpace, int nLineSpace,
int nGeomCount, OGRGeometryH *pahGeometries,
const char *pszGeomProjection,
const char *pszDstProjection,
double *padfDstGeoTransform,
GDALTransformerFunc pfnTransformer,
void *pTransformArg, double dfBurnValue,
char **papszOptions, GDALProgressFunc pfnProgress,
void *pProgressArg ) {
/* -------------------------------------------------------------------- */
/* If pixel and line spaceing are defaulted assign reasonable */
/* value assuming a packed buffer. */
/* -------------------------------------------------------------------- */
if( nPixelSpace != 0 )
{
nPixelSpace = GDALGetDataTypeSizeBytes( eBufType );
}
if( nPixelSpace != GDALGetDataTypeSizeBytes( eBufType ) )
{
CPLError(CE_Failure, CPLE_NotSupported,
"GDALRasterizeGeometriesBuf(): unsupported value of nPixelSpace");
return CE_Failure;
} if( nLineSpace == 0 )
{
nLineSpace = nPixelSpace * nBufXSize;
}
if( nLineSpace != nPixelSpace * nBufXSize )
{
CPLError(CE_Failure, CPLE_NotSupported,
"GDALRasterizeGeometriesBuf(): unsupported value of nLineSpace");
return CE_Failure;
} if( pfnProgress == nullptr )
pfnProgress = GDALDummyProgress; /* -------------------------------------------------------------------- */
/* Do some rudimentary arg checking. */
/* -------------------------------------------------------------------- */
if( nGeomCount == 0 )
return CE_None; /* -------------------------------------------------------------------- */
/* Options */
/* -------------------------------------------------------------------- */
int bAllTouched = FALSE;
GDALBurnValueSrc eBurnValueSource = GBV_UserBurnValue;
GDALRasterMergeAlg eMergeAlg = GRMA_Replace;
GDALRasterizeOptim eOptim = GRO_Auto;
if( GDALRasterizeOptions(papszOptions, &bAllTouched,
&eBurnValueSource, &eMergeAlg,
&eOptim) == CE_Failure )
{
return CE_Failure;
} /* -------------------------------------------------------------------- */
/* If we have no transformer, create the one from input file */
/* projection. Note that each layer can be georefernced */
/* separately. */
/* -------------------------------------------------------------------- */
bool bNeedToFreeTransformer = false; if( pfnTransformer == nullptr )
{
if( !pszGeomProjection )
{
CPLError( CE_Warning, CPLE_AppDefined,
"There is no specified spatial reference for the"
" geometry to build transformer, assuming"
" matching coordinate systems.");
} pTransformArg =
GDALCreateGenImgProjTransformer3( pszGeomProjection, nullptr,
pszDstProjection,
padfDstGeoTransform );
pfnTransformer = GDALGenImgProjTransform;
}
/* ==================================================================== */
/* Write geometry to the raster individually. */
/* ==================================================================== */
CPLErr eErr = CE_None; pfnProgress( 0.0, nullptr, pProgressArg ); int iGeometry;
for(iGeometry = 0; iGeometry < nGeomCount; ++iGeometry )
{
OGRGeometry *poGeom = reinterpret_cast<OGRGeometry*>(pahGeometries[iGeometry]); // 后期gv_rasterize_one_shape函数可能会变,此处后期需要修改
gv_rasterize_one_shape( static_cast<unsigned char *>(pData), 0, 0,
nBufXSize, nBufYSize,
1, eBufType, bAllTouched, poGeom,
&dfBurnValue, eBurnValueSource,
eMergeAlg,
pfnTransformer, pTransformArg ); if( !pfnProgress((iGeometry+1)/static_cast<double>(nGeomCount),
"", pProgressArg) )
{
CPLError( CE_Failure, CPLE_UserInterrupt, "User terminated" );
eErr = CE_Failure;
}
} if( bNeedToFreeTransformer )
GDALDestroyTransformer( pTransformArg ); return eErr;
}

在GDAL中添加GDALRasterizeGeometriesBuf函数的更多相关文章

  1. 在C语言结构体中添加成员函数

    我们在使用C语言的结构体时,经常都是只定义几个成员变量,而学过面向对象的人应该知道,我们定义类时,不只是定义了成员变量,还定义了成员方法,而类的结构和结构体非常的相似,所以,为什么不想想如何在C语言结 ...

  2. 教你在 Yii2 中添加全局函数

    方法一 这种方法就是直接在入口文件web/index.php里面写函数,示例代码如下: // something code …… // 全局函数 function pr($var) { $templa ...

  3. render()中添加js函数

    方案一: { title: '操作', key: 'operation', render: (_, record) => ( <div> <Link to={`/hostMai ...

  4. MFC编程入门之九(对话框:为控件添加消息处理函数)

    这一节讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件定义了诸多消息,我们对他们操作时会触发消息,这些消息最终由消息处理函数处理,比如我们点击按钮时就会产生BN_CLICKED消息,修 ...

  5. VS2010/MFC对话框四:为控件添加消息处理函数

    为控件添加消息处理函数 创建对话框类和添加控件变量在上一讲中已经讲过,这一讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消 ...

  6. trueStudio中使用printf函数

    1.通过printf输出浮点数需要如下设置: 在工程属性下找到C/C++ build->Settings->Tool Settings->C Linker->Miscellan ...

  7. VS2010/MFC编程入门之九(对话框:为控件添加消息处理函数)

    创建对话框类和添加控件变量在上一讲中已经讲过,这一讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理.比如我们 ...

  8. 在 Cocos2d-x 中添加自己的微博链接

    配置:OS X 10.10 + Xcode 6.0 + Cocos2d-x-3.2 一.Android 端代码 1.在 Cocos2dxActivity.java 中添加openUrl函数并导入响应包 ...

  9. LoadRunner中的Web 函数列表

    LoadRunner中的Web 函数列表 web test LoadRunner fuction_list D:\Program Files (x86)\Mercury Interactive\Mer ...

随机推荐

  1. elementui command绑定变量对象方法

    command绑定变量对象方法 使用v-bind : command绑定 简写 :command

  2. CentOS 7 休眠系统

    CentOS 7的电源按钮只有关机和重启两项,但是可以用命令来休眠系统: 重启: $ systemctl reboot 退出系统并停止电源: $ systemctl poweroff 待机: $ sy ...

  3. hdu 2091空心三角形

    把一个字符三角形掏空,就能节省材料成本,减轻重量,但关键是为了追求另一种视觉效果.在设计的过程中,需要给出各种花纹的材料和大小尺寸的三角形样板,通过电脑临时做出来,以便看看效果.  Input每行包含 ...

  4. 6486: An Ordinary Game(规律)

    题目描述 There is a string s of length 3 or greater. No two neighboring characters in s are equal.Takaha ...

  5. Service Discovery And Health Checks In ASP.NET Core With Consul

    在这篇文章中,我们将快速了解一下服务发现是什么,使用Consul在ASP.NET Core MVC框架中,并结合DnsClient.NET实现基于Dns的客户端服务发现 这篇文章的所有源代码都可以在G ...

  6. [洛谷P1880][NOI1995]石子合并

    区间DP模板题 区间DP模板Code: ;len<=n;len++) { ;i<=*n-;i++) //区间左端点 { ; //区间右端点 for(int k=i;k<j;k++) ...

  7. [Python] Marshmallow QuickStart

    常用小操作索引 指定fields必须:fields.String(required=True) 部分loading: 不load name:result = UserSchema.load({'ema ...

  8. BZOJ.4910.[SDOI2017]苹果树(树形依赖背包 DP 单调队列)

    BZOJ 洛谷 \(shadowice\)已经把他的思路说的很清楚了,可以先看一下会更好理解? 这篇主要是对\(Claris\)题解的简单说明.与\(shadowice\)的做法还是有差异的(比如并没 ...

  9. Java笔记(十四) 并发基础知识

    并发基础知识 一.线程的基本概念 线程表示一条单独的执行流,它有自己的程序计数器,有自己的栈. 1.创建线程 1)继承Thread Java中java.lang.Thread这个类表示线程,一个类可以 ...

  10. 潭州课堂25班:Ph201805201 django 项目 第十课 自定义错误码,完成图片验证码,用户是否被注册功能 (课堂笔记)

    把 视图传到前台的  JsonResponse(data=data) 先进行处理,之后再传到前台, 处理:引用自定义错误代码,把错误代码返回给前台,前台根据错误代码中文提示 class Code: O ...