Skip to content

Commit d15cef8

Browse files
authored
Merge pull request #14129 from rouault/fix_13931
ogr2ogr/gdal vector convert: warn about no support for curve/Z/M geometries by the output driver, unless --quiet is enabled
2 parents 92b7c78 + b34b1e0 commit d15cef8

File tree

16 files changed

+215
-4
lines changed

16 files changed

+215
-4
lines changed

.github/workflows/ubuntu_24.04/reference_arg_names.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,7 @@ profile
248248
promote-pixel-value-to-z
249249
propagate-nodata
250250
quadrant-segments
251+
quiet
251252
radius
252253
radius1
253254
radius2

apps/gdalalg_abstract_pipeline.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -481,7 +481,7 @@ bool GDALAbstractPipelineAlgorithm::ParseCommandLineArguments(
481481
m_progressBarRequested = true;
482482
continue;
483483
}
484-
if (arg == "--quiet")
484+
if (arg == "-q" || arg == "--quiet")
485485
{
486486
m_quiet = true;
487487
m_progressBarRequested = false;
@@ -2230,6 +2230,7 @@ bool GDALAbstractPipelineAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt)
22302230
step->m_stdout = true;
22312231
}
22322232
step->m_inputDatasetCanBeOmitted = false;
2233+
step->m_quiet = m_quiet;
22332234
if (!step->ValidateArguments() || !step->RunStep(stepCtxt))
22342235
{
22352236
ret = false;

apps/gdalalg_pipeline.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,7 @@ bool GDALPipelineStepAlgorithm::RunImpl(GDALProgressFunc pfnProgress,
388388
else
389389
{
390390
writeAlg->m_outputVRTCompatible = m_outputVRTCompatible;
391+
writeAlg->m_quiet = m_quiet;
391392

392393
std::vector<GDALArgDatasetValue> inputDataset(1);
393394
inputDataset[0].Set(m_outputDataset.GetDatasetRef());

apps/gdalalg_vector_write.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,10 @@ GDALVectorWriteAlgorithm::GDALVectorWriteAlgorithm()
3333
{
3434
AddVectorOutputArgs(/* hiddenForCLI = */ false,
3535
/* shortNameOutputLayerAllowed=*/true);
36+
37+
AddArg(GDAL_ARG_NAME_QUIET, 'q',
38+
_("Quiet mode (suppress warning messages)"), &m_quiet)
39+
.SetCategory(GAAC_COMMON);
3640
}
3741

3842
/************************************************************************/
@@ -259,6 +263,10 @@ bool GDALVectorWriteAlgorithm::RunStep(GDALPipelineStepRunContext &ctxt)
259263
{
260264
aosOptions.AddString("-skipfailures");
261265
}
266+
if (m_quiet)
267+
{
268+
aosOptions.AddString("-q");
269+
}
262270

263271
GDALDataset *poRetDS = nullptr;
264272
GDALDatasetH hOutDS =

apps/ogr2ogr_lib.cpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,6 +508,11 @@ struct TargetLayerInfo
508508
const char *m_pszGeomField = nullptr;
509509
std::vector<int> m_anDateTimeFieldIdx{};
510510
bool m_bSupportCurves = false;
511+
bool m_bSupportZ = false;
512+
bool m_bSupportM = false;
513+
bool m_bHasWarnedAboutCurves = false;
514+
bool m_bHasWarnedAboutZ = false;
515+
bool m_bHasWarnedAboutM = false;
511516
OGRArrowArrayStream m_sArrowArrayStream{};
512517

513518
void CheckSameCoordinateOperation() const;
@@ -5874,6 +5879,10 @@ SetupTargetLayer::Setup(OGRLayer *poSrcLayer, const char *pszNewLayerName,
58745879

58755880
psInfo->m_bSupportCurves =
58765881
CPL_TO_BOOL(poDstLayer->TestCapability(OLCCurveGeometries));
5882+
psInfo->m_bSupportZ =
5883+
CPL_TO_BOOL(poDstLayer->TestCapability(OLCZGeometries));
5884+
psInfo->m_bSupportM =
5885+
CPL_TO_BOOL(poDstLayer->TestCapability(OLCMeasuredGeometries));
58775886

58785887
psInfo->m_sArrowArrayStream = std::move(streamSrc);
58795888

@@ -7329,6 +7338,41 @@ bool LayerTranslator::Translate(
73297338
}
73307339
}
73317340

7341+
if (poDstGeometry && !psOptions->bQuiet)
7342+
{
7343+
if (!psInfo->m_bHasWarnedAboutCurves &&
7344+
!psInfo->m_bSupportCurves &&
7345+
OGR_GT_IsNonLinear(poDstGeometry->getGeometryType()))
7346+
{
7347+
CPLError(CE_Warning, CPLE_AppDefined,
7348+
"Attempt to write curve geometries to layer "
7349+
"%s that does not support them. They will be "
7350+
"linearized",
7351+
poDstLayer->GetDescription());
7352+
psInfo->m_bHasWarnedAboutCurves = true;
7353+
}
7354+
if (!psInfo->m_bHasWarnedAboutZ && !psInfo->m_bSupportZ &&
7355+
OGR_GT_HasZ(poDstGeometry->getGeometryType()))
7356+
{
7357+
CPLError(CE_Warning, CPLE_AppDefined,
7358+
"Attempt to write Z geometries to layer %s "
7359+
"that does not support them. Z component will "
7360+
"be discarded",
7361+
poDstLayer->GetDescription());
7362+
psInfo->m_bHasWarnedAboutZ = true;
7363+
}
7364+
if (!psInfo->m_bHasWarnedAboutM && !psInfo->m_bSupportM &&
7365+
OGR_GT_HasM(poDstGeometry->getGeometryType()))
7366+
{
7367+
CPLError(CE_Warning, CPLE_AppDefined,
7368+
"Attempt to write M geometries to layer %s "
7369+
"that does not support them. M component will "
7370+
"be discarded",
7371+
poDstLayer->GetDescription());
7372+
psInfo->m_bHasWarnedAboutM = true;
7373+
}
7374+
}
7375+
73327376
poDstFeature->SetGeomField(iGeom, std::move(poDstGeometry));
73337377
}
73347378

autotest/utilities/test_gdalalg_vector_convert.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -505,3 +505,57 @@ def test_error_message_leak(tmp_vsimem):
505505
out_path,
506506
],
507507
)
508+
509+
510+
###############################################################################
511+
512+
513+
@pytest.mark.require_driver("GeoJSON")
514+
@pytest.mark.parametrize("quiet", [True, False])
515+
def test_gdalalg_vector_convert_warn_no_curve_support(tmp_vsimem, quiet):
516+
517+
src_ds = gdal.GetDriverByName("MEM").CreateVector("")
518+
src_lyr = src_ds.CreateLayer("test")
519+
f = ogr.Feature(src_lyr.GetLayerDefn())
520+
f.SetGeometry(ogr.CreateGeometryFromWkt("CIRCULARSTRING(0 0,1 1,2 0)"))
521+
src_lyr.CreateFeature(f)
522+
523+
if quiet:
524+
with gdaltest.error_raised(gdal.CE_None):
525+
gdal.alg.vector.convert(
526+
input=src_ds, output=tmp_vsimem / "out.geojson", quiet=True
527+
)
528+
else:
529+
with gdaltest.error_raised(
530+
gdal.CE_Warning, match="Attempt to write curve geometries"
531+
):
532+
gdal.alg.vector.convert(input=src_ds, output=tmp_vsimem / "out.geojson")
533+
534+
535+
###############################################################################
536+
537+
538+
@pytest.mark.require_driver("GeoJSON")
539+
@pytest.mark.parametrize("quiet", [True, False])
540+
def test_gdalalg_vector_convert_pipeline_warn_no_curve_support(tmp_vsimem, quiet):
541+
542+
src_ds = gdal.GetDriverByName("MEM").CreateVector("")
543+
src_lyr = src_ds.CreateLayer("test")
544+
f = ogr.Feature(src_lyr.GetLayerDefn())
545+
f.SetGeometry(ogr.CreateGeometryFromWkt("CIRCULARSTRING(0 0,1 1,2 0)"))
546+
src_lyr.CreateFeature(f)
547+
548+
if quiet:
549+
with gdaltest.error_raised(gdal.CE_None):
550+
gdal.alg.vector.pipeline(
551+
input=src_ds,
552+
pipeline=f'read ! write {tmp_vsimem / "out.geojson"}',
553+
quiet=True,
554+
)
555+
else:
556+
with gdaltest.error_raised(
557+
gdal.CE_Warning, match="Attempt to write curve geometries"
558+
):
559+
gdal.alg.vector.pipeline(
560+
input=src_ds, pipeline=f'read ! write {tmp_vsimem / "out.geojson"}'
561+
)

