wktnettopologysuite

NetTopologySuite WKTReader ignores SRID


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).


Solution

  • 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;
            }
        }
    }