2015-10-23 34 views
10

Potrzebuję pomocy z GDAL. Wartość łańcucha z chińskimi symbolami nie jest poprawnie odczytana/zapisana (C#).GDAL GDALRATSetValueAsString() jak zapisać chińskie znaki (C#)?

Na wartość siatki LETNI używamy:
private static extern void GDALRATSetValueAsString (IntPtr uchwyt, int wiersz, int polu [W] [MarshalAs (UnmanagedType.LPStr)] wartość string); metoda (C#), aby zapisać wartość ciągu, wydaje się, że ta metoda zapisuje ciąg jako ANSI string.

do odczytu:

private static extern IntPtr GDALRATGetValueAsString(IntPtr handle, int row, int field); 

In. Przykład mój ciąg „银行 Flamwood C2” Nie jest dla metod, aby uzyskać wartości przez wskaźnik (zastosowanie w GDALRATGetValueAsString meto):

var pointer = GDALRATGetValueAsString(GDALRasterAttributeTableH, row, field); 
    a) var b = Marshal.PtrToStringUni(pointer);  // value: "㼿汆浡潷摯䌠2" 
    b) var a = Marshal.PtrToStringAnsi(pointer);  // value: "??Flamwood C2" 
    c) var c = Marshal.PtrToStringAuto(pointer);  // value: "㼿汆浡潷摯䌠2" 
    d) var d = Marshal.PtrToStringBSTR(pointer);  //Throws an error out of memory. 

P: W jaki sposób można uzyskać ciąg Unicode z został uratowany (tak mogę dostać za pomocą ten Marshal.PtrToStringUni (wskaźnik)) lub najprawdopodobniej jak zapisać ciąg Unicode do GDALRAT (GDAL RAT - GDAL Tabela atrybutów rastrowych)?

wersja GDAL: 1.11.1

Próbowałem ustawić charset = CharSet.Unicode ale id nie pomogło, wciąż nie prawidłowy ciąg:

[DllImport(GdalWrapper.GdalDLL, CallingConvention = CallingConvention.StdCall, CharSet = CharSet.Unicode)] 
private static extern void GDALRATSetValueAsString(IntPtr handle, int row, int field, [In][MarshalAs(UnmanagedType.LPStr)] string value); 

Dzięki za wszelką pomoc.

P.S. Jeśli pliki źródłowe GDAL muszą zostać ponownie skompilowane, aby zapisać ciąg jako ciąg znaków Unicode, to jakie parametry kompilacji i gdzie należy ustawić?

+1

Znaleziono ten link: https://trac.osgeo.org/gdal/wiki/rfc5_unicode. Być może jest to metoda łatwa (ten artykuł został napisany 5 lat temu ...)? – Drasius

+0

Utworzony bilet: https://trac.osgeo.org/gdal/ticket/6168#ticket – Drasius

+0

wkleić swoje rozwiązanie –

Odpowiedz

2

GDAL używa wewnętrznego kodowania UTF-8 podczas pracy z ciągami. Oznacza to, że ciągi muszą zostać przekonwertowane na UTF-8 przed przekazaniem ich do GDAL. To samo dotyczy ciągów wyjściowych GDAL - przed użyciem należy je przekonwertować z UTF-8 na kodowanie lokalne.

C# używa UTF-16 struny więc musi być wprowadzona do konwersji UTF-8 i tyłu:

public class EncodingConverter 
{ 
    public static string Utf16ToUtf8(string utf16String) 
    { 
     byte[] utf16Bytes = Encoding.Unicode.GetBytes(utf16String); 
     byte[] utf8Bytes = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, utf16Bytes); 
     return Encoding.Default.GetString(utf8Bytes); 
    } 

    public static string Utf8ToUtf16(string utf8String) 
    { 
     byte[] utf8Bytes = Encoding.Default.GetBytes(utf8String); 
     byte[] utf16Bytes = Encoding.Convert(Encoding.UTF8, Encoding.Unicode, utf8Bytes); 
     return Encoding.Unicode.GetString(utf16Bytes); 
    } 
} 

Wracając do Twojego problemu, japońskie znaki będą przetwarzane prawidłowo, jeśli zostaną zastosowane kodowania konwersji.

public void SetValueAsString(int row, int field, string value) 
    { 
     string utf8Value = EncodingConverter.Utf16ToUtf8(value); 
     GDALRATSetValueAsString(GDALRasterAttributeTableH, row, field, utf8Value); 
    } 

    public string GetValueAsString(int row, int field) 
    { 
     string value = null; 

     var pointer = GDALRATGetValueAsString(GDALRasterAttributeTableH, row, field); 
     if (pointer != IntPtr.Zero) 
     { 
      string utf8Value = Marshal.PtrToStringAnsi(pointer); 
      value = EncodingConverter.Utf8ToUtf16(utf8Value); 
     } 
     return value; 
    } 
0

Przeczytaj najpierw Specifying a Character Set. Upewnij się, że istnieje wersja GDALRATGetValueAsString w Unicode. Wersja Unicode kończy się na W, np. GDALRATGetValueAsStringW. Wersja ANSI kończy się na znaku A, np. GDALRATGetValueAsStringA. Jeśli importujesz GDALRATGetValueAsString, zestaw znaków jest automatyczny. Nie jest jasne, do której wersji funkcji się odwołujesz.

+1

Patrząc na API API C http: //www.gdal.org/gdal_8h.html wydaje się być ciągiem ANSI, który jest zwracany, ponieważ jest to const char *. Potrzebujesz funkcji owijającej, aby przekształcić ciąg ANSI w kod Unicode. Na przykład. MultiByteToWideChar https://msdn.microsoft.com/en-us/library/windows/desktop/dd319072(v=vs.85).aspx. –