NetTopologySuite / NetTopologySuite.IO.ShapeFile

The ShapeFile IO module for NTS.
35 stars 25 forks source link

'key is null' when trying to read a shapefile in Android #36

Closed FelixKainz closed 3 months ago

FelixKainz commented 4 years ago

Hello! I am working out how to read shapefiles cross platform (UWP and Android) in a Xamarin.Forms application (.netstandard 2.0). But I am encountering an issue:

System.ArgumentNullException
  Message=Value cannot be null.
Parameter name: key

this exception is thrown in the line

var shapeFileReader = Shapefile.CreateDataReader(shapeFile,
   new NetTopologySuite.Geometries.GeometryFactory(
      new NetTopologySuite.Geometries.PrecisionModel(1000000.0)));

where 'shapeFile' is a string with the path /data/user/0/com.companyname.shapefileforms/cache/ShapeFiles/countries (so without file extensions).

This code works fine when run as UWP app but not when run within Android. Tested with version 8.1, 9 and 10.

I attached the whole Project. This error occurs in ShapeFileForms.MainPage.xaml.cs in the Method ClickOnMap, line 83. I can not step into this line in the debugger, I guess because I installed this module through nuget instead of copying in its source code?

It would be awesome if we could work this out together, although I am quite new to this and pobably won't be of much help :/

Thank you very much!

ShapeFileForms.zip

FelixKainz commented 4 years ago

I added a debug output of the files in the chached ShapeFiles dir in the top of the problematic method CreateDrawables:

DirectoryInfo di = new DirectoryInfo(shapeFile.Substring(0, shapeFile.Length - 9));
            foreach (FileInfo fi in di.GetFiles())
            {
                System.Diagnostics.Debug.WriteLine(string.Format("{0} ({1} bytes)", fi.FullName, fi.Length));
            }

It gives the following output on UWP:

C:\Users\Joker\AppData\Local\Packages\a81b00f1-04c5-4770-b9bc-bd427610f6cf_x1waj26dt6j1y\LocalCache\ShapeFiles\countries.dbf (7301 bytes)
C:\Users\Joker\AppData\Local\Packages\a81b00f1-04c5-4770-b9bc-bd427610f6cf_x1waj26dt6j1y\LocalCache\ShapeFiles\countries.shp (459332 bytes)
C:\Users\Joker\AppData\Local\Packages\a81b00f1-04c5-4770-b9bc-bd427610f6cf_x1waj26dt6j1y\LocalCache\ShapeFiles\countries.shx (1276 bytes)

And on Android:

[0:] /data/user/0/com.companyname.shapefileforms/cache/ShapeFiles/countries.shp (459332 bytes)
[0:] /data/user/0/com.companyname.shapefileforms/cache/ShapeFiles/countries.dbf (7301 bytes)
[0:] /data/user/0/com.companyname.shapefileforms/cache/ShapeFiles/countries.shx (1276 bytes)

These are all identical with respect to IDs across UWP and Android 8.1, 9, 10.

So, to conclude: all the DBF, SHP and SHX files are there on any target platform and at least superficially (only judging by filesize) intact.

charlenni commented 4 years ago

Ok, I tried to debug this. I found problems (missing encoding and so the initializing of the DbaseEncodingUtility crashes), which could sometimes be solved, when I add System.Text.Encoding (4.3.0) to the dependencies of NetTopologySolution.IO.ShapeFile. But only sometimes. Perhaps it has to do with the handling of the NuGet packages in VS. I couldn't create a stable workaround for this. Strange.

The real problem is, that CodePagesEncodingProvider.Instance.GetEncoding(codePage) for codePage=1252 (the default) returns a null. And this null is then added to the IDictionary<byte, Encoding>, which than crashes and returns the static object DbaseEncodingUtility undefined, because the add to the dictionary is called in the static constructor.

Perhaps someone has an idea.

charlenni commented 4 years ago

I found some pages, one about encoding in NetCore, one from StackOverflow (see here). Perhaps it helps.

KubaSzostak commented 3 months ago

Hi @FelixKainz, do you need more support on this issue? If so, provide further details, please.

FelixKainz commented 3 months ago

Hi @KubaSzostak, thank you for following up after all this time hehe. I am good. I needed this for one of my exams in university. Meanwhile, I arrived well in the working world. Thanks to @charlenni back then for putting in the work to help me! <3