關於GDAL180中文路徑不能開啟的問題分析與解決

pamxy發表於2013-04-13

轉自:http://blog.csdn.net/liminlu0314/article/details/6610069

GDAL1.8.0釋出很久了,一直沒有將自己的工程中的版本更新到1.80。今天將其更新到1.80發現含有中文路徑的檔案都不能開啟了,影像和向量檔案都是。仔細對比了GDAL1.72和GDAL1.80的程式碼,終於發現了問題的所在之處,詳細程式碼在GDAL_HOME\port\cpl_vsil_win32.cpp檔案中的類VSIWin32FilesystemHandler中,以Stat()函式為例(435行),其他函式類似。程式碼如下:
       GDAL1.8.0程式碼(部分):
  1. /************************************************************************/  
  2. /*                                Stat()                                */  
  3. /************************************************************************/  
  4. int VSIWin32FilesystemHandler::Stat( const char * pszFilename,   
  5.                                      VSIStatBufL * pStatBuf,  
  6.                                      int nFlags )  
  7. {  
  8.     (void) nFlags;  
  9.   
  10. #if (defined(WIN32) && _MSC_VER >= 1310) || __MSVCRT_VERSION__ >= 0x0601  
  11.     if( CSLTestBoolean(  
  12.             CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8""YES" ) ) )  
  13.     {  
  14.         int nResult;  
  15.         wchar_t *pwszFilename =   
  16.             CPLRecodeToWChar( pszFilename, CPL_ENC_UTF8, CPL_ENC_UCS2 );  
  17.   
  18.         nResult = _wstat64( pwszFilename, pStatBuf );  
  19.         CPLFree( pwszFilename );  
  20.   
  21.         return nResult;  
  22.     }  
  23.     else  
  24. #endif  
  25.     {  
  26.         return( VSI_STAT64( pszFilename, pStatBuf ) );  
  27.     }  
  28. }  
GDAL1.7.2程式碼(部分):
  1. /************************************************************************/  
  2. /*                                Stat()                                */  
  3. /************************************************************************/  
  4. int VSIWin32FilesystemHandler::Stat( const char * pszFilename,   
  5.                                      VSIStatBufL * pStatBuf )  
  6. {  
  7.     return( VSI_STAT64( pszFilename, pStatBuf ) );  
  8. }  
     通過上面的程式碼對比,就會看到,原來在函式中新增了一個CPLGetConfigOption( "GDAL_FILENAME_IS_UTF8", "YES" )判斷,通過判斷是否是UTF8的編碼,而且指定的預設值還是UTF8編碼,在含有中文路徑的字串大多數的編碼應該是GBK的編碼,這樣,系統就將GBK的編碼當做UTF8的編碼來進行轉換,結果就是漢字全部是亂碼,導致的結果就是找不到檔案,所以打不開。

     知道原因,那麼解決的方式就知道了,大概有下面幾種,各有優劣,供大家選擇
     1:不改變GDAL原始碼,在自己呼叫GDALRegisterAll()和OGRAllRegiser()函式後,加上下面一句即可。
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
這樣的優點是,不用改動GDAL的原始碼,但是如果自己的工程中經常開啟影象的話,每次都要加,比較麻煩。
    2:修改GDAL原始碼,將下面一句
    CPLSetConfigOption("GDAL_FILENAME_IS_UTF8","NO");
分別新增到GDALAllRegister()函式【GDAL_HOME\frmts\gdalallregister.cpp73行左右】和OGRRegisterAll()函式【GDAL_HOME\ogr\ogrsf_frmts\generic\ogrregisterall.cpp38行左右】中,然後重新編譯GDAL即可。這樣的方式就和使用以前版本的GDAL一樣了,不用改動自己的程式碼,推薦使用這種方式。
3:修改GDAL原始碼,GDAL_HOME\port\cpl_vsil_win32.cpp檔案中的全部去掉CPLGetConfigOption全部去掉,或者將後面的YES改為NO,但是該工作量巨大,而且有好多地方,這種方式不推薦。

      希望對那些還在為GDAL180中文路徑亂碼糾結的人們有所幫助。尤其是看到好多人在外面先把中文路徑轉成utf8的編碼,然後再呼叫GDAL的函式。


相關文章