Skip to content

Commit 114588f

Browse files
committed
OpenFileGDB: add 'gdal driver openfilegdb repack'
1 parent 4d4a67a commit 114588f

File tree

4 files changed

+122
-0
lines changed

4 files changed

+122
-0
lines changed

autotest/ogr/ogr_openfilegdb_write.py

+42
Original file line numberDiff line numberDiff line change
@@ -4601,3 +4601,45 @@ def test_ogr_openfilegdb_write_check_golden_file(tmp_path, src_directory):
46014601
assert (
46024602
open(src_filename, "rb").read() == open(out_filename, "rb").read()
46034603
), filename
4604+
4605+
4606+
###############################################################################
4607+
# Test 'gdal driver openfilegdb repack'
4608+
4609+
4610+
@gdaltest.enable_exceptions()
4611+
def test_ogropenfilegdb_write_gdal_driver_openfilegdb_repack(tmp_path):
4612+
4613+
alg = gdal.GetGlobalAlgorithmRegistry()["driver"]
4614+
assert alg.GetName() == "driver"
4615+
4616+
alg = gdal.GetGlobalAlgorithmRegistry()["driver"]["openfilegdb"]
4617+
assert alg.GetName() == "openfilegdb"
4618+
4619+
out_directory = str(tmp_path / "test.gdb")
4620+
gdal.VectorTranslate(
4621+
out_directory, "data/openfilegdb/polygon_golden.gdb", format="OpenFileGDB"
4622+
)
4623+
4624+
alg = gdal.GetGlobalAlgorithmRegistry()["driver"]["openfilegdb"]["repack"]
4625+
assert alg.GetName() == "repack"
4626+
alg["input"] = "data/poly.shp"
4627+
with pytest.raises(Exception, match="is not a FileGeoDatabase"):
4628+
alg.Run()
4629+
4630+
alg = gdal.GetGlobalAlgorithmRegistry()["driver"]["openfilegdb"]["repack"]
4631+
assert alg.GetName() == "repack"
4632+
alg["input"] = out_directory
4633+
assert alg.Run()
4634+
4635+
last_pct = [0]
4636+
4637+
def my_progress(pct, msg, user_data):
4638+
last_pct[0] = pct
4639+
return True
4640+
4641+
alg = gdal.GetGlobalAlgorithmRegistry()["driver"]["openfilegdb"]["repack"]
4642+
assert alg.GetName() == "repack"
4643+
alg["input"] = out_directory
4644+
assert alg.Run(my_progress)
4645+
assert last_pct[0] == 1.0

ogr/ogrsf_frmts/openfilegdb/ogr_openfilegdb.h

+5
Original file line numberDiff line numberDiff line change
@@ -519,6 +519,11 @@ class OGROpenFileGDBDataSource final : public GDALDataset
519519

520520
virtual CPLErr FlushCache(bool bAtClosing = false) override;
521521

522+
std::vector<std::unique_ptr<OGROpenFileGDBLayer>> &GetLayers()
523+
{
524+
return m_apoLayers;
525+
}
526+
522527
virtual int GetLayerCount() override
523528
{
524529
return static_cast<int>(m_apoLayers.size());

ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdriver.cpp

+73
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "cpl_vsi.h"
2222
#include "gdal.h"
2323
#include "gdal_priv.h"
24+
#include "gdalalgorithm.h"
2425
#include "ogr_core.h"
2526

2627
// g++ -O2 -Wall -Wextra -g -shared -fPIC ogr/ogrsf_frmts/openfilegdb/*.cpp
@@ -149,6 +150,77 @@ static CPLErr OGROpenFileGDBDriverDelete(const char *pszFilename)
149150
return CE_None;
150151
}
151152

