2014年11月6日木曜日

GDAL-1.11.1 における ShapeDriver の日本語設定

前回「GDAL-1.10.1 の日本語環境ではまった」からの続きです。 うまく行ったり、行かなかったりは、文字コードが UTF-8 だったり SJIS だったりと、判別のしようが無い Shape が混在していたのが大きな原因でした。 それで、定説の 環境変数
set SHAPE_ENCODING=LDID/19 
ですが、そこを解釈するコードは、このようになっております。
CPLString OGRShapeLayer::ConvertCodePage( const char *pszCodePage )

{
    CPLString osEncoding;
  osEncoding.Clear();

    if( pszCodePage == NULL )
        return osEncoding;

    if( EQUALN(pszCodePage,"LDID/",5) )
    {
        int nCP = -1; // windows code page. 

        //http://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTM
        switch( atoi(pszCodePage+5) )
        {
          case 1: nCP = 437;      break;
          case 2: nCP = 850;      break;
          case 3: nCP = 1252;     break;
          case 4: nCP = 10000;    break;
          case 8: nCP = 865;      break;
          case 10: nCP = 850;     break;
          case 11: nCP = 437;     break;
          case 13: nCP = 437;     break;
          case 14: nCP = 850;     break;
          case 15: nCP = 437;     break;
          case 16: nCP = 850;     break;
          case 17: nCP = 437;     break;
          case 18: nCP = 850;     break;
          case 19: nCP = 932;     break;
          case 20: nCP = 850;     break;
          case 21: nCP = 437;     break;
          case 22: nCP = 850;     break;
          case 23: nCP = 865;     break;
          case 24: nCP = 437;     break;
          case 25: nCP = 437;     break;
          case 26: nCP = 850;     break;
          case 27: nCP = 437;     break;
          case 28: nCP = 863;     break;
          case 29: nCP = 850;     break;
          case 31: nCP = 852;     break;
          case 34: nCP = 852;     break;
          case 35: nCP = 852;     break;
          case 36: nCP = 860;     break;
          case 37: nCP = 850;     break;
          case 38: nCP = 866;     break;
          case 55: nCP = 850;     break;
          case 64: nCP = 852;     break;
          case 77: nCP = 936;     break;
          case 78: nCP = 949;     break;
          case 79: nCP = 950;     break;
          case 80: nCP = 874;     break;
          case 87: return CPL_ENC_ISO8859_1;
          case 88: nCP = 1252;     break;
          case 89: nCP = 1252;     break;
          case 100: nCP = 852;     break;
          case 101: nCP = 866;     break;
          case 102: nCP = 865;     break;
          case 103: nCP = 861;     break;
          case 104: nCP = 895;     break;
          case 105: nCP = 620;     break;
          case 106: nCP = 737;     break;
          case 107: nCP = 857;     break;
          case 108: nCP = 863;     break;
          case 120: nCP = 950;     break;
          case 121: nCP = 949;     break;
          case 122: nCP = 936;     break;
          case 123: nCP = 932;     break;
          case 124: nCP = 874;     break;
          case 134: nCP = 737;     break;
          case 135: nCP = 852;     break;
          case 136: nCP = 857;     break;
          case 150: nCP = 10007;   break;
          case 151: nCP = 10029;   break;
          case 200: nCP = 1250;    break;
          case 201: nCP = 1251;    break;
          case 202: nCP = 1254;    break;
          case 203: nCP = 1253;    break;
          case 204: nCP = 1257;    break;
          default: break;
        }

        if( nCP != -1 )
        {
            osEncoding.Printf( "CP%d", nCP );
            return osEncoding;
        }
    }

    // From the CPG file
    // http://resources.arcgis.com/fr/content/kbase?fa=articleShow&d=21106
    
    if( (atoi(pszCodePage) >= 437 && atoi(pszCodePage) <= 950)
        || (atoi(pszCodePage) >= 1250 && atoi(pszCodePage) <= 1258) )
    {
        osEncoding.Printf( "CP%d", atoi(pszCodePage) );
        return osEncoding;
    }
    if( EQUALN(pszCodePage,"8859",4) )
    {
        if( pszCodePage[4] == '-' )
            osEncoding.Printf( "ISO-8859-%s", pszCodePage + 5 );
        else
            osEncoding.Printf( "ISO-8859-%s", pszCodePage + 4 );
        return osEncoding;
    }
    if( EQUALN(pszCodePage,"UTF-8",5) )
        return CPL_ENC_UTF8;

    // try just using the CPG value directly.  Works for stuff like Big5.
    return pszCodePage;
}
これのディスカッションは、ESRI社のフォーラムで話題になっていました。
コード中の解説ページhttp://www.autopark.ru/ASBProgrammerGuide/DBFSTRUC.HTMが詳しいです。
CP932 に相当するケース文の値は、0x7B でなければなりませんから、10進数にしますと、123になります。上記コードと照らしあわせても整合がとれていますよね? という事で、LDID/19 でもOKなのですが、
set SHAPE_ENCODING=LDID/123 
を設定すると、CP932 に変換してくれる。
もしくは、最初から CP932 を指定していれば、LDID/の変換をパスして、上記関数を通った後の値が評価されるので
set SHAPE_ENCODING=CP932 
でもOKだったという事になるのでしょうか? 拡張子 DBF ファイルの 29バイト目に、case 文の値か、UTF-8なら -1 == 65535 == 0xFFFF を設定するように改善していけば良さそうですよね?
と、思ったら、-1 は CPACP 扱い? int は 32bit 以上で、65535 == 0xFFFF の解釈で考えればOKでしょうか? 同日追記:  実は SHAPE_ENCODING= を設定しない方が、うまく動く場合もあるようです。どうも、前回DBFファイルに設定があった場合は、SHAPE_ENCODINGは使用されないような事を書きましたが、その記述が間違いだったみたいです。そして、SHAPE_ENCODING=UTF-8 と設定してみましたが、挙動が違うような・・・。もうちょい、突っ込んで調べてみます・・・

2014年11月4日火曜日

近況2014/11/4

 ご無沙汰してます。すっかりマネジメントの方に引っ張られてます。 この先どうなっていくかは、不透明な状態ではありますが、クラウドに関して一周した感があるので、それについて、つらつらと書いてみます。  勝者一人勝ちの世界、そこは揺るぎようがないとは思いますが、結局の所、企業というのは他社との差別化が無いと付加価値はありません。コストだけに価値があるわけではないので、クラウドに移行したからと言って、受託の領域が無くなるわけじゃないのかなぁと感じています。  クラウドのビジネスに乗り出して戦うには、体力が必要です。投資の得られたベンチャーならともかく、中小企業がそれをやるには、あまりにも厳しい。じゃあ、仕事はクラウドになって無くなるのか?と思ったら、クラウドのプラットフォームと関連づけられた付加価値という名のサブシステムは無くなりようがないんじゃないかと。受託の領域が無くならないと感じているのは、まさにここなんです。  以上、こんな事を考えてました。とは言え、自分自身、この先どう歩んでいくのか模索中です。