Ejemplo n.º 1
0
        /// <summary>
        /// Determines whether the area contains a geographic coordinate.
        /// </summary>
        /// <param name="coordinate">The coordinate.</param>
        /// <returns><c>true</c> if the coordinate is within the area; otherwise, <c>false</c>.</returns>
        public Boolean Contains(GeoCoordinate coordinate)
        {
            if (coordinate == null)
            {
                return(false);
            }

            // if the boundary is specified, the contained can be determined more exactly
            if (this.Boundary != null)
            {
                return(!WindingNumberAlgorithm.InExterior(this.Boundary.Select(coord => (Coordinate)coord).ToArray(), (Coordinate)coordinate));
            }

            return((this.West <= this.East && this.West <= coordinate.Latitude && coordinate.Latitude <= this.East) ||
                   (this.West > this.East && ((this.West - Angle.FromRadian(2 * Math.PI) <= coordinate.Latitude && coordinate.Latitude <= this.East) ||
                                              (this.West <= coordinate.Latitude && coordinate.Latitude <= this.East + Angle.FromRadian(2 * Math.PI)))));
        }
        public void WindingNumberAlgorithmLocationCheckingTest()
        {
            // simple polygon

            Coordinate[] shell = new Coordinate[]
            {
                new Coordinate(0, 0),
                new Coordinate(20, 0),
                new Coordinate(15, 5),
                new Coordinate(20, 10),
                new Coordinate(0, 20),
                new Coordinate(0, 0),
            };

            Coordinate coordinate = new Coordinate(-1, 7);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(0, 0);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(0, 5);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(1, 1);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(3, 3);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(5, 8);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(6, 0);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(8, 4);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(8, 22);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(12, -2);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(12, 8);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(15, 5);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(15, 9);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(16, 1);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(19, 3);
            WindingNumberAlgorithm.InInterior(shell, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, coordinate).ShouldBeFalse();

            // polygon with holes

            shell = new Coordinate[]
            {
                new Coordinate(0, 0),
                new Coordinate(20, 0),
                new Coordinate(15, 5),
                new Coordinate(20, 10),
                new Coordinate(0, 20),
                new Coordinate(0, 0),
            };

            Coordinate[] hole1 = new Coordinate[]
            {
                new Coordinate(2, 2),
                new Coordinate(2, 4),
                new Coordinate(4, 4),
                new Coordinate(4, 2),
                new Coordinate(2, 2),
            };
            Coordinate[] hole2 = new Coordinate[]
            {
                new Coordinate(10, 7),
                new Coordinate(10, 9),
                new Coordinate(16, 9),
                new Coordinate(16, 7),
                new Coordinate(10, 7),
            };

            coordinate = new Coordinate(-1, 7);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(0, 0);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(0, 5);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(1, 1);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(3, 3);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(5, 8);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(6, 0);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(8, 4);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(8, 22);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(12, -2);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(12, 8);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(15, 5);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(15, 9);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();

            coordinate = new Coordinate(16, 1);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();

            coordinate = new Coordinate(19, 3);
            WindingNumberAlgorithm.InInterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
            WindingNumberAlgorithm.InExterior(shell, new[] { hole1, hole2 }, coordinate).ShouldBeTrue();
            WindingNumberAlgorithm.OnBoundary(shell, new[] { hole1, hole2 }, coordinate).ShouldBeFalse();
        }