Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions swig/csharp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,8 @@ list(APPEND GDAL_SWIG_COMMON_INTERFACE_FILES
${PROJECT_SOURCE_DIR}/swig/include/csharp/ogr_csharp.i
${PROJECT_SOURCE_DIR}/swig/include/csharp/osr_csharp.i
${PROJECT_SOURCE_DIR}/swig/include/csharp/swig_csharp_extensions.i
${PROJECT_SOURCE_DIR}/swig/include/csharp/typemaps_csharp.i)
${PROJECT_SOURCE_DIR}/swig/include/csharp/typemaps_csharp.i
${PROJECT_SOURCE_DIR}/swig/include/csharp/csharp_strings.i)

# function for csharp wrapper build
function (gdal_csharp_wrap)
Expand All @@ -154,9 +155,10 @@ function (gdal_csharp_wrap)
COMMAND ${CMAKE_COMMAND} -E make_directory ${_CSHARP_WORKING_DIRECTORY}
# SWIG command
COMMAND
${SWIG_EXECUTABLE} -namespace ${_CSHARP_NAMESPACE} -outdir ${_CSHARP_WORKING_DIRECTORY} -DSWIG2_CSHARP -dllimport
${_CSHARP_WRAPPER} -Wall -I${PROJECT_SOURCE_DIR}/swig/include -I${PROJECT_SOURCE_DIR}/swig/include/csharp
-I${PROJECT_SOURCE_DIR}/gdal -c++ -csharp -o ${_CSHARP_WRAPPER}.cpp ${_CSHARP_SWIG_INTERFACE}
${SWIG_EXECUTABLE} -namespace ${_CSHARP_NAMESPACE} -outdir ${_CSHARP_WORKING_DIRECTORY} -DSWIG2_CSHARP
-DSWIG_CSHARP_NO_STRING_HELPER -dllimport ${_CSHARP_WRAPPER} -Wall -I${PROJECT_SOURCE_DIR}/swig/include
-I${PROJECT_SOURCE_DIR}/swig/include/csharp -I${PROJECT_SOURCE_DIR}/gdal -c++ -csharp -o ${_CSHARP_WRAPPER}.cpp
${_CSHARP_SWIG_INTERFACE}
WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
DEPENDS ${GDAL_SWIG_COMMON_INTERFACE_FILES} ${PROJECT_SOURCE_DIR}/swig/include/csharp/typemaps_csharp.i
${_CSHARP_SWIG_INTERFACE})
Expand Down Expand Up @@ -708,8 +710,12 @@ if (BUILD_TESTING)
${CMAKE_CURRENT_SOURCE_DIR}/apps/GDALTestUtf8.cs
DEPENDS
gdal_csharp
ogr_csharp
osr_csharp
SYSTEM_DEPENDS
OSGeo.GDAL)
OSGeo.GDAL
OSGeo.OGR
OSGeo.OSR)

