在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; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理