I am trying to take a bunch of arbitrary line segments and convert them to polygons using NetTopology GetPolygons method. I have written below based on examples I have seen using this package. My lines are clearly intersecting, and clearly form polygons but I get no results, and all of the lines are in the "dangles" section.
NetTopologySuite.Geometries.GeometryFactory geometryFactory = new NetTopologySuite.Geometries.GeometryFactory();
List<NetTopologySuite.Geometries.Geometry> lines = new List<NetTopologySuite.Geometries.Geometry>();
foreach(var line in segments)
{
List<NetTopologySuite.Geometries.Coordinate> coords = new List<NetTopologySuite.Geometries.Coordinate>();
NetTopologySuite.Geometries.Coordinate lineStart = new NetTopologySuite.Geometries.Coordinate(line.X1, line.Y1);
NetTopologySuite.Geometries.Coordinate lineEnd = new NetTopologySuite.Geometries.Coordinate(line.X2, line.Y2);
coords.Add(lineStart);
coords.Add(lineEnd);
var lineGeometry = geometryFactory.CreateLineString(coords.ToArray());
Console.WriteLine("L=" + lineGeometry.ToString());
lines.Add(lineGeometry);
}
Polygonizer polygonizer = new Polygonizer();
polygonizer.Add(lines);
var polys = polygonizer.GetPolygons();
// Return zero
var dangles = polygonizer.GetDangles();
// Returns zero
Perhaps im not using it correctly, or its not designed to do what I expect?
Input
Expected (Closed lines form polygons, other lines (red x) are dangles?):
I include a serialized list of my lines
string ls = @"[{"Start":{"X":326.7043151855469,"Y":72.9458999633789,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":0,"Visible":false,"ID":0,"Tag":null,"Opacity":0},"End":{"X":948.3546752929688,"Y":77.146240234375,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":0,"Visible":false,"ID":0,"Tag":null,"Opacity":0},"X1":326.7043151855469,"Y1":72.9458999633789,"X2":948.3546752929688,"Y2":77.146240234375,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":false,"ID":100001,"Tag":"temp","Opacity":0},{"Start":{"X":452.7145080566406,"Y":35.14283752441406,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":446.41400146484375,"Y":215.75747680664062,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":452.7145080566406,"Y1":35.14283752441406,"X2":446.41400146484375,"Y2":215.75747680664062,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100002,"Tag":"temp","Opacity":1},{"Start":{"X":654.3308715820312,"Y":35.14283752441406,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":643.8300170898438,"Y":209.4569549560547,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":654.3308715820312,"Y1":35.14283752441406,"X2":643.8300170898438,"Y2":209.4569549560547,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100003,"Tag":"temp","Opacity":1},{"Start":{"X":792.9420776367188,"Y":35.14283752441406,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":795.042236328125,"Y":213.6573028564453,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":792.9420776367188,"Y1":35.14283752441406,"X2":795.042236328125,"Y2":213.6573028564453,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100004,"Tag":"temp","Opacity":1},{"Start":{"X":330.9046325683594,"Y":165.3533935546875,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":918.9522705078125,"Y":169.55372619628906,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":330.9046325683594,"Y1":165.3533935546875,"X2":918.9522705078125,"Y2":169.55372619628906,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100005,"Tag":"temp","Opacity":1},{"Start":{"X":547.22216796875,"Y":49.84402847290039,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":549.3223266601562,"Y":117.04946899414062,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":547.22216796875,"Y1":49.84402847290039,"X2":549.3223266601562,"Y2":117.04946899414062,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100006,"Tag":"temp","Opacity":1},{"Start":{"X":549.3223266601562,"Y":117.04946899414062,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":685.8333740234375,"Y":127.55032348632812,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":549.3223266601562,"Y1":117.04946899414062,"X2":685.8333740234375,"Y2":127.55032348632812,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100007,"Tag":"temp","Opacity":1},{"Start":{"X":549.3223266601562,"Y":112.84913635253906,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"End":{"X":551.4224853515625,"Y":192.6555938720703,"ShapeType":0,"Stroke":null,"Fill":null,"StrokeThickness":1,"Visible":true,"ID":0,"Tag":null,"Opacity":1},"X1":549.3223266601562,"Y1":112.84913635253906,"X2":551.4224853515625,"Y2":192.6555938720703,"ShapeType":1,"Stroke":"#FFFFFF","Fill":null,"StrokeThickness":3,"Visible":true,"ID":100008,"Tag":"temp","Opacity":1}]";
var lines = JsonSerializer.Deserialize<List<Line>>(ls);
Yeah, NTS doesn't do that. The thing is that Polygonizer
only joins lines from their ends. It does not break them first. You need to do that yourself. It can be easy if horizontal and vertical lines are distinguishable. Otherwise, you need to check all lines two by two and break them from their intersections.
WKTReader reader = new WKTReader();
var vLines = reader.Read("MULTILINESTRING ((124.5 309, 117.5 151.5), (229.5 316, 214.5 152.5), (330 320, 320 155.5), (430 320, 418 163))");
var hLines = reader.Read("MULTILINESTRING ((96.5 284.5, 469.5 276.5), (95.5 172.5, 464.5 187), (195.5 237.5, 361 226.5))");
var hLinesBreaked = hLines.Difference(vLines);
var vLinesBreaked = vLines.Difference(hLines);
var allLines = vLinesBreaked.Union(hLinesBreaked);
Polygonizer polygonizer = new Polygonizer();
polygonizer.Add(allLines);
ICollection<Geometry> polys = polygonizer.GetPolygons(); // count: 4
ICollection<LineString> dangles = polygonizer.GetDangles(); // count: 14