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 30 : GDALVectorConvertAlgorithm::GDALVectorConvertAlgorithm( 30 30 : bool /* standaloneStep */) 31 30 : : GDALAlgorithm(NAME, DESCRIPTION, HELP_URL) 32 : { 33 30 : AddProgressArg(); 34 30 : AddOutputFormatArg(&m_outputFormat) 35 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, 36 90 : {GDAL_DCAP_VECTOR, GDAL_DCAP_CREATE}); 37 30 : AddOpenOptionsArg(&m_openOptions); 38 30 : AddInputFormatsArg(&m_inputFormats) 39 60 : .AddMetadataItem(GAAMDI_REQUIRED_CAPABILITIES, {GDAL_DCAP_VECTOR}); 40 30 : AddInputDatasetArg(&m_inputDataset, GDAL_OF_VECTOR); 41 30 : AddOutputDatasetArg(&m_outputDataset, GDAL_OF_VECTOR) 42 30 : .SetDatasetInputFlags(GADV_NAME | GADV_OBJECT); 43 30 : AddCreationOptionsArg(&m_creationOptions); 44 30 : AddLayerCreationOptionsArg(&m_layerCreationOptions); 45 30 : AddOverwriteArg(&m_overwrite); 46 30 : AddUpdateArg(&m_update); 47 30 : AddOverwriteLayerArg(&m_overwriteLayer); 48 30 : AddAppendLayerArg(&m_appendLayer); 49 60 : AddArg("input-layer", 'l', _("Input layer name(s)"), &m_inputLayerNames) 50 30 : .AddAlias("layer"); 51 60 : AddArg("output-layer", 0, _("Output layer name"), &m_outputLayerName) 52 30 : .AddHiddenAlias("nln"); // For ogr2ogr nostalgic people 53 : AddArg("skip-errors", 0, _("Skip errors when writing features"), 54 60 : &m_skipErrors) 55 30 : .AddHiddenAlias("skip-failures"); // For ogr2ogr nostalgic people 56 30 : } 57 : 58 : /************************************************************************/ 59 : /* GDALVectorConvertAlgorithm::RunImpl() */ 60 : /************************************************************************/ 61 : 62 15 : bool GDALVectorConvertAlgorithm::RunImpl(GDALProgressFunc pfnProgress, 63 : void *pProgressData) 64 : { 65 15 : CPLAssert(m_inputDataset.GetDatasetRef()); 66 : 67 30 : CPLStringList aosOptions; 68 15 : aosOptions.AddString("--invoked-from-gdal-vector-convert"); 69 15 : if (!m_overwrite) 70 : { 71 12 : aosOptions.AddString("--no-overwrite"); 72 : } 73 15 : if (m_overwriteLayer) 74 : { 75 1 : aosOptions.AddString("-overwrite"); 76 : } 77 15 : if (m_appendLayer) 78 : { 79 1 : aosOptions.AddString("-append"); 80 : } 81 15 : if (!m_outputFormat.empty()) 82 : { 83 6 : aosOptions.AddString("-of"); 84 6 : aosOptions.AddString(m_outputFormat.c_str()); 85 : } 86 16 : for (const auto &co : m_creationOptions) 87 : { 88 1 : aosOptions.AddString("-dsco"); 89 1 : aosOptions.AddString(co.c_str()); 90 : } 91 18 : for (const auto &co : m_layerCreationOptions) 92 : { 93 3 : aosOptions.AddString("-lco"); 94 3 : aosOptions.AddString(co.c_str()); 95 : } 96 15 : if (!m_outputLayerName.empty()) 97 : { 98 2 : aosOptions.AddString("-nln"); 99 2 : aosOptions.AddString(m_outputLayerName.c_str()); 100 : } 101 15 : if (pfnProgress && pfnProgress != GDALDummyProgress) 102 : { 103 1 : aosOptions.AddString("-progress"); 104 : } 105 15 : if (m_skipErrors) 106 : { 107 1 : aosOptions.AddString("-skipfailures"); 108 : } 109 : 110 : // Must be last, as positional 111 16 : for (const auto &name : m_inputLayerNames) 112 : { 113 1 : aosOptions.AddString(name.c_str()); 114 : } 115 : 116 : std::unique_ptr<GDALVectorTranslateOptions, 117 : decltype(&GDALVectorTranslateOptionsFree)> 118 : psOptions(GDALVectorTranslateOptionsNew(aosOptions.List(), nullptr), 119 15 : GDALVectorTranslateOptionsFree); 120 15 : bool bOK = false; 121 15 : if (psOptions) 122 : { 123 15 : GDALVectorTranslateOptionsSetProgress(psOptions.get(), pfnProgress, 124 : pProgressData); 125 : GDALDatasetH hOutDS = 126 15 : GDALDataset::ToHandle(m_outputDataset.GetDatasetRef()); 127 : GDALDatasetH hSrcDS = 128 15 : GDALDataset::ToHandle(m_inputDataset.GetDatasetRef()); 129 15 : auto poRetDS = GDALDataset::FromHandle( 130 15 : GDALVectorTranslate(m_outputDataset.GetName().c_str(), hOutDS, 1, 131 15 : &hSrcDS, psOptions.get(), nullptr)); 132 15 : bOK = poRetDS != nullptr; 133 15 : if (!hOutDS) 134 : { 135 12 : m_outputDataset.Set(std::unique_ptr<GDALDataset>(poRetDS)); 136 : } 137 : } 138 : 139 30 : return bOK; 140 : } 141 : 142 : //! @endcond