57海图数据中文属性值乱码问题解决(续)

上篇博文中的代码使用了函数wcstombs来进行处理,今天发现GDAL库里面提供了宽字节转单字节的函数,,名字叫CPLRecodeFromWChar(这个函数需要libiconv库的支持,也就是在编译GDAL的时候需要把libiconv库一起编译)。本以为C#语言也可以使用,结果很悲剧的发现,C#的提供的接口中没有相关的函数,看来使用C#的同学有点悲剧了。

需要说明的是,需要先用函数CPLRecodeFromWChar将宽字节转为UTF8,然后再使用函数CPLRecode将UTF8转为汉字编码(CP936)。

程序依旧是昨天的那个,函数全部换成GDAL的函数,代码如下:

int ReadS57() { CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "NO"); OGRRegisterAll();//打开数据 const char* pszS57 = "D:\\C1100102.000"; OGRDataSource *poDS = OGRSFDriverRegistrar::Open(pszS57, FALSE ); if( poDS == NULL ) {printf( "Open failed.\n" );return 1; }// 获取有中文属性值的图层 OGRLayer *poLayer = poDS->GetLayerByName( "BUAARE" ); if( poLayer == NULL ) {printf( "Get Layer failed.\n" );OGRDataSource::DestroyDataSource( poDS );return 1; }poLayer->ResetReading(); OGRFeature *poFeature = poLayer->GetNextFeature(); while (poFeature != NULL ) {OGRFeatureDefn *poFDefn = poLayer->GetLayerDefn(); //获取属性字段值// 为了演示说明,就只输出乱码的属性值 const char* pszAttValue = poFeature->GetFieldAsString("NOBJNM"); size_t size = strlen(pszAttValue);if (size != 0){char* pszValue = new char[size];memcpy(pszValue, pszAttValue, size);pszValue[size-1] = ‘\0’;char *pszGetUTF8 = CPLRecodeFromWChar( (const wchar_t*)pszValue, CPL_ENC_UCS2, CPL_ENC_UTF8);pszAttValue = CPLRecode( pszGetUTF8, CPL_ENC_UTF8, "");delete []pszValue;}printf("%s\n", pszAttValue);OGRFeature::DestroyFeature( poFeature );poFeature = poLayer->GetNextFeature(); }OGRDataSource::DestroyDataSource( poDS ); return 0; }下图是执行输出的结果,和使用QGIS打开对比。

通过上面的方式是可以解决这个问题,不过稍微有点麻烦,需要在每次获取属性值的时候都要进行判断。我们可以直接修改GDAL库中的代码,这样在读取的时候直接就是汉字编码。找了一下午,在GDAL库的源码中文件gdal-1.9.2\ogr\ogrsf_frmts\s57\s57reader.cpp行883左右,修改为下面:

// Add By liml 2013-04-25 Convert UCS-2 to Utf-8const char* pachBuffer = poRecord->GetStringSubfield("NATF",0,"ATVL",iAttr);if( EQUAL(pszAcronym, "NOBJNM")){size_t nLength = strlen(pachBuffer);char* pszValue = new char[nLength];memcpy(pszValue, pachBuffer, nLength);pszValue[nLength-1] = ‘\0’;char *pszGetUTF8 = CPLRecodeFromWChar( (const wchar_t*)pszValue, CPL_ENC_UCS2, CPL_ENC_UTF8);pachBuffer = CPLRecode( pszGetUTF8, CPL_ENC_UTF8, CPL_ENC_LOCALE);delete []pszValue;}// Add By liml 2013-04-25poFeature->SetField( pszAcronym, pachBuffer);下面是使用ogrinfo输出的对比情况,左边是没修改时输出的,右边是修改后输出的。

虽然这么修改是可以解决这个问题,但是不知道会不会引起其他的副作用。等发现了再修改吧。修改之后的GDAL库已经上传至我的资源中心,有需要的同学可以自行去下载。

于是,月醉了,夜醉了,我也醉了。

57海图数据中文属性值乱码问题解决(续)

相关文章:

你感兴趣的文章:

标签云: