如何使用 GDAL C++ 从 shapefile 中删除特征?
How to delete feature from shapefile using GDAL C++?
我使用的是 GDAL 2.0.0 版。
我有一个 C++ 程序,我想在其中从 shapefile 中删除一个要素。 return 错误码表示删除成功。但是,该特征保留在 shapefile 中。
是否有一些我必须调用的后续函数才能使删除持续存在?例如,当您更改现有功能的字段时,您必须随后再次调用 OGRLayer::SetFeature()
,否则更改不会持续。
以下是我正在做的事情的片段。 shapefile 是通过对栅格文件进行多边形化从头开始创建的。然后我尝试在关闭文件之前从该 shapefile 中删除一个特征。
#include <gdal_alg.h> // GDALPolygonize()
#include <gdal_priv.h>
//
// srcPath is the path of the soruce raster geospatial file. e.g., a GeoTIFF file.
// tgtPath is the path of the target vector geospatial file. i.e., a shapefile.
//
void test( char const * srcPath, char const * tgtPath )
{
GDALAllRegister();
// Open source file.
GDALDataset * pSrcDataset = static_cast<GDALDataset *>( GDALOpen( srcPath, GA_ReadOnly ) );
GDALRasterBand * pSrcBand = pSrcDataset->GetRasterBand( 1 );
// Create and open target file.
GDALDriver * pDriver = GetGDALDriverManager()->GetDriverByName( "ESRI Shapefile" );
GDALDataset * pTgtDataset = pDriver->Create( tgtPath, 0, 0, 0, GDT_Unknown, NULL );
// Create a layer.
OGRLayer * pTgtLayer = pTgtDataset->CreateLayer( "layer", NULL, wkbPolygon, NULL );
// Create a field to contain value associated with each polygon feature.
OGRFieldDefn field( "value", OFTInteger );
field.SetWidth( 6 );
pTgtLayer->CreateField( &field );
// Call GDALPolygonize to convert source raster to polygon features.
GDALRasterBand * pMaskBand = NULL;
int valueFieldIdx = 0;
char ** options = NULL;
GDALPolygonize(
pSrcBand,
pMaskBand,
pTgtLayer,
valueFieldIdx,
options,
GDALTermProgress, NULL );
// Demonstrate that the target layer has the capability to delete a feature.
if ( !pTgtLayer->TestCapability( OLCDeleteFeature ) )
{
throw "Layer does not support delete feature capability";
}
// Delete a feature that I know is there.
// The feature has a particular integer ID.
OGRErr err = pTgtLayer->DeleteFeature( 12 );
// Demonstrate that there is a zero error code, indicating successful deletion.
if ( err != OGRERR_NONE )
{
throw "Failed to remove feature";
}
// Close source and target files.
GDALClose( pSrcDataset );
GDALClose( pTgtDataset );
}
我从一位同事那里学到了一些东西,可以强制删除特征保留在文件中。在完成所有特征删除后,在关闭 shapefile 之前,我执行以下操作。
// Delete features.
...
// Flush pending changes.
pTgtLayer->SyncToDisk();
// Execute a SQL command.
// It is essential, to force my changes to take effect.
// As a side effect, it renumbers the features to fill in
// the gaps left by deleted features.
stringstream sql;
sql << "REPACK " << pTgtLayer->GetName();
pTgtDataset->ExecuteSQL( sql.str().c_str(), NULL, NULL );
// Close files.
...
我使用的是 GDAL 2.0.0 版。
我有一个 C++ 程序,我想在其中从 shapefile 中删除一个要素。 return 错误码表示删除成功。但是,该特征保留在 shapefile 中。
是否有一些我必须调用的后续函数才能使删除持续存在?例如,当您更改现有功能的字段时,您必须随后再次调用 OGRLayer::SetFeature()
,否则更改不会持续。
以下是我正在做的事情的片段。 shapefile 是通过对栅格文件进行多边形化从头开始创建的。然后我尝试在关闭文件之前从该 shapefile 中删除一个特征。
#include <gdal_alg.h> // GDALPolygonize()
#include <gdal_priv.h>
//
// srcPath is the path of the soruce raster geospatial file. e.g., a GeoTIFF file.
// tgtPath is the path of the target vector geospatial file. i.e., a shapefile.
//
void test( char const * srcPath, char const * tgtPath )
{
GDALAllRegister();
// Open source file.
GDALDataset * pSrcDataset = static_cast<GDALDataset *>( GDALOpen( srcPath, GA_ReadOnly ) );
GDALRasterBand * pSrcBand = pSrcDataset->GetRasterBand( 1 );
// Create and open target file.
GDALDriver * pDriver = GetGDALDriverManager()->GetDriverByName( "ESRI Shapefile" );
GDALDataset * pTgtDataset = pDriver->Create( tgtPath, 0, 0, 0, GDT_Unknown, NULL );
// Create a layer.
OGRLayer * pTgtLayer = pTgtDataset->CreateLayer( "layer", NULL, wkbPolygon, NULL );
// Create a field to contain value associated with each polygon feature.
OGRFieldDefn field( "value", OFTInteger );
field.SetWidth( 6 );
pTgtLayer->CreateField( &field );
// Call GDALPolygonize to convert source raster to polygon features.
GDALRasterBand * pMaskBand = NULL;
int valueFieldIdx = 0;
char ** options = NULL;
GDALPolygonize(
pSrcBand,
pMaskBand,
pTgtLayer,
valueFieldIdx,
options,
GDALTermProgress, NULL );
// Demonstrate that the target layer has the capability to delete a feature.
if ( !pTgtLayer->TestCapability( OLCDeleteFeature ) )
{
throw "Layer does not support delete feature capability";
}
// Delete a feature that I know is there.
// The feature has a particular integer ID.
OGRErr err = pTgtLayer->DeleteFeature( 12 );
// Demonstrate that there is a zero error code, indicating successful deletion.
if ( err != OGRERR_NONE )
{
throw "Failed to remove feature";
}
// Close source and target files.
GDALClose( pSrcDataset );
GDALClose( pTgtDataset );
}
我从一位同事那里学到了一些东西,可以强制删除特征保留在文件中。在完成所有特征删除后,在关闭 shapefile 之前,我执行以下操作。
// Delete features.
...
// Flush pending changes.
pTgtLayer->SyncToDisk();
// Execute a SQL command.
// It is essential, to force my changes to take effect.
// As a side effect, it renumbers the features to fill in
// the gaps left by deleted features.
stringstream sql;
sql << "REPACK " << pTgtLayer->GetName();
pTgtDataset->ExecuteSQL( sql.str().c_str(), NULL, NULL );
// Close files.
...