缘起

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. 牛客练习赛 26 C题 城市规划【贪心】

    <题目链接> 题目描述 小a的国家里有n个城市,其中第i和第i - 1个城市之间有无向道路连接,特殊的,第1个城市仅与第2个城市相连为了减轻道路维护负担,城市规划局局长MXT给出了m个要求 ...

  2. Java内存空间的分配及回收

    Java中内存分为: 栈:存放简单数据类型变量(值和变量名都存在栈中),存放引用数据类型的变量名以及它所指向的实例的首地址. 堆:存放引用数据类型的实例. Java的垃圾回收 由一个后台线程gc进行垃 ...

  3. javascipt

    JavaScript的历史 1992年Nombas开发出C-minus-minus(C--)的嵌入式脚本语言(最初绑定在CEnvi软件中).后将其改名ScriptEase.(客户端执行的语言) Net ...

  4. python函数(一)调用函数

    在python中内置了很多函数或者类,比如:int,str,list,tuple,等.当然也可以自建函数,这个放在后文讨论.原理如下: 其实python中的类和方法非常非常多,这里只是以点带面,提供一 ...

  5. ENQUIRE the predecessor to the World Wide Web.

    看Building Responsive Data Visualization for the Web时介绍到了Enquire,表示wiki类系统实现了它的核心思想. 有点好奇是如何实现的,所以大概看 ...

  6. Python中join 和 split详解(推荐)

    http://www.jb51.net/article/87700.htm python join 和 split方法简单的说是:join用来连接字符串,split恰好相反,拆分字符串的. .join ...

  7. PhotoshopCC 2017安装破解 + cuterman

    之前安装了PhotoshopCC 2017版本的软件,但是绿色版的(安装简介.使用方便).但是在随着Adobe公司对设计的不断追求和工具的不断更新,更加强大.更加优秀的设计插件和工具不断出新,最近朋友 ...

  8. BZOJ2268 : Wormly

    考虑头部,一定是能向前就向前,因此是最左边的腿往右$b-1$个位置. 头部移动之后,腿部就要相应地移动到区间内最靠右的$l$个$1$之上. 若头部和腿部都不能移动,检查是否到达终点即可. 用前缀和以及 ...

  9. C++程序设计方法3:函数重写

    派生类对象包含从基类继承类的数据成员,他们构成了“基类子对象”基类中的私有成员,不允许在派生类成员函数中被访问,也不允许派生类的对象访问他们:真正体现基类私有,对派生类也不开放其权限:基类中的公有成员 ...

  10. yii2 Gridview网格小部件

    Gridview 网格小部件 一.特点: 1.是yii中功能最强大的小部件之一: 2.非常适合快速建立系统的管理后台. 3.用 dataProvider 键来指定数据的提供者 4.用 filterMo ...