zoukankan      html  css  js  c++  java
  • 在GDAL中添加GDALRasterizeGeometriesBuf函数

    缘起

    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;
    }
    
    
  • 相关阅读:
    Paint类的介绍
    缓存淘汰算法之LRU
    Android SurfaceView实战 打造抽奖转盘
    android中scrollTo和scrollBy的理解
    Android View.onMeasure方法的理解
    Android Context 上下文 你必须知道的一切
    Android Animation简述
    Markdown 语法说明
    理解Java虚拟机体系结构
    Java集合框架:HashMap
  • 原文地址:https://www.cnblogs.com/oloroso/p/10368595.html
Copyright © 2011-2022 走看看