Skip to content

Commit 7a49c59

Browse files
committed
OpenFileGDB: add 'gdal driver openfilegdb repack'
1 parent 77fa762 commit 7a49c59

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-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

+70
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,74 @@ 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+
if (!poLayer->Repack())
186+
{
187+
ReportError(CE_Failure, CPLE_AppDefined,
188+
"Repack of layer %s failed", poLayer->GetName());
189+
bSuccess = false;
190+
}
191+
++iLayer;
192+
if (pfnProgress && !pfnProgress(static_cast<double>(iLayer) /
193+
poDS->GetLayerCount(),
194+
"", pProgressData))
195+
return false;
196+
}
197+
return bSuccess;
198+
}
199+
200+
private:
201+
GDALArgDatasetValue m_dataset{};
202+
};
203+
204+
/************************************************************************/
205+
/* OGROpenFileGDBInstantiateAlgorithm() */
206+
/************************************************************************/
207+
208+
static GDALAlgorithm *
209+
OGROpenFileGDBInstantiateAlgorithm(const std::vector<std::string> &aosPath)
210+
{
211+
if (aosPath.size() == 1 && aosPath[0] == "repack")
212+
{
213+
return std::make_unique<OpenFileGDBRepackAlgorithm>().release();
214+
}
215+
else
216+
{
217+
return nullptr;
218+
}
219+
}
220+
152221
/***********************************************************************/
153222
/* RegisterOGROpenFileGDB() */
154223
/***********************************************************************/
@@ -168,6 +237,7 @@ void RegisterOGROpenFileGDB()
168237
poDriver->pfnOpen = OGROpenFileGDBDriverOpen;
169238
poDriver->pfnCreate = OGROpenFileGDBDriverCreate;
170239
poDriver->pfnDelete = OGROpenFileGDBDriverDelete;
240+
poDriver->pfnInstantiateAlgorithm = OGROpenFileGDBInstantiateAlgorithm;
171241

172242
GetGDALDriverManager()->RegisterDriver(poDriver);
173243
}

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)