Search code examples
c#geometrygeospatialnettopologysuite

NetTopology 'found non-noded intersection' Exception when determining the difference between two specific geometries


Using the NetTopology in C# I'm getting a 'found non-noded intersection' Exception when determining the difference between two specific geometries.

These geometries are the result of using several routines like CascadedPolygonUnion.Union, Intersection, and Difference.

At some point, we have a MultiPolygon from which we want to cut out another geometry (Polygon): image

We use this code to try and cut off the 'red' polygon:

Geometry difference = multiPolygon.Difference(geometryToRemove);

But then we get a NetTopologySuite.Geometries.TopologyException with the message:

found non-noded intersection between LINESTRING (240173.28029999882 493556.2806000002, 240173.28177031482 493556.28131837514) and LINESTRING (240173.28176154062 493556.2813140882, 240173.28176153247 493556.2813140842) [ (240173.28176153894, 493556.2813140874) ]

I asked this question also in the NetTopologySuite Discussuion forum because we are close to a release date and I was hoping someone could give some extra insight (of ideas for a workaround) as this looks like a bug in de library because the polygons themselves seem valid.

The data regarding the polygons can be found here - we use the 'RDNew' data to perform the Difference action, but I also added the WGS84 versions of these polygons to be able to view them in tools like geojson.io.


Solution

  • Thanks to one of the maintainers of the library I got the answer.

    Basically, I needed to upgrade to version 2.2 (which I already did at first to see if this would resolve the problem).

    But second, I needed to configure the application to use the - in version 2.2 introduced - 'NextGen' overlay generator, which is not turned on by default.

    To use the 'Next Gen' overlay generator, add the following code at some starup point in your application:

    var curInstance = NetTopologySuite.NtsGeometryServices.Instance;
    NetTopologySuite.NtsGeometryServices.Instance = new NetTopologySuite.NtsGeometryServices(
        curInstance.DefaultCoordinateSequenceFactory,
        curInstance.DefaultPrecisionModel,
        curInstance.DefaultSRID,
        GeometryOverlay.NG, // RH: use 'Next Gen' overlay generator
        curInstance.CoordinateEqualityComparer);
    

    I use the current instance of NtsGeometryServices to get and reuse the current default instances of the other configurable parts. But your free to create new instances of the required parts (like mentioned in the original post at https://github.com/NetTopologySuite/NetTopologySuite/discussions/530#discussioncomment-888410 )

    There are also possibilities to use both overlay generators next to each other (also mentioned in the original post), but I never tried this as we will be using the 'NextGen' version for the entire application.