Open benabdelkrim opened 4 years ago
please post the complete code you're testing, from this I don't see why the line highlighted can throw a "ArgumentNullException" actually. No similar "throws" in the source code
I suspect the error is in attributes dictionary...
Posting images of your VisualStudio instance is not useful.
Please set up a minimum working sample project for us to test your code.
string path;
string C_postal = "C_postal";
string Type_bat = "Type_bat";
string X_coord = "X_coord";
string Y_coord = "Y_coord";
//create geometry factory
GeometryFactory geomFactory = NtsGeometryServices.Instance.CreateGeometryFactory();
//create the default table with fields - alternately use DBaseField classes
AttributesTable attributes1 = new AttributesTable();
attributes1.Add(C_postal, "40050");
attributes1.Add(Type_bat, "Immeuble");
attributes1.Add(X_coord, "300000");
attributes1.Add(Y_coord, "5000000");
AttributesTable attributes2 = new AttributesTable();
attributes2.Add(C_postal, "40050");
attributes2.Add(Type_bat, "Using");
attributes2.Add(X_coord, "300200");
attributes2.Add(Y_coord, "5000300");
//create geometries and features
Geometry geometry1 = geomFactory.CreatePoint(new Coordinate(300000, 5000000));
Geometry geometry2 = geomFactory.CreatePoint(new Coordinate(300200, 5000300));
Feature feat1 = new Feature(geometry1, attributes1);
Feature feat2 = new Feature(geometry2, attributes2);
//create attribute list
IList
this code is working in application desktop c# but in Xamarin.forms not working, i don't know why ?
I'm still missing a project file, the code you posted is just a function. Now, to get to where you are at, we do have to put in effort to set up a project that uses Xamairn.Forms, that eventually invokes your code. Please provide a minimum working sample project for us to test your code.
thank you for find the code in this link https://www.swisstransfer.com/d/c1fda1a0-e909-4d7f-a992-e86e0970d66f
this code works in .net, I made small changes
string path;
string C_postal = "C_postal";
string Type_bat = "Type_bat";
string X_coord = "X_coord";
string Y_coord = "Y_coord";
//create geometry factory
var geomFactory = NtsGeometryServices.Instance.CreateGeometryFactory();
//create the default table with fields - alternately use DBaseField classes
var attributes1 = new AttributesTable();
attributes1.Add(C_postal, "40050");
attributes1.Add(Type_bat, "Immeuble");
attributes1.Add(X_coord, "300000");
attributes1.Add(Y_coord, "5000000");
var attributes2 = new AttributesTable();
attributes2.Add(C_postal, "40050");
attributes2.Add(Type_bat, "Using");
attributes2.Add(X_coord, "300200");
attributes2.Add(Y_coord, "5000300");
//create geometries and features
Geometry geometry1 = geomFactory.CreatePoint(new Coordinate(300000, 5000000));
Geometry geometry2 = geomFactory.CreatePoint(new Coordinate(300200, 5000300));
var feat1 = new Feature(geometry1, attributes1);
var feat2 = new Feature(geometry2, attributes2);
//create attribute list
var features = new List<IFeature>() { feat1, feat2 };
path = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "shape");
var writer = new ShapefileDataWriter(path);
writer.Header = ShapefileDataWriter.GetHeader(features[0], features.Count);
writer.Write(features);
it still the problem ! even i separate the Header ! var writer = new ShapefileDataWriter(path); writer.Header = ShapefileDataWriter.GetHeader(features[0], features.Count); Other thing this code is working in .NET but in xamarin.forms i have this problem
can you post the stack trace? can be helpful to investigate what is the method actually throwing the exception
The cause for this to fail is probably the failure of the initialization of NetTopologySuite.IO.DbaseEncodingUtility
.
Maybe some of the initial codepages are not available for Android?
Please I need to know if there's a solution to read/write a shapefile in Xamarin.forms. I really appreciate your help.
Thanks in advance.
oh, understood. Maybe you can try to initialize the writer using an explicit Encoding as the third parameter and see if it works
new ShapefileDataWriter(path, geomFactory, Encoding.UTF8) // or ASCII
BTW I'm trying to install Xamarin to do some tests... but it takes quite a time! Abd it's incredibly slow without Hyper-V acceleration (unavailable in my system...)
@FObermaier GetEncodingForCodePageIdentifier(437)
- French OEM - returns null
this code shall work but actually the write of the features fail...
ShapefileDataWriter writer = new ShapefileDataWriter(path, geomFactory, Encoding.Default);
writer.Header = ShapefileDataWriter.GetHeader(features[0], features.Count, Encoding.Default);
writer.Write(features);
because RegisterEncodings stops recording all the other encodings after the first that fails, I think... handling all the exceptions, and not only NotSupportedException, fix the problem
try
{
var enc = GetEncodingForCodePageIdentifier(codePage);
AddLdidEncodingPair(ldid, enc);
}
catch //(NotSupportedException)
{
string message = string.Format("Failed to get codepage for language driver {0}", ldid);
Debug.WriteLine(message);
}
those are the missing encodings
Loaded assembly: System.Text.Encoding.CodePages.dll [External]
[0:] Failed to get codepage for language driver 1
[0:] Failed to get codepage for language driver 2
[0:] Failed to get codepage for language driver 8
[0:] Failed to get codepage for language driver 9
[0:] Failed to get codepage for language driver 10
[0:] Failed to get codepage for language driver 11
[0:] Failed to get codepage for language driver 13
[0:] Failed to get codepage for language driver 14
[0:] Failed to get codepage for language driver 15
[0:] Failed to get codepage for language driver 16
[0:] Failed to get codepage for language driver 17
[0:] Failed to get codepage for language driver 18
[0:] Failed to get codepage for language driver 19
[0:] Failed to get codepage for language driver 20
[0:] Failed to get codepage for language driver 21
[0:] Failed to get codepage for language driver 22
[0:] Failed to get codepage for language driver 23
[0:] Failed to get codepage for language driver 24
[0:] Failed to get codepage for language driver 25
[0:] Failed to get codepage for language driver 26
[0:] Failed to get codepage for language driver 27
[0:] Failed to get codepage for language driver 28
[0:] Failed to get codepage for language driver 29
[0:] Failed to get codepage for language driver 31
[0:] Failed to get codepage for language driver 34
[0:] Failed to get codepage for language driver 35
[0:] Failed to get codepage for language driver 36
[0:] Failed to get codepage for language driver 37
[0:] Failed to get codepage for language driver 38
[0:] Failed to get codepage for language driver 55
[0:] Failed to get codepage for language driver 64
[0:] Failed to get codepage for language driver 77
[0:] Failed to get codepage for language driver 78
[0:] Failed to get codepage for language driver 79
[0:] Failed to get codepage for language driver 80
[0:] Failed to get codepage for language driver 88
[0:] Failed to get codepage for language driver 89
[0:] Failed to get codepage for language driver 100
[0:] Failed to get codepage for language driver 101
[0:] Failed to get codepage for language driver 102
[0:] Failed to get codepage for language driver 103
[0:] Failed to get codepage for language driver 106
[0:] Failed to get codepage for language driver 107
[0:] Failed to get codepage for language driver 108
[0:] Failed to get codepage for language driver 120
[0:] Failed to get codepage for language driver 121
[0:] Failed to get codepage for language driver 122
[0:] Failed to get codepage for language driver 123
[0:] Failed to get codepage for language driver 124
[0:] Failed to get codepage for language driver 134
[0:] Failed to get codepage for language driver 135
[0:] Failed to get codepage for language driver 136
[0:] Failed to get codepage for language driver 200
[0:] Failed to get codepage for language driver 201
[0:] Failed to get codepage for language driver 202
[0:] Failed to get codepage for language driver 203
[0:] Failed to get codepage for language driver 204
@FObermaier if you agree I can push the fix direclty from my side, let me know
@benabdelkrim you can do this to continue working
try
{
var enc = GetEncodingForCodePageIdentifier(codePage);
AddLdidEncodingPair(ldid, enc);
}
catch //(NotSupportedException)
{
string message = string.Format("Failed to get codepage for language driver {0}", ldid);
Debug.WriteLine(message);
}
ShapefileDataWriter writer = new ShapefileDataWriter(path, geomFactory, Encoding.Default);
writer.Header = ShapefileDataWriter.GetHeader(features[0], features.Count, Encoding.Default);
writer.Write(features);
@DGuidi current implementation of GetEncodingForCodePageIdentifier(int)
does not work well on Android.
Changing the implementation to
/// <summary>
/// Utility function to get an encoding for the provided codepage identifier
/// </summary>
/// <param name="codePage">A code page identifier</param>
/// <returns> An <c>Encoding</c> or <c>null</c></returns>
public static Encoding GetEncodingForCodePageIdentifier(int codePage)
{
try { return CodePagesEncodingProvider.Instance.GetEncoding(codePage) ?? Encoding.GetEncoding(codePage); }
catch { return null; }
}
gives much better results. No Encoding that can't be found. I changed the implementation of RegisterEncodings
to
private static void RegisterEncodings(object[][] ldidCodePagePairs)
{
var validCodePages = new HashSet<int>(Encoding.GetEncodings().Select(t => t.CodePage));
foreach (object[] ldidCodePagePair in ldidCodePagePairs)
{
byte ldid = Convert.ToByte(ldidCodePagePair[0], CultureInfo.InvariantCulture);
int codePage = (int)ldidCodePagePair[1];
if (validCodePages.Contains(codePage))
AddLdidEncodingPair(ldid, Encoding.GetEncoding(codePage));
#if DEBUG
else
{
Debug.WriteLine("Failed to get Encoding for ldid={0} (Codepage {1})", ldid, codePage);
}
#endif
}
}
Additionally I made the the unit tests pass, there were a lot failing... If you don't mind, I'd rather commit my changes.
Additionally I made the the unit tests pass, there were a lot failing...
do you mean, they fails in android?
If you don't mind, I'd rather commit my changes.
of course, thanks
Hi all,
On Android I have the same issue as the original issue describes. I tried out the solution recommended by @FObermaier, and it solves the issue (adding the "Encoding.GetEncoding(codePage);" as fallback)
public static Encoding GetEncodingForCodePageIdentifier(int codePage) => CodePagesEncodingProvider.Instance.GetEncoding(codePage) ?? Encoding.GetEncoding(codePage);
Just wondering if there is any reason why it is not merged to the implementation? Without this, I'm not able to read the ShapeFile on Android, unless I use the source code of the NetTopologySuite.IO.ShapeFile, and add that fallback manually, but in that case I won't be able to get updates later.
Thanks, S.
Hi @benabdelkrim, do you need more support on this issue? If so, provide further details, please.