/// <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));
        }
예제 #2
0
        /// <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));
        }
예제 #5
0
        /// <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;
        }
예제 #7
0
        /// <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);
        }
예제 #8
0
        private List<IBasicPolygon> GetNeighbours(IBasicPolygon polygon)
        {
            var neighbours = new List<IBasicPolygon>();

            neighbours.AddRange(GetXNeighbours(polygon));
            neighbours.AddRange(GetYNeighbours(polygon));

            return neighbours;
        }
예제 #9
0
        /// <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));
        }
예제 #10
0
        /// <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));
        }
예제 #11
0
        /// <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)));
        }
예제 #12
0
        /// <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);
        }
예제 #13
0
        /// <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);
        }
예제 #14
0
        /// <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));
        }
예제 #15
0
        /// <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));
        }
예제 #16
0
        /// <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));
        }
예제 #17
0
        /// <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);
        }
예제 #18
0
        /// <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);
        }
예제 #23
0
        /// <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;
        }
예제 #25
0
        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);
                }
            }
        }
예제 #26
0
        /// <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);
        }
예제 #27
0
        /// <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);
        }
예제 #28
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);
        }
예제 #30
0
        /// <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);
        }
예제 #32
0
        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;
        }
예제 #33
0
        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;
        }
예제 #34
0
        /// <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;
        }
예제 #35
0
        private bool HasNeighbourWithState(IBasicPolygon polygon, PolygonState state)
        {
            var neighbours = GetNeighbours(polygon);

            return neighbours.Where(cn => cn.State == state).Count() > 0;
        }
예제 #36
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) { }