autotest/utilities/test_ogr2ogr_lib.py

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3481,3 +3481,83 @@ def test_ogr2ogr_lib_create_field_failure(tmp_vsimem):
34813481
layerName="test",
34823482
skipFailures=True,
34833483
)
3484+
3485+
3486+
###############################################################################
3487+
3488+
3489+
@pytest.mark.require_driver("GeoJSON")
3490+
@pytest.mark.parametrize("quiet", [True, False])
3491+
def test_ogr2ogr_lib_warn_no_curve_support(tmp_vsimem, quiet):
3492+
3493+
src_ds = gdal.GetDriverByName("MEM").CreateVector("")
3494+
src_lyr = src_ds.CreateLayer("test")
3495+
f = ogr.Feature(src_lyr.GetLayerDefn())
3496+
f.SetGeometry(ogr.CreateGeometryFromWkt("CIRCULARSTRING(0 0,1 1,2 0)"))
3497+
src_lyr.CreateFeature(f)
3498+
f = ogr.Feature(src_lyr.GetLayerDefn())
3499+
f.SetGeometry(ogr.CreateGeometryFromWkt("CIRCULARSTRING(0 0,1 1,2 0)"))
3500+
src_lyr.CreateFeature(f)
3501+
3502+
if quiet:
3503+
with gdaltest.error_raised(gdal.CE_None):
3504+
gdal.VectorTranslate(tmp_vsimem / "out.geojson", src_ds, quiet=True)
3505+
else:
3506+
with gdaltest.error_raised(
3507+
gdal.CE_Warning, match="Attempt to write curve geometries"
3508+
):
3509+
gdal.VectorTranslate(tmp_vsimem / "out.geojson", src_ds)
3510+
3511+
3512+
###############################################################################
3513+
3514+
3515+
@pytest.mark.require_driver("MapML")
3516+
@pytest.mark.parametrize("quiet", [True, False])
3517+
def test_ogr2ogr_lib_warn_no_Z_support(tmp_vsimem, quiet):
3518+
3519+
src_ds = gdal.GetDriverByName("MEM").CreateVector("")
3520+
src_lyr = src_ds.CreateLayer("test")
3521+
f = ogr.Feature(src_lyr.GetLayerDefn())
3522+
f.SetGeometry(ogr.CreateGeometryFromWkt("POINT Z (1 2 3)"))
3523+
src_lyr.CreateFeature(f)
3524+
f = ogr.Feature(src_lyr.GetLayerDefn())
3525+
f.SetGeometry(ogr.CreateGeometryFromWkt("POINT Z (1 2 3)"))
3526+
src_lyr.CreateFeature(f)
3527+
3528+
if quiet:
3529+
with gdaltest.error_raised(gdal.CE_None):
3530+
gdal.VectorTranslate(
3531+
tmp_vsimem / "out.mapml", src_ds, format="MAPML", quiet=True
3532+
)
3533+
else:
3534+
with gdaltest.error_raised(
3535+
gdal.CE_Warning, match="Attempt to write Z geometries"
3536+
):
3537+
gdal.VectorTranslate(tmp_vsimem / "out.mapml", src_ds, format="MAPML")
3538+
3539+
3540+
###############################################################################
3541+
3542+
3543+
@pytest.mark.require_driver("GeoJSON")
3544+
@pytest.mark.parametrize("quiet", [True, False])
3545+
def test_ogr2ogr_lib_warn_no_M_support(tmp_vsimem, quiet):
3546+
3547+
src_ds = gdal.GetDriverByName("MEM").CreateVector("")
3548+
src_lyr = src_ds.CreateLayer("test")
3549+
f = ogr.Feature(src_lyr.GetLayerDefn())
3550+
f.SetGeometry(ogr.CreateGeometryFromWkt("POINT M (1 2 3)"))
3551+
src_lyr.CreateFeature(f)
3552+
f = ogr.Feature(src_lyr.GetLayerDefn())
3553+
f.SetGeometry(ogr.CreateGeometryFromWkt("POINT M (1 2 3)"))
3554+
src_lyr.CreateFeature(f)
3555+
3556+
if quiet:
3557+
with gdaltest.error_raised(gdal.CE_None):
3558+
gdal.VectorTranslate(tmp_vsimem / "out.geojson", src_ds, quiet=True)
3559+
else:
3560+
with gdaltest.error_raised(
3561+
gdal.CE_Warning, match="Attempt to write M geometries"
3562+
):
3563+
gdal.VectorTranslate(tmp_vsimem / "out.geojson", src_ds)
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.. option:: -q, --quiet
2+
3+
Suppress progress bar and some warning messages.

doc/source/programs/gdal_raster_convert.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ Standard Options
4040

4141
.. include:: gdal_options/overwrite.rst
4242

43+
.. include:: gdal_options/quiet.rst
44+
4345
.. Return status code
4446
.. ------------------
4547

doc/source/programs/gdal_raster_reproject.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ Standard Options
213213

214214
.. include:: gdal_options/overwrite.rst
215215

216+
.. include:: gdal_options/quiet.rst
216217

217218
Nodata / source validity mask handling
218219
--------------------------------------

0 commit comments

Comments
 (0)