using System; using System.Collections; using GeoAPI.Geometries; namespace GisSharpBlog.NetTopologySuite.Geometries { /// /// Iterates over all Geometry's in a GeometryCollection. /// Implements a pre-order depth-first traversal of the GeometryCollection /// (which may be nested). The original GeometryCollection is /// returned as well (as the first object), as are all sub-collections. It is /// simple to ignore the GeometryCollection objects if they are not /// needed. /// public class GeometryCollectionEnumerator : IEnumerator { /// /// The GeometryCollection being iterated over. /// private IGeometryCollection parent; /// /// Indicates whether or not the first element (the GeometryCollection) /// has been returned. /// private bool atStart; /// /// The number of Geometrys in the the GeometryCollection. /// private int max; /// /// The index of the Geometry that will be returned when next /// is called. /// private int index; /// /// The iterator over a nested GeometryCollection, or null /// if this GeometryCollectionIterator is not currently iterating /// over a nested GeometryCollection. /// private GeometryCollectionEnumerator subcollectionEnumerator; /// /// Constructs an iterator over the given GeometryCollection. /// /// /// The collection over which to iterate; also, the first /// element returned by the iterator. /// public GeometryCollectionEnumerator(IGeometryCollection parent) { this.parent = parent; atStart = true; index = 0; max = parent.NumGeometries; } /// /// /// /// public bool MoveNext() { if (atStart) return true; if (subcollectionEnumerator != null) { if (subcollectionEnumerator.MoveNext()) return true; subcollectionEnumerator = null; } if (index >= max) return false; return true; } /// /// /// /// The parent GeometryCollection is the first object returned! public object Current { get { // the parent GeometryCollection is the first object returned if (atStart) { atStart = false; return parent; } if (subcollectionEnumerator != null) { if (subcollectionEnumerator.MoveNext()) return subcollectionEnumerator.Current; else subcollectionEnumerator = null; } if (index >= max) throw new ArgumentOutOfRangeException(); IGeometry obj = parent.GetGeometryN(index++); if (obj is IGeometryCollection) { subcollectionEnumerator = new GeometryCollectionEnumerator((IGeometryCollection) obj); // there will always be at least one element in the sub-collection return subcollectionEnumerator.Current; } return obj; } } /// /// /// public void Reset() { atStart = true; index = 0; } } }