gdal_build_csharp_sample(
OUTPUT
Expand Down
203 changes: 192 additions & 11 deletions swig/csharp/apps/GDALTestUtf8.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.IO;

using OSGeo.GDAL;
using OSGeo.OGR;
using OSGeo.OSR;

namespace testapp
{
Expand All @@ -12,18 +15,41 @@ class GdalTestUtf8
public static void Main()
{
Console.OutputEncoding = System.Text.Encoding.UTF8;
RunTest("ConfigOption", Gdal.GetConfigOption, Gdal.SetConfigOption);
RunTest("ThreadLocalConfigOption", Gdal.GetThreadLocalConfigOption, Gdal.SetThreadLocalConfigOption);
RunTest("ThreadLocalConfigOption", (k, d) => Gdal.GetPathSpecificOption("/", k, d), (k, v) => Gdal.SetPathSpecificOption("/", k, v));
RunTest("Credential", (k, d) => Gdal.GetCredential("/", k, d), (k, v) => Gdal.SetCredential("/", k, v));
Gdal.AllRegister();
TestOptionGettingAndSetting();
TestXMLNodeStrings();
TestUnicodeStringProperties();
TestStringsByReference();
TestUnicodeDatasetLayerName();
TestUnicodeFieldDefs();
TestUnicodeVrtFiles();
}

private static void RunTest(string name, Func<string, string, string> getter, Action<string, string> setter)
private static void AssertEqual(string expected, string actual, string funcName)
{
if (expected == actual)
{
Console.WriteLine($" {funcName} returned the expected value: '{expected ?? "NULL"}'");
}
else
{
throw new Exception($"Expected '{expected}' but {funcName} returned '{actual ?? "NULL"}'");
}
}
private static void TestOptionGettingAndSetting()
{
Console.WriteLine("Test setting, getting, and clearing Unicode string config options.");
TestOptionGettingAndSetting(nameof(Gdal.GetConfigOption), Gdal.GetConfigOption, Gdal.SetConfigOption);
TestOptionGettingAndSetting(nameof(Gdal.GetThreadLocalConfigOption), Gdal.GetThreadLocalConfigOption, Gdal.SetThreadLocalConfigOption);
TestOptionGettingAndSetting(nameof(Gdal.GetPathSpecificOption), (k, d) => Gdal.GetPathSpecificOption("/", k, d), (k, v) => Gdal.SetPathSpecificOption("/", k, v));
TestOptionGettingAndSetting(nameof(Gdal.GetCredential), (k, d) => Gdal.GetCredential("/", k, d), (k, v) => Gdal.SetCredential("/", k, v));
}
private static void TestOptionGettingAndSetting(string name, Func<string, string, string> getter, Action<string, string> setter)
{
Console.WriteLine($"Testing {name}");
Console.WriteLine($" Setting and getting Unicode string");
setter(ConfigKey, UnicodeString);
var configValue = getter(ConfigKey, null);
string configValue = getter(ConfigKey, null);
AssertEqual(UnicodeString, configValue, name);

Console.WriteLine($" Setting null value");
Expand All @@ -35,16 +61,171 @@ private static void RunTest(string name, Func<string, string, string> getter, Ac
configValue = getter(ConfigKey, UnicodeString);
AssertEqual(UnicodeString, configValue, name);
}
private static void TestXMLNodeStrings()
{
Console.WriteLine("Test creating and serializing XMLNode with Unicode strings.");
XMLNode node = new XMLNode(XMLNodeType.CXT_Element, "TestElement");
node.SetXMLValue(".", UnicodeString);
string serializedXml = node.SerializeXMLTree();
string expectedXml = $"<TestElement>{UnicodeString}</TestElement>";
AssertEqual(expectedXml, serializedXml?.TrimEnd('\n'), $"{nameof(XMLNode)}.{nameof(node.SerializeXMLTree)}");
}
private static void TestUnicodeStringProperties()
{
Console.WriteLine("Testing C# Property setting and getting with Unicode strings.");
GCP gcp = new GCP(0, 0, 0, 0, 0, UnicodeString, "Id");
AssertEqual(gcp.Info, UnicodeString, $"{nameof(GCP)}.{nameof(gcp.Info)}");
gcp.Id = UnicodeString;
AssertEqual(gcp.Id, UnicodeString, $"{nameof(GCP)}.{nameof(gcp.Id)}");
}
private static void TestStringsByReference()
{
Console.WriteLine("Testing 'out string' and 'ref string' parameters");
string wkText;
using (SpatialReference sr = new SpatialReference(null))
{
sr.ImportFromEPSG(4326); // WGS 84
sr.ExportToWkt(out wkText, null);
string name = sr.GetName();
int nameStart = wkText.IndexOf(name);
wkText = wkText.Substring(0, nameStart) + UnicodeString + wkText.Substring(nameStart + name.Length);
}

private static void AssertEqual(string expected, string actual, string funcName)
using (SpatialReference sr2 = new SpatialReference(null))
{
sr2.ImportFromWkt(ref wkText);
string name = sr2.GetName();
AssertEqual(UnicodeString, name, nameof(sr2.GetName));
sr2.ExportToWkt(out string wkTextImportExport, null);
AssertEqual(wkText, wkTextImportExport, $"{nameof(SpatialReference)}.{nameof(sr2.ExportToWkt)}");
}

}
private static void TestUnicodeDatasetLayerName()
{
if (expected == actual)
Console.WriteLine("Test Unicode layer names");
string fileName = UnicodeString + ".gdb";
if (File.Exists(fileName))
File.Delete(fileName);
using (OSGeo.OGR.Driver shpDriver = Ogr.GetDriverByName("OpenFileGDB"))
{
Console.WriteLine($" {funcName} returned the expected value: '{expected ?? "NULL"}'");
using (DataSource shpSrc = shpDriver.CreateDataSource(fileName, null))
shpSrc.CreateLayer("图层", null, wkbGeometryType.wkbPoint, null).Dispose();
}
else
using (DataSource shpSrc = Ogr.Open(fileName, 0))
{
throw new Exception($"Expected '{expected}' but {funcName} returned '{actual ?? "NULL"}'");
AssertEqual(fileName, shpSrc.GetName(), $"{nameof(DataSource)}.{nameof(shpSrc.GetName)}");
using (Layer shpLyr = shpSrc.GetLayerByName("图层"))
AssertEqual("图层", shpLyr.GetName(), $"{nameof(Layer)}.{nameof(shpSrc.GetName)}");
}
}
private static void TestUnicodeFieldDefs()
{
Console.WriteLine("Test Unicode Field Definitions");
string[] nameFieldValues = new string[]
{
"Drâ’ Berrani",
"Drâ’ Ali Ben Amar",
"图层",
UnicodeString,
};

string fileName = UnicodeString + ".shp";
if (File.Exists(fileName))
File.Delete(fileName);

using (OSGeo.OGR.Driver shpDriver = Ogr.GetDriverByName("ESRI Shapefile"))
{
using (DataSource shpSrc = shpDriver.CreateDataSource(fileName, null))
using (Layer shpLyr = shpSrc.CreateLayer(UnicodeString, null, wkbGeometryType.wkbPoint, new string[] { "ENCODING=UTF-8" }))
{
using (FeatureDefn layerDef = shpLyr.GetLayerDefn())
{
using (FieldDefn fieldDef = new FieldDefn("图层", FieldType.OFTString))
if (shpLyr.CreateField(fieldDef, 1) != 0)
throw new Exception("Failed to create a field definition on layer.");

foreach (string nameString in nameFieldValues)
{
using (Feature feature = new Feature(layerDef))
{
feature.SetField("图层", nameString);
if (shpLyr.CreateFeature(feature) != 0)
throw new Exception("Failed to create feature on layer.");
}
}
}
}
}
using (DataSource shpSrc = Ogr.Open(fileName, 0))
{
if (shpSrc == null)
throw new Exception($"Failed to open dataset: {shpSrc}");

Layer shpLyr = shpSrc.GetLayerByName(UnicodeString)
?? throw new Exception("Failed to get layer from shape file by name.");

int featureIndex = 0;
while (true) using (Feature namFeat = shpLyr.GetNextFeature())
{
if (namFeat == null)
break;

string fieldValue = namFeat.GetFieldAsString("图层");
AssertEqual(nameFieldValues[featureIndex++], fieldValue, $"{nameof(Layer)}.{nameof(shpSrc.GetName)}");
}
}
}
private static void TestUnicodeVrtFiles()
{
Console.WriteLine("Testing BuildVRT with Unicode filenames.");
string fileName1 = "File1 - " + UnicodeString + ".tif";
if (File.Exists(fileName1))
File.Delete(fileName1);

string fileName2 = "File2 - " + UnicodeString + ".tif";
if (File.Exists(fileName2))
File.Delete(fileName2);

string vrtFile = UnicodeString + ".vrt";
if (File.Exists(vrtFile))
File.Delete(vrtFile);

using (SpatialReference webMerc = new SpatialReference(""))
{
webMerc.ImportFromEPSG(3857);
using (OSGeo.GDAL.Driver tifDriver = Gdal.GetDriverByName("GTiff"))
{
using (Dataset ds1 = tifDriver.Create(fileName1, 100, 100, 3, DataType.GDT_Byte, null))
{
ds1.SetSpatialRef(webMerc);
ds1.SetGeoTransform(new double[] { 0, 1, 0, 0, 0, -1 });
}

using (Dataset ds2 = tifDriver.Create(fileName2, 100, 100, 3, DataType.GDT_Byte, null))
{
ds2.SetSpatialRef(webMerc);
ds2.SetGeoTransform(new double[] { 100, 1, 0, 0, 0, -1 });
}
}
}

Gdal.BuildVRT(vrtFile, new string[] { fileName1, fileName2 }, null, null, null).Dispose();
using (Dataset vrt = Gdal.Open(vrtFile, Access.GA_ReadOnly))
{
if (vrt.RasterXSize != 200)
throw new Exception($"Expected VRT width of 200, got {vrt.RasterXSize}");

if (vrt.RasterYSize != 100)
throw new Exception($"Expected VRT height of 100, got {vrt.RasterYSize}");

string[] list = vrt.GetFileList();
if (list.Length != 3)
throw new Exception($"Expected 3 files in VRT file list, got {list.Length}");

AssertEqual(vrtFile, list[0], $"{nameof(Dataset)}.{nameof(vrt.GetFileList)}()[0]");
AssertEqual(fileName1, list[1], $"{nameof(Dataset)}.{nameof(vrt.GetFileList)}()[1]");
AssertEqual(fileName2, list[2], $"{nameof(Dataset)}.{nameof(vrt.GetFileList)}()[2]");
}
}
}
Expand Down
Loading
Loading