Closed KubaSzostak closed 1 year ago
NetTopologySuite.IO.Esri currently read all polygon shapefiles always as MultiPolygon what is consistent with ESRI Shapefile Technical Description. The same for lines - they are always read as MultiLineString.
I have some compilation issues
dbf.Keys()
should be record.GetNames()
I think
in Test.cs, PrintFieldValues should be something like
protected void PrintFieldValues(IAttributesTable values)
{
Console.WriteLine();
foreach (var nameVal in values.GetNames())
{
PrintFieldValue(nameVal, values[nameVal]);
}
}
or am I missing something?
There is also something in ShapeFileDataReaderTest.TestReadingShapeFileWithNulls
that prevents subsequent tests to be executed, at least in my machine. There is a Debug.Assert
in ShpPolygonReader that fails when this test is executed.
Debug.Assert(!shell.IsCCW, "Invalid Shapefile polygon - shell coordinates are not in in clockwise order.");
Beside this, all tests are basically green. In my opinion, the code can be integrated and marked as experimental in the docs, so everyone out there can start using it, but the clear disclaimer that the code written against the old shapefile library can be rewritten, the behavour is different and there will be some bugs.
Thanks for the feedback, @DGuidi . I've fixed compilation errors in the TestConsole app. By the way I also upgraded it from .NET Framework into .NET 6.
Assert statement was set for this piece of code
var shell = Factory.CreateLinearRing(partsBuilder[0]);
if (shell.IsCCW)
{
if (partsBuilder.Count > 1)
{
ThrowInvalidRecordException("Invalid Shapefile polygon - shell coordinates are not in in clockwise order.");
}
Debug.Assert(!shell.IsCCW, "Invalid Shapefile polygon - shell coordinates are not in in clockwise order.");
shell = Factory.CreateLinearRing(partsBuilder[0].Reversed());
}
According to SHP specification vertices for a polygon shell should have clockwise order. I could throw an error if that's not the case, but in order to pass other tests forgiving approach was used. If, contrary to documentation, shell IsCCW
and there is only one polygon part (there are no other polygons and there are no holes) then it is recreated using Reversed()
vertices order. In theory it shouldn't happen so I decided to add an Assert statement to make developer aware of the issue. In this specific test case we have test shapefile that contains incorrect data. That is intentionally alerted through Assert statement. I started thinking that after passing all other test maybe this is no longer needed? Should I remove it or there is another way to make the subsequent tests pass even if there is failure in an Assert statement?
I think that this can be related to IO.ShapeFile issue 70 and related PR 80?
Yes, it's related to issue 70 and PR 80. Currently it works like this:
LinearRing
IsCCW == false
it's fine, go further.IsCCW == true
and there is only one polygon part (no other polygons, no holes) then reversed order of vertices is used.IsCCW == true
and there are more polygon parts then Invalid Shapefile polygon exception is thrown .IsCCW == false
starts new polygon IsCCW == true
are holes in previously read polygon.IsValid
property set to fasle
.Above approach was chosen in order to make the reading fast. Personally I don't like the idea of checking every geometry in the world because there can be someone who provided us invalid Shapefile. But if you like to sacrifice performance for convenience I can change the code to follow @FObermaier proposal:
Polygon
s without holes) MultiPolygon
).[Multi]Polygon
.What is the decision?
In the meantime I've moved all ported test into Depraced folder/namespace. I've also added a new test checking if MultiPolygons that have a polygon inside the hole are handled properly.
What is the decision?
My2cents: as in old library (if I remember correctly), enable the "slower code that checks every geometry" only if a specific flag is enabled. Otherwise assume the data provided is correct and use the faster.code.
I like this idea. I will add a flag to ShapefileReaderOptions and create two ReadGeometry()
variants. How to name the flag?
WktRreadder
)There should be similar flags in the codebase of the io.shapefile library. You can take a look for inspiration, but feel free to choose whatever you prefer. EDIT: @kubaszostak actually the code I mentioned is not in the main branch, see PolygonBuilder here
I'm going to handle it using following flags (common for all geometry types):
In my opinion, the code can be integrated and marked as experimental in the docs, so everyone out there can start using it, but the clear disclaimer that the code written against the old shapefile library can be rewritten, the behavour is different and there will be some bugs.
@FObermaier @airbreather sorry to bother you. any advice on this?
Add Test project from NetTopologySuite.IO.ShapeFile repository
TODO: Changed original test logic
comments.TODO: Remove no longer relevant test
comments.