using System; using System.Collections; using GeoAPI.Geometries; using GisSharpBlog.NetTopologySuite.Utilities; namespace GisSharpBlog.NetTopologySuite.Geometries { /// /// Basic implementation of GeometryCollection. /// [Serializable] public class GeometryCollection : Geometry, IGeometryCollection { /// /// Internal representation of this GeometryCollection. /// protected IGeometry[] geometries; /// /// /// /// /// The Geometrys for this GeometryCollection, /// or null or an empty array to create the empty /// point. Elements may be empty Geometrys, /// but not nulls. /// /// public GeometryCollection(IGeometry[] geometries, IGeometryFactory factory) : base(factory) { if (geometries == null) { geometries = new IGeometry[] {}; } if (HasNullElements(geometries)) { throw new ArgumentException("geometries must not contain null elements"); } this.geometries = geometries; GeometryChangedAction(); } /// /// Returns the iTh element in the collection. /// /// /// public IGeometry this[int i] { get { return geometries[i]; } } /// /// /// public override ICoordinate Coordinate { get { if (IsEmpty) { return null; } return geometries[0].Coordinate; } } /// /// Collects all coordinates of all subgeometries into an Array. /// Note that while changes to the coordinate objects themselves /// may modify the Geometries in place, the returned Array as such /// is only a temporary container which is not synchronized back. /// /// The collected coordinates. public override ICoordinate[] Coordinates { get { ICoordinate[] coordinates = new ICoordinate[NumPoints]; int k = -1; for (int i = 0; i < geometries.Length; i++) { ICoordinate[] childCoordinates = geometries[i].Coordinates; for (int j = 0; j < childCoordinates.Length; j++) { k++; coordinates[k] = childCoordinates[j]; } } return coordinates; } } /// /// /// public override bool IsEmpty { get { for (int i = 0; i < geometries.Length; i++) { if (!geometries[i].IsEmpty) { return false; } } return true; } } /// /// /// public override Dimensions Dimension { get { Dimensions dimension = Dimensions.False; for (int i = 0; i < geometries.Length; i++) { dimension = (Dimensions) Math.Max((int) dimension, (int) geometries[i].Dimension); } return dimension; } } /// /// /// public override Dimensions BoundaryDimension { get { Dimensions dimension = Dimensions.False; for (int i = 0; i < geometries.Length; i++) { dimension = (Dimensions) Math.Max((int) dimension, (int) (geometries[i].BoundaryDimension)); } return dimension; } } /// /// /// public override int NumGeometries { get { return geometries.Length; } } /// /// /// public IGeometry[] Geometries { get { return geometries; } } /// /// /// public override int NumPoints { get { int numPoints = 0; for (int i = 0; i < geometries.Length; i++) { numPoints += geometries[i].NumPoints; } return numPoints; } } /// /// /// public override string GeometryType { get { return "GeometryCollection"; } } /// /// /// public override bool IsSimple { get { CheckNotGeometryCollection(this); Assert.ShouldNeverReachHere(); return false; } } /// /// /// public override IGeometry Boundary { get { CheckNotGeometryCollection(this); Assert.ShouldNeverReachHere(); return null; } } /// /// Returns the area of this GeometryCollection. /// public override double Area { get { double area = 0.0; for (int i = 0; i < geometries.Length; i++) { area += geometries[i].Area; } return area; } } /// /// Returns the length of this GeometryCollection. /// public override double Length { get { double sum = 0.0; for (int i = 0; i < geometries.Length; i++) { sum += (geometries[i]).Length; } return sum; } } /* BEGIN ADDED BY MPAUL42: monoGIS team */ /// /// Returns the number of geometries contained by this . /// public int Count { get { return geometries.Length; } } /// /// /// /// /// public override IGeometry GetGeometryN(int n) { return geometries[n]; } /// /// /// /// /// /// public override bool EqualsExact(IGeometry other, double tolerance) { if (!IsEquivalentClass(other)) { return false; } IGeometryCollection otherCollection = (IGeometryCollection) other; if (geometries.Length != otherCollection.Geometries.Length) { return false; } for (int i = 0; i < geometries.Length; i++) { if (!geometries[i].EqualsExact( otherCollection.Geometries[i], tolerance)) { return false; } } return true; } /// /// /// /// public override void Apply(ICoordinateFilter filter) { for (int i = 0; i < geometries.Length; i++) { geometries[i].Apply(filter); } } /// /// /// /// public override void Apply(IGeometryFilter filter) { filter.Filter(this); for (int i = 0; i < geometries.Length; i++) { geometries[i].Apply(filter); } } /// /// /// /// public override void Apply(IGeometryComponentFilter filter) { filter.Filter(this); for (int i = 0; i < geometries.Length; i++) { geometries[i].Apply(filter); } } /// /// /// /// public override object Clone() { GeometryCollection gc = (GeometryCollection) base.Clone(); gc.geometries = new IGeometry[geometries.Length]; for (int i = 0; i < geometries.Length; i++) { gc.geometries[i] = (IGeometry) geometries[i].Clone(); } return gc; } /// /// /// public override void Normalize() { for (int i = 0; i < geometries.Length; i++) { geometries[i].Normalize(); } Array.Sort(geometries); } /// /// Returns a GeometryCollectionEnumerator: /// this IEnumerator returns the parent geometry as first element. /// In most cases is more useful the code /// geometryCollectionInstance.Geometries.GetEnumerator(): /// this returns an IEnumerator over geometries composing GeometryCollection. /// /// public IEnumerator GetEnumerator() { return new GeometryCollectionEnumerator(this); } /// /// /// /// /// protected internal override int CompareToSameClass(object o) { ArrayList theseElements = new ArrayList(geometries); ArrayList otherElements = new ArrayList(((GeometryCollection) o).geometries); return Compare(theseElements, otherElements); } /// /// /// /// protected override IEnvelope ComputeEnvelopeInternal() { IEnvelope envelope = new Envelope(); for (int i = 0; i < geometries.Length; i++) { envelope.ExpandToInclude(geometries[i].EnvelopeInternal); } return envelope; } /* END ADDED BY MPAUL42: monoGIS team */ } }