LCOV - code coverage report
Current view: top level - apps - gdalalg_vector_rasterize.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 144 153 94.1 %
Date: 2025-05-15 13:16:46 Functions: 3 3 100.0 %

          Line data    Source code
       1             : /******************************************************************************
       2             :  *
       3             :  * Project:  GDAL
       4             :  * Purpose:  gdal "vector rasterize" subcommand
       5             :  * Author:   Alessandro Pasotti <elpaso at itopen dot it>
       6             :  *
       7             :  ******************************************************************************
       8             :  * Copyright (c) 2025, Alessandro Pasotti <elpaso at itopen dot it>
       9             :  *
      10             :  * SPDX-License-Identifier: MIT
      11             :  ****************************************************************************/
      12             : 
      13             : #include <cmath>
      14             : 
      15             : #include "gdalalg_vector_rasterize.h"
      16             : 
      17             : #include "cpl_conv.h"
      18             : #include "gdal_priv.h"
      19             : #include "gdal_utils.h"
      20             : 
      21             : //! @cond Doxygen_Suppress
      22             : 
      23             : #ifndef _
      24             : #define _(x) (x)
      25             : #endif
      26             : 
      27             : /************************************************************************/
      28             : /*        GDALVectorRasterizeAlgorithm::GDALVectorRasterizeAlgorithm()  */
      29             : /************************************************************************/
      30             : 
      31          33 : GDALVectorRasterizeAlgorithm::GDALVectorRasterizeAlgorithm()
      32          33 :     : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL)
      33             : {
      34          33 :     AddProgressArg();
      35          33 :     AddOutputFormatArg(&m_outputFormat)
      36             :         .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES,
      37         132 :                          {GDAL_DCAP_RASTER, GDAL_DCAP_CREATE})
      38          66 :         .AddMetadataItem(GAAMDI_VRT_COMPATIBLE, {"false"});
      39          33 :     AddOpenOptionsArg(&m_openOptions);
      40          33 :     AddInputFormatsArg(&m_inputFormats)
      41          66 :         .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR});
      42          33 :     AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR);
      43          33 :     AddOutputDatasetArg(&m_outputDataset, GDAL_OF_RASTER)
      44          33 :         .SetDatasetInputFlags(GADV_NAME | GADV_OBJECT);
      45          33 :     AddCreationOptionsArg(&m_datasetCreationOptions);
      46          33 :     AddBandArg(&m_bands, _("The band(s) to burn values into (1-based index)"));
      47          66 :     AddArg("invert", 0, _("Invert the rasterization"), &m_invert)
      48          33 :         .SetDefault(false);
      49             :     AddArg("all-touched", 0, _("Enables the ALL_TOUCHED rasterization option"),
      50          33 :            &m_allTouched);
      51          33 :     AddArg("burn", 0, _("Burn value"), &m_burnValues);
      52          33 :     AddArg("attribute-name", 'a', _("Attribute name"), &m_attributeName);
      53             :     AddArg("3d", 0,
      54             :            _("Indicates that a burn value should be extracted from the Z"
      55             :              " values of the feature"),
      56          33 :            &m_3d);
      57             :     auto &addArg =
      58          33 :         AddArg("add", 0, _("Add to existing raster"), &m_add).SetDefault(false);
      59          66 :     AddArg("layer-name", 'l', _("Layer name"), &m_layerName)
      60          66 :         .AddAlias("layer")
      61          33 :         .SetMutualExclusionGroup("layer-name-or-sql");
      62          33 :     AddArg("where", 0, _("SQL where clause"), &m_where);
      63          66 :     AddArg("sql", 0, _("SQL select statement"), &m_sql)
      64          33 :         .SetMutualExclusionGroup("layer-name-or-sql");
      65          33 :     AddArg("dialect", 0, _("SQL dialect"), &m_dialect);
      66             :     AddArg("nodata", 0, _("Assign a specified nodata value to output bands"),
      67          33 :            &m_nodata);
      68             :     AddArg("init", 0, _("Pre-initialize output bands with specified value"),
      69          33 :            &m_initValues);
      70          66 :     AddArg("crs", 0, _("Override the projection for the output file"), &m_srs)
      71          66 :         .AddHiddenAlias("srs")
      72          33 :         .SetIsCRSArg(/*noneAllowed=*/false);
      73             :     AddArg("transformer-option", 0,
      74             :            _("Set a transformer option suitable to pass to "
      75             :              "GDALCreateGenImgProjTransformer2"),
      76          66 :            &m_transformerOption)
      77          33 :         .SetMetaVar("<NAME>=<VALUE>");
      78             :     AddArg("extent", 0, _("Set the target georeferenced extent"),
      79          66 :            &m_targetExtent)
      80          33 :         .SetMinCount(4)
      81          33 :         .SetMaxCount(4)
      82          33 :         .SetRepeatedArgAllowed(false)
      83          33 :         .SetMetaVar("<xmin>,<ymin>,<xmax>,<ymax>");
      84          66 :     AddArg("resolution", 0, _("Set the target resolution"), &m_targetResolution)
      85          33 :         .SetMinCount(2)
      86          33 :         .SetMaxCount(2)
      87          33 :         .SetRepeatedArgAllowed(false)
      88          66 :         .SetMetaVar("<xres>,<yres>")
      89          33 :         .SetMutualExclusionGroup("size-or-resolution");
      90             :     AddArg("target-aligned-pixels", 0,
      91             :            _("(target aligned pixels) Align the coordinates of the extent of "
      92             :              "the output file to the values of the resolution"),
      93          66 :            &m_tap)
      94          33 :         .AddAlias("tap");
      95             :     AddArg("size", 0, _("Set the target size in pixels and lines"),
      96          66 :            &m_targetSize)
      97          33 :         .SetMinCount(2)
      98          33 :         .SetMaxCount(2)
      99          33 :         .SetRepeatedArgAllowed(false)
     100          66 :         .SetMetaVar("<xsize>,<ysize>")
     101          33 :         .SetMutualExclusionGroup("size-or-resolution");
     102          33 :     AddOutputDataTypeArg(&m_outputType);
     103             :     AddArg("optimization", 0,
     104             :            _("Force the algorithm used (results are identical)"),
     105          66 :            &m_optimization)
     106          33 :         .SetChoices("AUTO", "RASTER", "VECTOR")
     107          33 :         .SetDefault("AUTO");
     108          33 :     auto &updateArg = AddUpdateArg(&m_update);
     109          33 :     AddOverwriteArg(&m_overwrite);
     110             :     addArg.AddValidationAction(
     111           1 :         [&updateArg]()
     112             :         {
     113           1 :             updateArg.Set(true);
     114           1 :             return true;
     115          33 :         });
     116          33 : }
     117             : 
     118             : /************************************************************************/
     119             : /*                GDALVectorRasterizeAlgorithm::RunImpl()               */
     120             : /************************************************************************/
     121             : 
     122          26 : bool GDALVectorRasterizeAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
     123             :                                            void *pProgressData)
     124             : {
     125          26 :     CPLAssert(m_inputDataset.GetDatasetRef());
     126             : 
     127          52 :     CPLStringList aosOptions;
     128             : 
     129          26 :     if (m_bands.size())
     130             :     {
     131          72 :         for (int band : m_bands)
     132             :         {
     133          54 :             aosOptions.AddString("-b");
     134          54 :             aosOptions.AddString(CPLSPrintf("%d", band));
     135             :         }
     136             :     }
     137             : 
     138          26 :     if (m_invert)
     139             :     {
     140           1 :         aosOptions.AddString("-i");
     141             :     }
     142             : 
     143          26 :     if (m_allTouched)
     144             :     {
     145          25 :         aosOptions.AddString("-at");
     146             :     }
     147             : 
     148          26 :     if (m_burnValues.size())
     149             :     {
     150          92 :         for (double burnValue : m_burnValues)
     151             :         {
     152          69 :             aosOptions.AddString("-burn");
     153          69 :             aosOptions.AddString(CPLSPrintf("%.17g", burnValue));
     154             :         }
     155             :     }
     156             : 
     157          26 :     if (!m_attributeName.empty())
     158             :     {
     159           3 :         aosOptions.AddString("-a");
     160           3 :         aosOptions.AddString(m_attributeName.c_str());
     161             :     }
     162             : 
     163          26 :     if (m_3d)
     164             :     {
     165           2 :         aosOptions.AddString("-3d");
     166             :     }
     167             : 
     168          26 :     if (m_add)
     169             :     {
     170           1 :         aosOptions.AddString("-add");
     171             :         // Implies update
     172           1 :         m_update = true;
     173             :     }
     174             : 
     175          26 :     if (!m_layerName.empty())
     176             :     {
     177          19 :         aosOptions.AddString("-l");
     178          19 :         aosOptions.AddString(m_layerName.c_str());
     179             :     }
     180             : 
     181          26 :     if (!m_where.empty())
     182             :     {
     183           1 :         aosOptions.AddString("-where");
     184           1 :         aosOptions.AddString(m_where.c_str());
     185             :     }
     186             : 
     187          26 :     if (!m_sql.empty())
     188             :     {
     189           4 :         aosOptions.AddString("-sql");
     190           4 :         aosOptions.AddString(m_sql.c_str());
     191             :     }
     192             : 
     193          26 :     if (!m_dialect.empty())
     194             :     {
     195           3 :         aosOptions.AddString("-dialect");
     196           3 :         aosOptions.AddString(m_dialect.c_str());
     197             :     }
     198             : 
     199          26 :     if (!m_outputFormat.empty())
     200             :     {
     201           0 :         aosOptions.AddString("-of");
     202           0 :         aosOptions.AddString(m_outputFormat.c_str());
     203             :     }
     204             : 
     205          26 :     if (!std::isnan(m_nodata))
     206             :     {
     207           1 :         aosOptions.AddString("-a_nodata");
     208           1 :         aosOptions.AddString(CPLSPrintf("%.17g", m_nodata));
     209             :     }
     210             : 
     211          26 :     if (m_initValues.size())
     212             :     {
     213          12 :         for (double initValue : m_initValues)
     214             :         {
     215           9 :             aosOptions.AddString("-init");
     216           9 :             aosOptions.AddString(CPLSPrintf("%.17g", initValue));
     217             :         }
     218             :     }
     219             : 
     220          26 :     if (!m_srs.empty())
     221             :     {
     222           1 :         aosOptions.AddString("-a_srs");
     223           1 :         aosOptions.AddString(m_srs.c_str());
     224             :     }
     225             : 
     226          26 :     if (m_transformerOption.size())
     227             :     {
     228           0 :         for (const auto &to : m_transformerOption)
     229             :         {
     230           0 :             aosOptions.AddString("-to");
     231           0 :             aosOptions.AddString(to.c_str());
     232             :         }
     233             :     }
     234             : 
     235          26 :     for (const auto &co : m_datasetCreationOptions)
     236             :     {
     237           0 :         aosOptions.AddString("-dsco");
     238           0 :         aosOptions.AddString(co.c_str());
     239             :     }
     240             : 
     241          26 :     if (m_targetExtent.size())
     242             :     {
     243           1 :         aosOptions.AddString("-te");
     244           5 :         for (double targetExtent : m_targetExtent)
     245             :         {
     246           4 :             aosOptions.AddString(CPLSPrintf("%.17g", targetExtent));
     247             :         }
     248             :     }
     249             : 
     250          26 :     if (m_targetResolution.size())
     251             :     {
     252           6 :         aosOptions.AddString("-tr");
     253          18 :         for (double targetResolution : m_targetResolution)
     254             :         {
     255          12 :             aosOptions.AddString(CPLSPrintf("%.17g", targetResolution));
     256             :         }
     257             :     }
     258             : 
     259          26 :     if (m_tap)
     260             :     {
     261           1 :         aosOptions.AddString("-tap");
     262             :     }
     263             : 
     264          26 :     if (m_targetSize.size())
     265             :     {
     266           3 :         aosOptions.AddString("-ts");
     267           9 :         for (int targetSize : m_targetSize)
     268             :         {
     269           6 :             aosOptions.AddString(CPLSPrintf("%d", targetSize));
     270             :         }
     271             :     }
     272             : 
     273          26 :     if (!m_outputType.empty())
     274             :     {
     275           0 :         aosOptions.AddString("-ot");
     276           0 :         aosOptions.AddString(m_outputType.c_str());
     277             :     }
     278             : 
     279          26 :     if (!m_optimization.empty())
     280             :     {
     281          26 :         aosOptions.AddString("-optim");
     282          26 :         aosOptions.AddString(m_optimization.c_str());
     283             :     }
     284             : 
     285          26 :     bool bOK = false;
     286             :     std::unique_ptr<GDALRasterizeOptions, decltype(&GDALRasterizeOptionsFree)>
     287             :         psOptions{GDALRasterizeOptionsNew(aosOptions.List(), nullptr),
     288          26 :                   GDALRasterizeOptionsFree};
     289          26 :     if (psOptions)
     290             :     {
     291          22 :         GDALRasterizeOptionsSetProgress(psOptions.get(), pfnProgress,
     292             :                                         pProgressData);
     293             : 
     294             :         GDALDatasetH hDstDS =
     295          22 :             GDALDataset::ToHandle(m_outputDataset.GetDatasetRef());
     296             : 
     297             :         GDALDatasetH hSrcDS =
     298          22 :             GDALDataset::ToHandle(m_inputDataset.GetDatasetRef());
     299          22 :         auto poRetDS = GDALDataset::FromHandle(
     300          22 :             GDALRasterize(m_outputDataset.GetName().c_str(), hDstDS, hSrcDS,
     301          22 :                           psOptions.get(), nullptr));
     302          22 :         bOK = poRetDS != nullptr;
     303             : 
     304          22 :         if (!hDstDS)
     305             :         {
     306           9 :             m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS));
     307             :         }
     308             :     }
     309             : 
     310          52 :     return bOK;
     311             : }
     312             : 
     313             : //! @endcond

Generated by: LCOV version 1.14