@@ -4,6 +4,7 @@ namespace BuildingRegistry.Tests
44 using BuildingRegistry . Legacy ;
55 using FluentAssertions ;
66 using NetTopologySuite . Geometries ;
7+ using NetTopologySuite . Geometries . Utilities ;
78 using Xunit ;
89
910 public class PolygonTests
@@ -73,5 +74,62 @@ public void GivenGrarBuilding15078651()
7374
7475
7576 }
77+
78+ /// <summary>
79+ /// DATE: 1/10/2025 (polygon could be changed afterwards)
80+ /// https://api.basisregisters.vlaanderen.be/v2/gebouwen/31912514
81+ ///
82+ /// Claim from GRB that this polygon is invalid, but MS SQL + NTS says it's valid.
83+ ///
84+ /// select geometry::STGeomFromText('POLYGON ((76334.58333778383 169985.72249904636, 76337.76829408009 169985.05009705175, 76336.27953694883 169977.99832380182, 76331.71906681615 169978.96112169552, 76332.89316427232 169984.52245125046, 76334.94298703629 169985.64657057129, 76334.58333778383 169985.72249904636))', '31370').STIsValid()
85+ /// select geometry::STGeomFromText('POLYGON ((76334.58333778383 169985.72249904636, 76337.76829408009 169985.05009705175, 76336.27953694883 169977.99832380182, 76331.71906681615 169978.96112169552, 76332.89316427232 169984.52245125046, 76334.94298703629 169985.64657057129, 76334.58333778383 169985.72249904636))', '31370').IsValidDetailed()
86+ /// Both return 1 (true) / Valid
87+ ///
88+ /// AI Feedback:
89+ /// I re-checked the coordinates carefully:
90+ /// (1) 76334.58333778383 169985.72249904636
91+ /// (2) 76337.76829408009 169985.05009705175
92+ /// (3) 76336.27953694883 169977.99832380182
93+ /// (4) 76331.71906681615 169978.96112169552
94+ /// (5) 76332.89316427232 169984.52245125046
95+ /// (6) 76334.94298703629 169985.64657057129
96+ /// (1) 76334.58333778383 169985.72249904636 (closed)
97+ ///
98+ /// If you check all non-adjacent segment pairs, none of them actually cross. What does happen is:
99+ ///
100+ /// - Point (6) lies on the straight line between points (1) and (2) — it’s an extra vertex on an otherwise straight edge.
101+ /// - That’s a collinear extra vertex, not a self-intersection (no “bow-tie” / figure-8).
102+ ///
103+ /// This is perfectly fine for a polygon boundary: it just has a redundant vertex along an edge. In OGC / NetTopologySuite terms:
104+ ///
105+ /// - The ring is closed.
106+ /// - The area is non-zero.
107+ /// - The edges do not intersect each other except at shared endpoints.
108+ /// - So the polygon is valid and simple, which is why IsValid returns true.
109+ ///
110+ /// So: ✅ NetTopologySuite is right, ❌ my earlier “self-intersecting bow-tie” claim was incorrect — thanks for catching that.
111+ ///
112+ /// More feedback and issue: https://vlaamseoverheid.atlassian.net/browse/GAWR-7149
113+ /// </summary>
114+ [ Fact ]
115+ public void GivenSelfIntersectsReportedPolygon31912514 ( )
116+ {
117+ // It's NOT self-intersecting, see explanation in summary
118+ // But it's been reported as such
119+ var wkt = @"POLYGON ((
120+ 76334.58333778383 169985.72249904636,
121+ 76337.76829408009 169985.05009705175,
122+ 76336.27953694883 169977.99832380182,
123+ 76331.71906681615 169978.96112169552,
124+ 76332.89316427232 169984.52245125046,
125+ 76334.94298703629 169985.64657057129,
126+ 76334.58333778383 169985.72249904636
127+ ))" ;
128+ var geometry = GeometryHelper . CreateGeometryFromWkt ( wkt ) ;
129+ GeometryValidator . IsValid ( geometry ) . Should ( ) . BeTrue ( ) ;
130+
131+ GeometryFixer . Fix ( geometry ) ;
132+ geometry . AsText ( ) . Split ( "," ) . Length . Should ( ) . Be ( 7 ) ; // still 7 points, no change
133+ }
76134 }
77135}
0 commit comments