I’m using NetTopologySuite and have a lot of lines in a List<LineString>
and would like to group them in List<MultiLineString>
. Every MultiLineString
should contain the LineStrings
which are connected to each other (i. e. share at least one coordinate) or crossing each other.
I’m thinking of a method like:
List<MultiLineString> GroupLineStrings(List<LineString> lineStrings)
{
multiLineStrings = new List<MultilineString>();
// ...
return multiLineStrings;
}
I have tried the following:
public static List<LineString> GetConnectedLineStrings(List<LineString> lineStrings)
{
var visited = new HashSet<LineString>();
var lineNetworks = new List<LineString>();
foreach (var lineString in lineStrings)
{
if (!visited.Contains(lineString))
{
var connectedLines = new List<LineString>();
DFS(lineString, lineStrings, visited, connectedLines);
lineNetworks.Add(lineString);
}
}
return lineNetworks;
}
private static void DFS(LineString currentLine, List<LineString> allLines, HashSet<LineString> visited, List<LineString> connectedLines)
{
visited.Add(currentLine);
connectedLines.Add(currentLine);
foreach (var nextLine in GetConnectedLines(currentLine, allLines))
{
if (!visited.Contains(nextLine))
{
DFS(nextLine, allLines, visited, connectedLines);
}
}
}
private static List<LineString> GetConnectedLines(LineString line, List<LineString> allLines)
{
var connectedLines = new List<LineString>();
foreach (var otherLine in allLines)
{
if (!line.Equals(otherLine) && AreConnected(line, otherLine))
{
connectedLines.Add(otherLine);
}
}
return connectedLines;
}
private static bool AreConnected(LineString line1, LineString line2)
{
// Check if any point from line1 is contained within line2
for (int i = 0; i < line1.NumPoints; i++)
{
if (line2.Contains(line1.GetPointN(i)))
{
return true;
}
}
// Check if any point from line2 is contained within line1
for (int i = 0; i < line2.NumPoints; i++)
{
if (line1.Contains(line2.GetPointN(i)))
{
return true;
}
}
return false;
}
The result is unfortunately false.