/// <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(); }