Line data Source code
1 : /****************************************************************************** 2 : * 3 : * Project: GDAL 4 : * Purpose: gdal "vector convert" subcommand 5 : * Author: Even Rouault <even dot rouault at spatialys.com> 6 : * 7 : ****************************************************************************** 8 : * Copyright (c) 2024, Even Rouault <even dot rouault at spatialys.com> 9 : * 10 : * SPDX-License-Identifier: MIT 11 : ****************************************************************************/ 12 : 13 : #include "gdalalg_vector_convert.h" 14 : 15 : #include "cpl_conv.h" 16 : #include "gdal_priv.h" 17 : #include "gdal_utils.h" 18 : 19 : //! @cond Doxygen_Suppress 20 : 21 : #ifndef _ 22 : #define _(x) (x) 23 : #endif 24 : 25 : /************************************************************************/ 26 : /* GDALVectorConvertAlgorithm::GDALVectorConvertAlgorithm() */ 27 : /************************************************************************/ 28 : 29 28 : GDALVectorConvertAlgorithm::GDALVectorConvertAlgorithm() 30 28 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL) 31 : { 32 28 : AddProgressArg(); 33 28 : AddOutputFormatArg(&m_outputFormat) 34 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, 35 84 : {GDAL_DCAP_VECTOR, GDAL_DCAP_CREATE}); 36 28 : AddOpenOptionsArg(&m_openOptions); 37 28 : AddInputFormatsArg(&m_inputFormats) 38 56 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}); 39 28 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR); 40 28 : AddOutputDatasetArg(&m_outputDataset, GDAL_OF_VECTOR) 41 28 : .SetDatasetInputFlags(GADV_NAME | GADV_OBJECT); 42 28 : AddCreationOptionsArg(&m_creationOptions); 43 28 : AddLayerCreationOptionsArg(&m_layerCreationOptions); 44 28 : AddOverwriteArg(&m_overwrite); 45 28 : auto &updateArg = AddUpdateArg(&m_update); 46 : AddArg("overwrite-layer", 0, 47 : _("Whether overwriting existing layer is allowed"), 48 56 : &m_overwriteLayer) 49 28 : .SetDefault(false) 50 : .AddValidationAction( 51 1 : [&updateArg]() 52 : { 53 1 : updateArg.Set(true); 54 1 : return true; 55 28 : }); 56 : AddAppendUpdateArg(&m_appendLayer, 57 28 : _("Whether appending to existing layer is allowed")); 58 56 : AddArg("input-layer", 'l', _("Input layer name(s)"), &m_inputLayerNames) 59 28 : .AddAlias("layer"); 60 56 : AddArg("output-layer", 0, _("Output layer name"), &m_outputLayerName) 61 28 : .AddHiddenAlias("nln"); // For ogr2ogr nostalgic people 62 28 : } 63 : 64 : /************************************************************************/ 65 : /* GDALVectorConvertAlgorithm::RunImpl() */ 66 : /************************************************************************/ 67 : 68 14 : bool GDALVectorConvertAlgorithm::RunImpl(GDALProgressFunc pfnProgress, 69 : void *pProgressData) 70 : { 71 14 : CPLAssert(m_inputDataset.GetDatasetRef()); 72 : 73 28 : CPLStringList aosOptions; 74 14 : aosOptions.AddString("--invoked-from-gdal-vector-convert"); 75 14 : if (!m_overwrite) 76 : { 77 11 : aosOptions.AddString("--no-overwrite"); 78 : } 79 14 : if (m_overwriteLayer) 80 : { 81 1 : aosOptions.AddString("-overwrite"); 82 : } 83 14 : if (m_appendLayer) 84 : { 85 1 : aosOptions.AddString("-append"); 86 : } 87 14 : if (!m_outputFormat.empty()) 88 : { 89 6 : aosOptions.AddString("-of"); 90 6 : aosOptions.AddString(m_outputFormat.c_str()); 91 : } 92 15 : for (const auto &co : m_creationOptions) 93 : { 94 1 : aosOptions.AddString("-dsco"); 95 1 : aosOptions.AddString(co.c_str()); 96 : } 97 17 : for (const auto &co : m_layerCreationOptions) 98 : { 99 3 : aosOptions.AddString("-lco"); 100 3 : aosOptions.AddString(co.c_str()); 101 : } 102 14 : if (!m_outputLayerName.empty()) 103 : { 104 2 : aosOptions.AddString("-nln"); 105 2 : aosOptions.AddString(m_outputLayerName.c_str()); 106 : } 107 14 : if (pfnProgress && pfnProgress != GDALDummyProgress) 108 : { 109 1 : aosOptions.AddString("-progress"); 110 : } 111 : 112 : // Must be last, as positional 113 15 : for (const auto &name : m_inputLayerNames) 114 : { 115 1 : aosOptions.AddString(name.c_str()); 116 : } 117 : 118 : std::unique_ptr<GDALVectorTranslateOptions, 119 : decltype(&GDALVectorTranslateOptionsFree)> 120 : psOptions(GDALVectorTranslateOptionsNew(aosOptions.List(), nullptr), 121 14 : GDALVectorTranslateOptionsFree); 122 14 : bool bOK = false; 123 14 : if (psOptions) 124 : { 125 14 : GDALVectorTranslateOptionsSetProgress(psOptions.get(), pfnProgress, 126 : pProgressData); 127 : GDALDatasetH hOutDS = 128 14 : GDALDataset::ToHandle(m_outputDataset.GetDatasetRef()); 129 : GDALDatasetH hSrcDS = 130 14 : GDALDataset::ToHandle(m_inputDataset.GetDatasetRef()); 131 14 : auto poRetDS = GDALDataset::FromHandle( 132 14 : GDALVectorTranslate(m_outputDataset.GetName().c_str(), hOutDS, 1, 133 14 : &hSrcDS, psOptions.get(), nullptr)); 134 14 : bOK = poRetDS != nullptr; 135 14 : if (!hOutDS) 136 : { 137 11 : m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS)); 138 : } 139 : } 140 : 141 28 : return bOK; 142 : } 143 : 144 : //! @endcond