153+
/************************************************************************/
154+
/* OpenFileGDBRepackAlgorithm */
155+
/************************************************************************/
156+
157+
class OpenFileGDBRepackAlgorithm final : public GDALAlgorithm
158+
{
159+
public:
160+
OpenFileGDBRepackAlgorithm()
161+
: GDALAlgorithm("repack", std::string("Repack a FileGDB dataset"),
162+
"/drivers/vector/openfilegdb.html")
163+
{
164+
AddProgressArg();
165+
AddInputDatasetArg(&m_dataset,
166+
GDAL_OF_RASTER | GDAL_OF_VECTOR | GDAL_OF_UPDATE);
167+
}
168+
169+
protected:
170+
bool RunImpl(GDALProgressFunc pfnProgress, void *pProgressData) override
171+
{
172+
auto poDS =
173+
dynamic_cast<OGROpenFileGDBDataSource *>(m_dataset.GetDatasetRef());
174+
if (!poDS)
175+
{
176+
ReportError(CE_Failure, CPLE_AppDefined,
177+
"%s is not a FileGeoDatabase",
178+
m_dataset.GetName().c_str());
179+
return false;
180+
}
181+
bool bSuccess = true;
182+
int iLayer = 0;
183+
for (auto &poLayer : poDS->GetLayers())
184+
{
185+
void *pScaledData = GDALCreateScaledProgress(
186+
static_cast<double>(iLayer) / poDS->GetLayerCount(),
187+
static_cast<double>(iLayer + 1) / poDS->GetLayerCount(),
188+
pfnProgress, pProgressData);
189+
const bool bRet = poLayer->Repack(
190+
pScaledData ? GDALScaledProgress : nullptr, pScaledData);
191+
GDALDestroyScaledProgress(pScaledData);
192+
if (!bRet)
193+
{
194+
ReportError(CE_Failure, CPLE_AppDefined,
195+
"Repack of layer %s failed", poLayer->GetName());
196+
bSuccess = false;
197+
}
198+
++iLayer;
199+
}
200+
return bSuccess;
201+
}
202+
203+
private:
204+
GDALArgDatasetValue m_dataset{};
205+
};
206+
207+
/************************************************************************/
208+
/* OGROpenFileGDBInstantiateAlgorithm() */
209+
/************************************************************************/
210+
211+
static GDALAlgorithm *
212+
OGROpenFileGDBInstantiateAlgorithm(const std::vector<std::string> &aosPath)
213+
{
214+
if (aosPath.size() == 1 && aosPath[0] == "repack")
215+
{
216+
return std::make_unique<OpenFileGDBRepackAlgorithm>().release();
217+
}
218+
else
219+
{
220+
return nullptr;
221+
}
222+
}
223+
152224
/***********************************************************************/
153225
/* RegisterOGROpenFileGDB() */
154226
/***********************************************************************/
@@ -168,6 +240,7 @@ void RegisterOGROpenFileGDB()
168240
poDriver->pfnOpen = OGROpenFileGDBDriverOpen;
169241
poDriver->pfnCreate = OGROpenFileGDBDriverCreate;
170242
poDriver->pfnDelete = OGROpenFileGDBDriverDelete;
243+
poDriver->pfnInstantiateAlgorithm = OGROpenFileGDBInstantiateAlgorithm;
171244

172245
GetGDALDriverManager()->RegisterDriver(poDriver);
173246
}

ogr/ogrsf_frmts/openfilegdb/ogropenfilegdbdrivercore.cpp

+2
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,8 @@ void OGROpenFileGDBDriverSetCommonMetadata(GDALDriver *poDriver)
306306
poDriver->pfnIdentify = OGROpenFileGDBDriverIdentify;
307307
poDriver->SetMetadataItem(GDAL_DCAP_OPEN, "YES");
308308
poDriver->SetMetadataItem(GDAL_DCAP_CREATE, "YES");
309+
310+
poDriver->DeclareAlgorithm({"repack"});
309311
}
310312

311313
/************************************************************************/

0 commit comments

Comments
 (0)