在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 ...
随机推荐
- Java实现简单计算器、抽票程序
计算器: import java.awt.BorderLayout; import java.awt.Container; import java.awt.Font; import java.awt. ...
- Java大数相加-hdu1047
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1047 题目描述: 题意有点绕,但是仔细的读了后就发现是处理大数相加的问题.注意:输入数据有多组,每组输 ...
- PostgreSQL 在Ubuntu下如何修改postgres默认密码
Step1: 切换用户为postgres sudo su postgres Step2: 用postgres连接postgreSQL psql -U postgres Step3: 修改postgre ...
- uni-app — 一套前端开发跨平台应用的终极解决方案
uni-app 是一个使用 Vue.js 开发跨平台应用的前端框架,开发者编写一套代码,可编译到iOS.Android.H5.小程序等多个平台. 今天有空就来介绍一下uni-app这个能够跨平台开发, ...
- Spring监听,ApplicationListener
import java.util.HashMap; import java.util.Map; import org.apache.commons.lang3.StringUtils; import ...
- 详解Spring中的ApplicationListener和ContextRefreshedEvent
ApplicationListener和ContextRefreshedEvent一般都是成对出现的.最近在面试中问到了被面试者对于这两个的用法,面试者大多数被问懵了.可见基础知识的掌握程度.基于此本 ...
- SpringBoot使用数据库
这一篇简单介绍一下SpringBoot配置数据库的配置(依赖和application.properties),以下全是以本地数据库为例子,具体用户名密码地址都根据实际去修改. Mysql数据库: po ...
- TF-IDF算法解释
http://www.ruanyifeng.com/blog/2013/03/tf-idf.html
- json信息的后台到前台的传输
公共方法: /** * 实际返回的是 response.setContentType("text/html;charset=utf-8"); * * @param o */ pub ...
- redis副本集
1.数据库配置细节: a.拷贝多个redis.conf文件:b.开启daemonize yes; c.Pid文件名字; d.指定端口; e.Log文件名字; f:Dump.rdb名字 2.配置redi ...