/// <summary> /// Tests whether a <see cref="Geometry" /> is sequenced correctly. /// <see cref="LineString" />s are trivially sequenced. /// <see cref="MultiLineString" />s are checked for correct sequencing. /// Otherwise, <c>IsSequenced</c> is defined /// to be <c>true</c> for geometries that are not lineal. /// </summary> /// <param name="geom">The <see cref="Geometry" /> to test.</param> /// <returns> /// <c>true</c> if the <see cref="Geometry" /> is sequenced or is not lineal. /// </returns> public static bool IsSequenced(IGeometry geom) { if (!(geom is IMultiLineString)) return true; IMultiLineString mls = geom as IMultiLineString; // The nodes in all subgraphs which have been completely scanned ISet<ICoordinate> prevSubgraphNodes = new SortedSet<ICoordinate>(); ICoordinate lastNode = null; IList<ICoordinate> currNodes = new List<ICoordinate>(); for (int i = 0; i < mls.NumGeometries; i++) { ILineString line = (ILineString) mls.GetGeometryN(i); ICoordinate startNode = line.GetCoordinateN(0); ICoordinate endNode = line.GetCoordinateN(line.NumPoints - 1); /* * If this linestring is connected to a previous subgraph, geom is not sequenced */ if (prevSubgraphNodes.Contains(startNode)) return false; if (prevSubgraphNodes.Contains(endNode)) return false; if (lastNode != null && startNode != lastNode) { // start new connected sequence prevSubgraphNodes.AddAll(currNodes); currNodes.Clear(); } currNodes.Add(startNode); currNodes.Add(endNode); lastNode = endNode; } return true; }