From a6bd2c0897a626f4d6d7fb585324361019fb73cd Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 26 Jun 2024 22:25:08 +0200 Subject: [PATCH] LIBKML: fix writing a .kmz to cloud storage Fixes #10313 --- autotest/ogr/ogr_libkml.py | 11 +++++++++ .../libkml/ogrlibkmldatasource.cpp | 24 ++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) diff --git a/autotest/ogr/ogr_libkml.py b/autotest/ogr/ogr_libkml.py index 28608e370283..f92ba78c1822 100755 --- a/autotest/ogr/ogr_libkml.py +++ b/autotest/ogr/ogr_libkml.py @@ -455,6 +455,17 @@ def test_ogr_libkml_write_kmz_use_doc_off(tmp_vsimem): ogr_libkml_check_write(tmp_vsimem / "libkml_use_doc_off.kmz") +def test_ogr_libkml_write_kmz_simulate_cloud(tmp_vsimem): + with gdal.config_option("CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE", "FORCED"): + ogr_libkml_write(tmp_vsimem / "test_ogr_libkml_write_kmz_simulate_cloud.kmz") + + ogr_libkml_check_write(tmp_vsimem / "test_ogr_libkml_write_kmz_simulate_cloud.kmz") + + with gdal.config_option("CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE", "FORCED"): + with pytest.raises(Exception): + ogr_libkml_write("/i_do/not/exist.kmz") + + ############################################################################### # Test reading attributes with XML content in them # diff --git a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp index ac600fe32475..5cf1c16b394e 100644 --- a/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp +++ b/ogr/ogrsf_frmts/libkml/ogrlibkmldatasource.cpp @@ -412,7 +412,16 @@ static KmlPtr OGRLIBKMLCreateOGCKml22(KmlFactory *poFactory, bool OGRLIBKMLDataSource::WriteKmz() { - void *hZIP = CPLCreateZip(m_pszName, nullptr); + std::string osTmpFilename; + if (!VSISupportsRandomWrite(m_pszName, false) || + EQUAL(CPLGetConfigOption("CPL_VSIL_USE_TEMP_FILE_FOR_RANDOM_WRITE", ""), + "FORCED")) + { + osTmpFilename = CPLGenerateTempFilename(CPLGetBasename(m_pszName)); + } + + void *hZIP = CPLCreateZip( + osTmpFilename.empty() ? m_pszName : osTmpFilename.c_str(), nullptr); if (!hZIP) { @@ -536,6 +545,19 @@ bool OGRLIBKMLDataSource::WriteKmz() } CPLCloseZip(hZIP); + + if (!osTmpFilename.empty()) + { + if (bRet) + { + bRet = CPLCopyFile(m_pszName, osTmpFilename.c_str()) == 0; + if (!bRet) + CPLError(CE_Failure, CPLE_FileIO, + "Cannot copy temporary file to %s", m_pszName); + } + VSIUnlink(osTmpFilename.c_str()); + } + return bRet; }