The data I've loaded from a shapefile into a geometry column in SQL Server (using NetTopologySuite) is not producing valid GeoJSON when I export it because it doesn't follow the right-hand rule.

I thought this would be easy to fix with the MakeValid() function, but it's not correcting the issue.

I tried with a simplified geometry as below:

declare @geom geometry
select @geom = geometry::STGeomFromText('POLYGON ((
0 0,
0 1,
2 1,
2 0, 
0 0
))', 4326)

select @geom, @geom.IsValidDetailed()

SQL Server says it's valid (24400: Valid), so presumably that's why it's not fixing it in the MakeValid function.

What's the best way to resolve this? I've seen an option to use: UPDATE table SET geom = geom.STUnion(geom.STStartPoint()) which works for simple polygons, but I'm not sure how well it will work for more complex geometries.

  • Is using ogr2ogr an acceptable option for you? – user30184 Jul 16 '18 at 21:53
  • @user30184 Not really. I believe that's a command line tool, where I need it embedded in a website so a user can upload a shapefile and it gets processed (preferably using C#). – Sean Jul 17 '18 at 14:21
  • How about GDAL generally if used through C# or Python bindings? But it does feel like a heavy tool if the only problem is with ring orientations. – user30184 Jul 17 '18 at 14:26
  • Yeah - I'm so close with NetTopologySuite loading the data in, there's just this one small issue, which MakeValid is supposed to fix. So I'm wondering if there's something wrong with how I'm doing it, rather than looking for a new tool. – Sean Jul 17 '18 at 18:51

I had thought I would fix this in Sql Server using a spatial function like MakeValid, but as that didn't work, I've found a way to fix it when loading the data from the shape file, using NetTopologySuite.

I was using:

var factory = new GeometryFactory();
using (var shapeFileDataReader = new ShapefileDataReader(filePath, factory))

But simply changing the factory worked, like this:

var factory = new OgcCompliantGeometryFactory();
using (var shapeFileDataReader = new ShapefileDataReader(filePath, factory))
| improve this answer | |

I've started working with NetTopologySuite, and have the same problem. I found a fix here. Simply put:

if (!polygon.Shell.IsCCW) polygon = polygon.Reverse();

If you have Geometries you will need to cast, and if you have MultiPolygons you will have to iterate through each of them.

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.