在GDAL中添加GDALRasterizeGeometriesBuf函数
缘起
GDAL的栅格化算法中有GDALRasterizeLayers
、GDALRasterizeLayersBuf
和GDALRasterizeGeometries
函数,但是没有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函数的更多相关文章
- 在C语言结构体中添加成员函数
我们在使用C语言的结构体时,经常都是只定义几个成员变量,而学过面向对象的人应该知道,我们定义类时,不只是定义了成员变量,还定义了成员方法,而类的结构和结构体非常的相似,所以,为什么不想想如何在C语言结 ...
- 教你在 Yii2 中添加全局函数
方法一 这种方法就是直接在入口文件web/index.php里面写函数,示例代码如下: // something code …… // 全局函数 function pr($var) { $templa ...
- render()中添加js函数
方案一: { title: '操作', key: 'operation', render: (_, record) => ( <div> <Link to={`/hostMai ...
- MFC编程入门之九(对话框:为控件添加消息处理函数)
这一节讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件定义了诸多消息,我们对他们操作时会触发消息,这些消息最终由消息处理函数处理,比如我们点击按钮时就会产生BN_CLICKED消息,修 ...
- VS2010/MFC对话框四:为控件添加消息处理函数
为控件添加消息处理函数 创建对话框类和添加控件变量在上一讲中已经讲过,这一讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消 ...
- trueStudio中使用printf函数
1.通过printf输出浮点数需要如下设置: 在工程属性下找到C/C++ build->Settings->Tool Settings->C Linker->Miscellan ...
- VS2010/MFC编程入门之九(对话框:为控件添加消息处理函数)
创建对话框类和添加控件变量在上一讲中已经讲过,这一讲的主要内容是如何为控件添加消息处理函数. MFC为对话框和控件等定义了诸多消息,我们对它们操作时会触发消息,这些消息最终由消息处理函数处理.比如我们 ...
- 在 Cocos2d-x 中添加自己的微博链接
配置:OS X 10.10 + Xcode 6.0 + Cocos2d-x-3.2 一.Android 端代码 1.在 Cocos2dxActivity.java 中添加openUrl函数并导入响应包 ...
- LoadRunner中的Web 函数列表
LoadRunner中的Web 函数列表 web test LoadRunner fuction_list D:\Program Files (x86)\Mercury Interactive\Mer ...
随机推荐
- Binder原理
--摘自<android插件化开发指南> 1.Binder分为Client和Server两个进程: client和server是相对的.谁发消息,谁就是client:谁接收消息,谁就是se ...
- HDU4578 Transformation【线段树】
<题目链接> <转载于 >>> > 题目大意: 有一个序列,有四种操作: 1:区间[l,r]内的数全部加c. 2:区间[l,r]内的数全部乘c. 3:区间[l ...
- Django之win7下安装与命令行工具
Django之win7下安装与命令行工具 下载安装 pip3 install django 注意:自动添加环境变量 测试是否安装成功 1.输入python 2.输入import django 3.输入 ...
- webpack 4.x之搭建前端开发环境
webpack是一个现代JavaScript应用程序的静态模块打包器,借用官网的一张图,它能够将一些预处理语言,js的最新语法转换成浏览器识别的内容.现在一般的前端框架都有比较成熟的脚手架,大多数对w ...
- Adobe Premiere Pro生成峰值文件假死
一.正文 使用Adobe的Premiere Pro CC进行视频剪辑制作的时候,有的时候在右下角总会出现一个“自动生成峰值文件”的提示符,并跟随一个进度条: 大部分时候,这并不会引起什么问题.虽然我也 ...
- Django单表操作
一.数据库相关设置 配置ORM的loggers日志: # 配置ORM的loggers日志 LOGGING = { 'version': 1, 'disable_existing_loggers': F ...
- Redis自学笔记:3.4入门-列表类型
3.4列表类型 3.4.1介绍 列表类型可以存储一个有序的字符串列表,常用的操作是向列表两端添加元素,或者 获得列表的某一片段. 优点:内部使用的是双向链表,所以向列表两端添加元素的时间复杂度为O(1 ...
- BZOJ.5251.[八省联考2018]劈配mentor(最大流)
BZOJ 洛谷 对于每个人,每次枚举一个志愿看是否能增广即可. 对于第二问,可以保留第一问中\(n\)次增广前后的\(n\)张图,二分,在对应图上看是否能增广即可. 貌似匈牙利的某种写法比网络流优多了 ...
- Lua的 table.sort排序
在用table.sort 排序的时候注意,如果使用多个条件排序,应在一个排序函数里按照条件优先级进行比较排序. 例如 local t = { {time = , i = }, {time = , i ...
- (转)ConurrentHashMap和Hashtable的区别
集合类是Java API的核心,但是我觉得要用好它们是一种艺术.我总结了一些个人的经验,譬如使用ArrayList能够提高性能,而不再需要过时的Vector了,等等.JDK 1.5引入了一些好用的并发 ...