1

I implemented NetTopologySuite into EF Core (SQLServer). I'm getting coordinates from the Google APIs, transforming them into Point and Polygon and saving them into the database without trouble.

I stringify Geometry.AsText() these types when sending them over HTTP to my backend API. In the backend, I read those stringified geometries using the WKTReader. The WKTReader seems to drop the SRID that I configured on the GeometryFactory. This causes an error.

As a workaround, I assign the SRID on the Geometry object after it being read and before it going to the database operation. This works but feels wrong.

Can you help me improve this code and resolving this issue?

The variables x,y and z and for debug purposes only. See screenshot of debugging: debugging code snippet

public static class CoordinatesHelper
{
    private static readonly GeometryFactory GeoFactory = NtsGeometryServices.Instance.CreateGeometryFactory(4326);
    private static readonly WKTReader GeoReader = new(GeoFactory.GeometryServices);

    public static Geometry? ReadGeometry(string? geoString)
    {
        if (string.IsNullOrWhiteSpace(geoString)) return null;

        var x = GeoFactory.SRID;
        var y = GeoReader.DefaultSRID;
        
        var geometry = GeoReader.Read(geoString);
        var z = geometry.SRID;
        
        geometry.SRID = 4326; // ? WKT reader ignores SRID, this fixes SQL error but is it a correct solution?
        return geometry;
    }
}

I was expecting the WKTReader to result in a Geometry with the configured SRID (4326) instead of the default (-1).

Auguste VN
  • 15
  • 3

1 Answers1

1

Your CoordinatesHelper class should look like this:

public static class CoordinatesHelper
{
    private static readonly WKTReader GeoReader = 
        new(new NtsGeometryServices(new PrecisionModel(), 4326));

    public static Geometry? ReadGeometry(string? geoString)
    {
        if (string.IsNullOrWhiteSpace(geoString))
            return null;

        try {
            return GeoReader.Read(geoString);
        }
        catch (ParseException pex) {
            Debug.WriteLine(pex.Message);
            return null;
        }
    }
}

FObermaier
  • 832
  • 5
  • 12
  • Thanks, I'll try that NtsGeometryServices constructor. Could you confirm that the WKTReader then respects the SRID? Also, I'm using the GeoFactory for creating the shapes since that's recommended. I left that part out to not pollute the snippet. – Auguste VN May 18 '23 at 12:38
  • @AugusteVN you're probably trying to fix the same CCW exception I'm struggling with. Testing out FObermaier's answer in LINQPad I can confirm that it honors the SRID. Buffering seems to create a shape that's not what I'm looking for and in the wrong SRID, so I'm still using my 4326 > 2855 > Buffer > 4326 helper. – Gup3rSuR4c May 22 '23 at 02:28
  • @Gup3rSuR4c I also went down that hole. I haven't visualized the polygons yet but so far my search functionality (Google API viewport) IsWithinDistance is working. I'm saving all viewports as constructed Polygons with CCW, valid linear rings. And to get them back out, I use the WKTReader. All with the SRID of 4326. I convert them back and forth between their stringified version and shape type. Often times when I got these CCW or invalid range exceptions, it had to do with incorrectly constructing or reading the shapes, wrong SRID. Rather invalid shapes than the shape rotation was the cause. – Auguste VN May 23 '23 at 09:03
  • _Buffering seems to create a shape that's not what I'm looking for and in the wrong SRID._ NTS __does not__ do geographic computations, it treats everything as if it were planar 2.5D. Calling the `geom.Buffer` function __does not__ change the SRID. If it does for you, raise an issue over at github.com/nettopologysuite/nettopologysuite – FObermaier May 24 '23 at 11:22
  • To force the creation of SqlServer conformant polygon geometries you can derive `NtsGeometryServices` class and let it create `GeometryFactoryEx` factories for which you can define ring orientation for the ex- and interior specifically. See https://github.com/NetTopologySuite/NetTopologySuite/blob/main/test/NetTopologySuite.Tests.NUnit/Geometries/GeometryFactoryExTest.cs – FObermaier May 24 '23 at 11:34