项目问题,遇到了一个shp文件读取乱码,于是自己写代码调试,踩坑不少,特此记录过程,供大家参考。
于是找到网上的代码GDAL之OGR入门:
#include "ogrsf_frmts.h"
int main()
{
OGRRegisterAll();
OGRDataSource *poDS;
poDS = OGRSFDriverRegistrar::Open( "point.shp", FALSE );
if( poDS == NULL )
{
printf( "Open failed.\n%s" );
exit( 1 );
}
OGRLayer *poLayer;
poLayer = poDS->GetLayerByName( "point" );
OGRFeature *poFeature;
poLayer->ResetReading();
while( (poFeature = poLayer->GetNextFeature()) != NULL )
{
OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
int iField;
for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
{
OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField );
if( poFieldDefn->GetType() == OFTInteger )
printf( "%d,", poFeature->GetFieldAsInteger( iField ) );
else if( poFieldDefn->GetType() == OFTReal )
printf( "%.3f,", poFeature->GetFieldAsDouble(iField) );
else if( poFieldDefn->GetType() == OFTString )
printf( "%s,", poFeature->GetFieldAsString(iField) );
else
printf( "%s,", poFeature->GetFieldAsString(iField) );
}
OGRGeometry *poGeometry;
poGeometry = poFeature->GetGeometryRef();
if( poGeometry != NULL
&& wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
{
OGRPoint *poPoint = (OGRPoint *) poGeometry;
printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
}
else
{
printf( "no point geometry\n" );
}
OGRFeature::DestroyFeature( poFeature );
}
OGRDataSource::DestroyDataSource( poDS );
}
然而vs提示没有成员Open函数,想必是GDAL更新了接口,于是继续寻找,总算找到了这篇GDAL2.x与1.x的主要变化比较(以C++为例说明),这才发现了新接口的使用办法,于是更改代码:
OGRRegisterAll();
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径
CPLSetConfigOption("SHAPE_ENCODING", ""); // 属性表字段支持中文
GDALDataset *poDS = (GDALDataset*) GDALOpenEx(stSrcPath.c_str(), GDAL_OF_VECTOR, NULL, NULL, NULL );
if( poDS == NULL )
{
printf( "Open failed.\n" );
exit( 1 );
}
OGRLayer *poLayer = poDS->GetLayerByName( "points" );
OGRFeature *poFeature;
poLayer->ResetReading();
while( (poFeature = poLayer->GetNextFeature()) != NULL )
{
OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn();
int iField;
for( iField = 0; iField < poFDefn->GetFieldCount(); iField++ )
{
OGRFieldDefn *poFieldDefn = poFDefn->GetFieldDefn( iField );
if( poFieldDefn->GetType() == OFTInteger )
printf( "%d,", poFeature->GetFieldAsInteger( iField ) );
else if( poFieldDefn->GetType() == OFTReal )
printf( "%.3f,", poFeature->GetFieldAsDouble(iField) );
else if( poFieldDefn->GetType() == OFTString )
AddItemToList(poFeature->GetFieldAsString(iField));
else
AddItemToList(poFeature->GetFieldAsString(iField));
}
OGRGeometry *poGeometry;
poGeometry = poFeature->GetGeometryRef();
if( poGeometry != NULL
&& wkbFlatten(poGeometry->getGeometryType()) == wkbPoint )
{
OGRPoint *poPoint = (OGRPoint *) poGeometry;
printf( "%.3f,%3.f\n", poPoint->getX(), poPoint->getY() );
}
else
{
printf( "no point geometry\n" );
}
OGRFeature::DestroyFeature( poFeature );
}
//关闭数据
GDALClose( poDS );
特别注意设置以下两点,否则会出现shp文件无法打开,或者打开后字段乱码的问题:
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); //设置支持中文路径
CPLSetConfigOption("SHAPE_ENCODING", ""); // 属性表字段支持中文
希望能够帮助到有需要的人。