/// <summary> /// Simplifies the specified polygon. /// </summary> /// <param name="source">The polygon.</param> /// <param name="delta">The tolerance.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The simplified polygon.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentOutOfRangeException">The delta is less than or equal to 0.</exception> public static IBasicPolygon Simplify(IBasicPolygon source, Double delta, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(null); } DouglasPeuckerAlgorithm algorithm = new DouglasPeuckerAlgorithm(source.Shell.Coordinates, delta, precisionModel); algorithm.Compute(); IList <Coordinate> shell = algorithm.Result; List <IList <Coordinate> > holes = new List <IList <Coordinate> >(); foreach (IBasicLineString hole in source.Holes) { if (hole == null || hole.Coordinates == null) { continue; } algorithm = new DouglasPeuckerAlgorithm(hole.Coordinates, delta, precisionModel); algorithm.Compute(); holes.Add(algorithm.Result); } return(new BasicPolygon(shell, holes)); }
/// <summary> /// Initializes a new instance of the <see cref="MinkowskiSumAlgorithm" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <param name="precisionModel">The precision model.</param> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The buffer is null. /// </exception> public MinkowskiSumAlgorithm(IBasicPolygon source, IReadOnlyList <Coordinate> buffer, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } this.PrecisionModel = precisionModel ?? PrecisionModel.Default; this.sourceShellCoordinates = source.Shell; this.sourceHoleCoordinates = source.Holes.Select(hole => hole).ToList(); if (buffer.Count > 0 && buffer[0] != buffer[buffer.Count - 1]) { this.bufferCoordinates = new BasicProxyLineString(buffer, true); } else { this.bufferCoordinates = buffer; } this.hasResult = false; }
/// <summary> /// Computes the buffer of the source geometry. /// </summary> public void Compute() { _resultShellCoordinates = new List <Coordinate>(); _resultHoleCoordinates = new List <IList <Coordinate> >(); if (_sourceShellCoordinates.Count == 1) { ComputeMinkowskiSumOfPoint(_sourceShellCoordinates); } else { ComputeMinkowskiSumOfCoordinateList(_sourceShellCoordinates, false); if (_sourceHoleCoordinates != null) { for (Int32 holeIndex = 0; holeIndex < _sourceHoleCoordinates.Count; holeIndex++) { ComputeMinkowskiSumOfCoordinateList(_sourceHoleCoordinates[holeIndex], true); } } } _result = new BasicPolygon(_resultShellCoordinates, _resultHoleCoordinates); _hasResult = true; }
public void MonotoneSubdivisionAlgorithmConstructorTest() { // predefined polygon (which is extended) MonotoneSubdivisionAlgorithm algorithm = new MonotoneSubdivisionAlgorithm(_shell); Assert.AreEqual(_shell.Count + 1, algorithm.Shell.Count); Assert.IsTrue(_shell.SequenceEqual(algorithm.Shell.Take(_shell.Count))); Assert.AreEqual(algorithm.Shell[0], algorithm.Shell[algorithm.Shell.Count - 1]); // random polygon IBasicPolygon polygon = RandomPolygonGenerator.CreateRandomPolygon(100, new Coordinate(10, 10), new Coordinate(50, 50)); algorithm = new MonotoneSubdivisionAlgorithm(polygon.Shell.Coordinates); Assert.IsTrue(polygon.Shell.SequenceEqual(algorithm.Shell)); // exceptions Assert.IsTrue(polygon.Shell.SequenceEqual(algorithm.Shell)); Assert.Throws <ArgumentNullException>(() => algorithm = new MonotoneSubdivisionAlgorithm(null)); }
/// <summary> /// Buffers he specified source. /// </summary> public void Compute() { this.resultShellCoordinates = new List <Coordinate>(); this.resultHoleCoordinates = new List <List <Coordinate> >(); if (this.sourceShellCoordinates.Count == 1) { this.ComputeMinkowskiSumOfPoint(); } else { this.ComputeMinkowskiSumOfCoordinateList(this.sourceShellCoordinates, false); if (this.sourceHoleCoordinates != null) { for (Int32 holeIndex = 0; holeIndex < this.sourceHoleCoordinates.Count; holeIndex++) { this.ComputeMinkowskiSumOfCoordinateList(this.sourceHoleCoordinates[holeIndex], true); } } } this.result = new BasicProxyPolygon(this.resultShellCoordinates, this.resultHoleCoordinates); this.hasResult = true; }
/// <summary> /// Initializes a new instance of the <see cref="MinkowskiSumAlgorithm" /> class. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentNullException">The buffer is null.</exception> /// <exception cref="System.ArgumentException">The orientation of the source is not suitable.</exception> /// <exception cref="System.ArgumentException">The orientation of the buffer is not suitable.</exception> public MinkowskiSumAlgorithm(IList <Coordinate> source, IBasicPolygon buffer) { if (source == null) { throw new ArgumentNullException(nameof(source), "The source is null."); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer), "The buffer is null."); } _sourceShellCoordinates = source; if (_sourceShellCoordinates.Count > 1 && _sourceShellCoordinates[_sourceShellCoordinates.Count - 1] != _sourceShellCoordinates[0]) { _sourceShellCoordinates.Add(_sourceShellCoordinates[0]); } if (_sourceShellCoordinates.Count > 3 && PolygonAlgorithms.Orientation(_sourceShellCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the source is not suitable.", nameof(source)); } _bufferCoordinates = new List <Coordinate>(); foreach (Coordinate coordinate in buffer.Shell.Coordinates) { _bufferCoordinates.Add(coordinate); } if (PolygonAlgorithms.Orientation(_bufferCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the buffer is not suitable.", nameof(buffer)); } _hasResult = false; }
/// <summary> /// Compute the centroid of the polygon. /// </summary> /// <param name="source">The polygon.</param> /// <returns>The centroid of the polygon.</returns> public static Coordinate ComputeCentroid(IBasicPolygon source) { PolygonCentroidAlgorithm algorithm = new PolygonCentroidAlgorithm(source); algorithm.Compute(); return(algorithm.Result); }
private List<IBasicPolygon> GetNeighbours(IBasicPolygon polygon) { var neighbours = new List<IBasicPolygon>(); neighbours.AddRange(GetXNeighbours(polygon)); neighbours.AddRange(GetYNeighbours(polygon)); return neighbours; }
/// <summary> /// Computes the signed area of the specified polygon. /// </summary> /// <param name="polygon">The polygon.</param> /// <returns>The signed area of the polygon. If the polygon is not valid, <c>NaN</c> is returned.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public static Double SignedArea(IBasicPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(SignedArea(polygon.Shell, polygon.Holes)); }
/// <summary> /// Computes the planar orientation of a polygon. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The orientation of the polygon shell. If the polygon is invalid <c>Undefined</c> is returned.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public static Orientation Orientation(IBasicPolygon polygon, PrecisionModel precisionModel) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(Orientation(polygon.Shell, precisionModel)); }
/// <summary> /// Computes the area of the specified polygon. /// </summary> /// <param name="polygon">The polygon.</param> /// <returns>The area of the polygon. If the polygon is not valid, <c>NaN</c> is returned.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public static Double Area(IBasicPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(Math.Abs(SignedArea(polygon))); }
/// <summary> /// Buffers he specified source. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The buffered polygon.</returns> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The buffer is null. /// </exception> public static IBasicPolygon Buffer(IBasicPolygon source, IBasicPolygon buffer, PrecisionModel precisionModel) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } return(new MinkowskiSumAlgorithm(source, buffer.Shell, precisionModel).Result); }
/// <summary> /// Computes the convex hull of the specified polygon. /// </summary> /// <param name="source">The source polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The convex hull of <paramref name="source" />.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public static IReadOnlyList <Coordinate> ComputeConvexHull(IBasicPolygon source, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(new GrahamScanAlgorithm(source.Shell, precisionModel).Result); }
/// <summary> /// Computes whether the given coordinate is outside the polygon. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="coordinate">The coordinate to check.</param> /// <param name="precisionModel">The precision model.</param> /// <returns><c>true</c> if the coordinate is outside the polygon; otherwise, <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> /// <remarks> /// Positions on the boundary of the polygon shell are neither inside or outside the polygon. /// </remarks> public static Boolean InExterior(IBasicPolygon polygon, Coordinate coordinate, PrecisionModel precisionModel) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(InExterior(polygon.Shell, polygon.Holes, coordinate, precisionModel)); }
/// <summary> /// Determines whether the specified polygon is valid. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns><c>true</c> if the polygon is valid; otherwise false.</returns> /// <exception cref="System.ArgumentNullException">The shell is null.</exception> public static Boolean IsValid(IBasicPolygon polygon, PrecisionModel precisionModel) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(IsValid(polygon.Shell, polygon.Holes, true, precisionModel)); }
/// <summary> /// Computes the location of the specified coordinate with respect to a polygon. /// </summary> /// <param name="polygon">The polygon.</param> /// <param name="coordinate">The coordinate.</param> /// <param name="precision">The precision model.</param> /// <returns>The relative location of the coordinate with respect to the polygon.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public static RelativeLocation Location(IBasicPolygon polygon, Coordinate coordinate, PrecisionModel precision) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } return(ComputeLocation(polygon.Shell, polygon.Holes, coordinate, precision)); }
/// <summary> /// Computes the approximate convex hull of the specified polygon. /// </summary> /// <param name="source">The source polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The approximate convex hull of <paramref name="source" />.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public static IReadOnlyList <Coordinate> ApproximateConvexHull(IBasicPolygon source, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException(nameof(source)); } return(new BentleyFaustPreparataAlgorithm(source.Shell, precisionModel).Result); }
/// <summary> /// Initializes a new instance of the <see cref="PolygonCentroidAlgorithm" /> class. /// </summary> /// <param name="polygon">The source polygon.</param> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public PolygonCentroidAlgorithm(IBasicPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } this.Shell = polygon.Shell; this.Holes = polygon.Holes; this.hasResult = false; }
/// <summary> /// Computes the approximate convex hull of the specified polygon. /// </summary> /// <param name="source">The source polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The approximate convex hull of <see cref="source" />.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public static IList <Coordinate> ApproximateConvexHull(IBasicPolygon source, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(null); } return(new BentleyFaustPreparataAlgorithm(source.Shell.Coordinates, precisionModel).Result); }
/// <summary> /// Determines the triangles of the polygon. /// </summary> /// <param name="source">The polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <exception cref="System.ArgumentNullException">The shell is null.</exception> public static IList <Coordinate[]> Triangulate(IBasicPolygon source, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(null); } return(new MonotoneSubdivisionAlgorithm(source.Shell.Coordinates, precisionModel).Result); }
/// <summary> /// Determines whether a coordinate is inside a polygon. /// </summary> /// <param name="source">The polygon.</param> /// <param name="coordinate">The coordinate.</param> /// <returns><c>true</c> if the polygon contains <paramref name="coordinate"/>; otherwise, <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <remarks> /// This method might also result <c>true</c> for coordinates on the boundary of the polygon. /// </remarks> public static Boolean IsInsidePolygon(IBasicPolygon source, Coordinate coordinate, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(false); } return(IsInsidePolygon(source.Shell, source.Holes, coordinate, precisionModel)); }
/// <summary> /// Computes the convex hull of the specified polygon. /// </summary> /// <param name="source">The source polygon.</param> /// <param name="precision">The precision model.</param> /// <returns>The convex hull of <see cref="source" />.</returns> /// <exception cref="System.ArgumentNullException">The source is null.</exception> public static IList <Coordinate> ComputeConvexHull(IBasicPolygon source, PrecisionModel precision) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(null); } return(new GrahamScanAlgorithm(source.Shell.Coordinates, precision).Result); }
/// <summary> /// Determines whether the specified polygon is convex. /// </summary> /// <param name="polygon">The polygon.</param> /// <returns><c>true</c> if the polygon is convex; otherwise <c>false</c>.</returns> /// <exception cref="System.ArgumentNullException">The polygon is null.</exception> public static Boolean IsConvex(IBasicPolygon polygon) { if (polygon == null) { throw new ArgumentNullException(nameof(polygon)); } if (polygon.HoleCount > 0) { return(false); } return(IsConvex(polygon.Shell)); }
/// <summary> /// Initializes a new instance of the <see cref="MinkowskiSumAlgorithm"/> class. /// </summary> /// <param name="source">The source.</param> /// <param name="buffer">The buffer.</param> /// <exception cref="System.ArgumentNullException">The source is null.</exception> /// <exception cref="System.ArgumentNullException">The buffer is null.</exception> /// <exception cref="System.ArgumentException">The orientation of the source is not suitable.</exception> /// <exception cref="System.ArgumentException">The orientation of the buffer is not suitable.</exception> public MinkowskiSumAlgorithm(IBasicPolygon source, IBasicPolygon buffer) { if (source == null) { throw new ArgumentNullException(nameof(source), "The source is null."); } if (buffer == null) { throw new ArgumentNullException(nameof(buffer), "The buffer is null."); } _sourceShellCoordinates = new List <Coordinate>(); foreach (Coordinate coordinate in source.Shell.Coordinates) { _sourceShellCoordinates.Add(coordinate); } if (PolygonAlgorithms.Orientation(_sourceShellCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the source is not suitable.", nameof(source)); } _sourceHoleCoordinates = new List <IList <Coordinate> >(); for (Int32 holeIndex = 0; holeIndex < source.HoleCount; holeIndex++) { _sourceHoleCoordinates.Add(new List <Coordinate>()); foreach (Coordinate coordinate in source.Holes[holeIndex].Coordinates) { _sourceHoleCoordinates[holeIndex].Add(coordinate); } if (PolygonAlgorithms.Orientation(_sourceHoleCoordinates[holeIndex]) != Orientation.Clockwise) { throw new ArgumentException("The orientation of the source is not suitable.", nameof(source)); } } _bufferCoordinates = new List <Coordinate>(); foreach (Coordinate coordinate in buffer.Shell.Coordinates) { _bufferCoordinates.Add(coordinate); } if (PolygonAlgorithms.Orientation(_bufferCoordinates) != Orientation.CounterClockwise) { throw new ArgumentException("The orientation of the buffer is not suitable.", nameof(buffer)); } _hasResult = false; }
public void MonotoneSubdivisionTriangulateTest() { for (Int32 polygonNumber = 1; polygonNumber < 10; polygonNumber++) { IBasicPolygon polygon = RandomPolygonGenerator.CreateRandomPolygon(10 * polygonNumber, new Coordinate(10, 10), new Coordinate(50, 50)); IReadOnlyList <Coordinate[]> triangles = MonotoneSubdivisionAlgorithm.Triangulate(polygon.Shell); triangles.Count.ShouldBe(polygon.Shell.Count - 3); foreach (Coordinate[] triangle in triangles) { triangle.Length.ShouldBe(3); triangle.ShouldBeSubsetOf(polygon.Shell); } } }
/// <summary> /// Create a ShapeRange from a Geometry to use in constructing a Shape /// </summary> /// <param name="geometry"></param> /// <param name="vertices"></param> /// <param name="offset">offset into vertices array where this feature starts</param> /// <returns></returns> public static ShapeRange ShapeRangeFromGeometry(IBasicGeometry geometry, double[] vertices, int offset) { var featureType = geometry.FeatureType; ShapeRange shx = new ShapeRange(featureType) { Extent = new Extent(geometry.Envelope) }; int vIndex = offset / 2; shx.Parts = new List <PartRange>(); int shapeStart = vIndex; for (int part = 0; part < geometry.NumGeometries; part++) { PartRange prtx = new PartRange(vertices, shapeStart, vIndex - shapeStart, featureType); IBasicPolygon bp = geometry.GetBasicGeometryN(part) as IBasicPolygon; if (bp != null) { // Account for the Shell prtx.NumVertices = bp.Shell.NumPoints; vIndex += bp.Shell.NumPoints; // The part range should be adjusted to no longer include the holes foreach (var hole in bp.Holes) { PartRange holex = new PartRange(vertices, shapeStart, vIndex - shapeStart, featureType) { NumVertices = hole.NumPoints }; shx.Parts.Add(holex); vIndex += hole.NumPoints; } } else { int numPoints = geometry.GetBasicGeometryN(part).NumPoints; // This is not a polygon, so just add the number of points. vIndex += numPoints; prtx.NumVertices = numPoints; } shx.Parts.Add(prtx); } return(shx); }
/// <summary> /// Compares two <see cref="IBasicPolygon" /> instances and returns a value indicating whether one is less than, equal to, or greater than the other. /// </summary> /// <param name="x">The first <see cref="IBasicPolygon" /> to compare.</param> /// <param name="y">The second <see cref="IBasicPolygon" /> to compare.</param> /// <returns>A signed integer that indicates the relative values of <paramref name="x" /> and <paramref name="y" />.</returns> /// <exception cref="System.ArgumentNullException"> /// The x argument is null. /// or /// The y argument is null. /// </exception> public Int32 Compare(IBasicPolygon x, IBasicPolygon y) { if (x == null) { throw new ArgumentNullException("x", "The x argument is null."); } if (y == null) { throw new ArgumentNullException("y", "The y argument is null."); } if (x == y) { return(0); } // check the shell Int32 shellCompare = Compare(x.Shell, y.Shell); if (shellCompare != 0) { return(shellCompare); } Int32 index = 0; // look for the first different hole in the polygon while (index < x.HoleCount && index < y.HoleCount) { Int32 holeCompare = Compare(x.GetHole(index), y.GetHole(index)); if (holeCompare != 0) { return(holeCompare); } index++; } // check whether there are additional holes in either polygon if (index < x.HoleCount) { return(1); } if (index < y.HoleCount) { return(-1); } return(0); }
/// <summary> /// If the input geometry is a singular basic geometry, this will become a collection of 1 geometry. /// If the input geometry is a multi- basic geometry, this will simply ensure that each member /// is upgraded to a full geometry. /// </summary> /// <param name="inGeometry"></param> /// <param name="inFactory"></param> public GeometryCollection(IBasicGeometry inGeometry, IGeometryFactory inFactory) : base(inFactory) { if (inGeometry == null) { _geometries = new IGeometry[] { }; return; } IBasicPolygon pg = inGeometry.GetBasicGeometryN(0) as IBasicPolygon; if (pg != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pg = inGeometry.GetBasicGeometryN(iGeom) as IBasicPolygon; _geometries[iGeom] = new Polygon(pg); } return; } IBasicPoint pt = inGeometry.GetBasicGeometryN(0) as IBasicPoint; if (pt != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { pt = inGeometry.GetBasicGeometryN(iGeom) as IBasicPoint; _geometries[iGeom] = new Point(pt); } return; } IBasicLineString ls = inGeometry.GetBasicGeometryN(0) as IBasicLineString; if (ls != null) { _geometries = new IGeometry[inGeometry.NumGeometries]; for (int iGeom = 0; iGeom < inGeometry.NumGeometries; iGeom++) { ls = inGeometry.GetBasicGeometryN(iGeom) as IBasicLineString; _geometries[iGeom] = new LineString(ls); } return; } }
/// <summary> /// Compute the centroid of the polygon. /// </summary> /// <param name="source">The polygon.</param> /// <param name="precisionModel">The precision model.</param> /// <returns>The centroid of the polygon.</returns> public static Coordinate ComputeCentroid(IBasicPolygon source, PrecisionModel precisionModel) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } if (source.Shell == null || source.Shell.Coordinates == null) { return(Coordinate.Undefined); } PolygonCentroidAlgorithm algorithm = new PolygonCentroidAlgorithm(source.Shell.Coordinates, source.Holes != null ? source.Holes.Select(hole => hole != null ? hole.Coordinates : null) : null, precisionModel); algorithm.Compute(); return(algorithm.Result); }
/// <summary> /// Constructor for a polygon /// </summary> /// <param name="polygonBase">A simpler BasicPolygon to empower with topology functions</param> public Polygon(IBasicPolygon polygonBase) : base(DefaultFactory) { SetHoles(polygonBase.Holes); LinearRing shell = new LinearRing(polygonBase.Shell); if (HasNullElements(_holes)) { throw new PolygonException(TopologyText.PolygonException_HoleElementNull); } if (shell.IsEmpty && HasNonEmptyElements(_holes)) { throw new PolygonException(TopologyText.PolygonException_ShellEmptyButHolesNot); } _shell = shell; }
/// <summary> /// Clips a polygons with an envelope. /// </summary> /// <param name="source">The polygon to clip.</param> /// <param name="window">The clipping window.</param> /// <returns>The clipped coordinates.</returns> /// <exception cref="System.ArgumentNullException"> /// The source is null. /// or /// The clipping window is null. /// </exception> public static IEnumerable <IList <Coordinate> > Clip(IBasicPolygon source, Envelope window) { if (source == null) { throw new ArgumentNullException("source", "The source is null."); } List <IList <Coordinate> > coordinates = new List <IList <Coordinate> >(); coordinates.Add(source.Shell.Coordinates); foreach (IBasicLineString linestring in source.Holes) { coordinates.Add(linestring.Coordinates); } return(new CyrusBeckAlgorithm(coordinates, window).Result); }
private List<IBasicPolygon> GetYNeighbours(IBasicPolygon polygon) { var neighbours = new List<IBasicPolygon>(); for (int y = polygon.Coordintes.Y - 1; y <= polygon.Coordintes.Y + 1; y++) { if (y == polygon.Coordintes.Y) { continue; } var cell = GetCell(new Point3d() { X = polygon.Coordintes.X, Y = y, Z = 0 }); if (cell != null) { neighbours.Add(cell); } } return neighbours; }
private List<IBasicPolygon> GetXNeighbours(IBasicPolygon polygon) { var neighbours = new List<IBasicPolygon>(); for (int x = polygon.Coordintes.X - 1; x <= polygon.Coordintes.X + 1; x++) { if (x == polygon.Coordintes.X) { continue; } var cell = GetCell(new Point3d() { X = x, Y = polygon.Coordintes.Y, Z = 0 }); if (cell != null) { neighbours.Add(cell); } } return neighbours; }
/// <summary> /// Constructor for a polygon /// </summary> /// <param name="polygonBase">A simpler BasicPolygon to empower with topology functions</param> public Polygon(IBasicPolygon polygonBase) : base(DefaultFactory) { SetHoles(polygonBase.Holes); LinearRing shell = new LinearRing(polygonBase.Shell); if (HasNullElements(_holes)) throw new PolygonException(TopologyText.PolygonException_HoleElementNull); if (shell.IsEmpty && HasNonEmptyElements(_holes)) throw new PolygonException(TopologyText.PolygonException_ShellEmptyButHolesNot); _shell = shell; }
private bool HasNeighbourWithState(IBasicPolygon polygon, PolygonState state) { var neighbours = GetNeighbours(polygon); return neighbours.Where(cn => cn.State == state).Count() > 0; }
/// <summary> /// This was added by Ted Dunsford to allow the construction of MultiPolygons /// from an array of basic polygon interfaces. /// </summary> /// <param name="polygons"></param> public MultiPolygon(IBasicPolygon[] polygons) : base(polygons, DefaultFactory) { }