【问题标题】:How to delete feature from shapefile using GDAL C++?如何使用 GDAL C++ 从 shapefile 中删除特征?
【发布时间】:2016-01-22 15:49:33
【问题描述】:

我使用的是 GDAL 2.0.0 版。

我有一个 C++ 程序,我想在其中从 shapefile 中删除一个特征。返回错误码表示删除成功。但是,该特征仍保留在 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 );
}

【问题讨论】:

  • 什么是pLayer?是不是打错字了?
  • 确实是一个错字。我修好了。

标签: c++ gdal shapefile


【解决方案1】:

我从一位同事那里学到了一些东西,它迫使功能删除保留在文件中。在我完成所有特征删除之后,在我关闭 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.
  ...

【讨论】:

  • 或者,它也可以调用GDALDataset::FlushCache(),而不是调用OGRLayer::SyncToDisk(),文档说它将在所有层上调用SyncToDisk()。我测试了这个替代方案,它也有效。
  • 如果你已经解决了问题,那么为什么不接受你的答案呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
相关资源
最近更新 更多