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
{
///
/// Represents an empty GeometryCollection.
///
public static readonly IGeometryCollection Empty = DefaultFactory.CreateGeometryCollection(null);
///
/// Internal representation of this GeometryCollection.
///
protected IGeometry[] geometries = null;
///
///
///
///
/// The Geometrys for this GeometryCollection,
/// or null or an empty array to create the empty
/// point. Elements may be empty Geometrys,
/// but not nulls.
///
///
/// For create this is used a standard
/// with == .
///
public GeometryCollection(IGeometry[] geometries) : this(geometries, DefaultFactory) {}
///
///
///
///
/// 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;
}
}
///
/// Return true if all features in collection are of the same type.
///
public bool IsHomogeneous
{
get
{
IGeometry baseGeom = Geometries[0];
for (int i = 1; i < Geometries.Length; i++)
{
if (baseGeom.GetType() != Geometries[i].GetType())
{
return false;
}
}
return true;
}
}
/* 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 */
}
}