public void WindingNumberAlgorithmLocationTest() { // simple convex polygon Coordinate[] polygon = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0), }; WindingNumberAlgorithm.Location(polygon, new Coordinate(0, 5)).ShouldBe(RelativeLocation.Boundary); WindingNumberAlgorithm.Location(polygon, new Coordinate(10, 5)).ShouldBe(RelativeLocation.Boundary); WindingNumberAlgorithm.Location(polygon, new Coordinate(5, 0)).ShouldBe(RelativeLocation.Boundary); WindingNumberAlgorithm.Location(polygon, new Coordinate(10, 10)).ShouldBe(RelativeLocation.Boundary); WindingNumberAlgorithm.Location(polygon, new Coordinate(5, 5)).ShouldBe(RelativeLocation.Interior); WindingNumberAlgorithm.Location(polygon, new Coordinate(15, 5)).ShouldBe(RelativeLocation.Exterior); WindingNumberAlgorithm.Location(polygon, new Coordinate(0, 5)).ShouldBe(RelativeLocation.Boundary); // simple convex polygon with negative coordinates polygon = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, -5), new Coordinate(10, 15), new Coordinate(0, 10), new Coordinate(0, 0), }; WindingNumberAlgorithm.Location(polygon, new Coordinate(5, 12.5)).ShouldBe(RelativeLocation.Boundary); WindingNumberAlgorithm.Location(polygon, new Coordinate(5, 10)).ShouldBe(RelativeLocation.Interior); WindingNumberAlgorithm.Location(polygon, new Coordinate(-5, 0)).ShouldBe(RelativeLocation.Exterior); }
/// <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(); }
public void WindingNumberAlgorithmIsInsidePolygonTest() { // simple convex polygon Coordinate[] shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0), }; Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(5, 5))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(10, 5))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(15, 5))); // simple convex polygon with negative coordinates shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, -5), new Coordinate(10, 15), new Coordinate(0, 10), new Coordinate(0, 0), }; Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(5, 5))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(5, 0))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(5, 10))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 0))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 10))); // convex polygon with holes shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(20, 0), new Coordinate(20, 20), new Coordinate(0, 20), new Coordinate(0, 0), }; Coordinate[] hole1 = new Coordinate[] { new Coordinate(5, 5), new Coordinate(5, 10), new Coordinate(10, 10), new Coordinate(10, 5), new Coordinate(5, 5), }; Coordinate[] hole2 = new Coordinate[] { new Coordinate(10, 10), new Coordinate(5, 15), new Coordinate(15, 15), new Coordinate(15, 10), new Coordinate(10, 10), }; Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new List <Coordinate[]>() { hole1, hole2 }, new Coordinate(10, 10))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new List <Coordinate[]>() { hole1, hole2 }, new Coordinate(18, 8))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new List <Coordinate[]>() { hole1, hole2 }, new Coordinate(12, 2))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new List <Coordinate[]>() { hole1, hole2 }, new Coordinate(12, 12))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new List <Coordinate[]>() { hole1, hole2 }, new Coordinate(8, 8))); // concave polygon shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(15, 0), new Coordinate(15, 5), new Coordinate(12, 5), new Coordinate(12, 7), new Coordinate(10, 7), new Coordinate(10, 5), new Coordinate(5, 5), new Coordinate(5, 10), new Coordinate(0, 10), new Coordinate(0, 0), }; Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(3, 3))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(3, 5))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(3, 7))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(3, 12))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(11, 3))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(11, 5))); Assert.IsTrue(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(11, 6))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(11, 8))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 3))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 5))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 6))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 7))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 8))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(-5, 12))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(4, -1))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(5, -1))); Assert.IsFalse(WindingNumberAlgorithm.IsInsidePolygon(shell, new Coordinate(20, -1))); }
public void WindingNumberAlgorithmIsOnBoundaryTest() { // simple convex polygon Coordinate[] shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, 0), new Coordinate(10, 10), new Coordinate(0, 10), new Coordinate(0, 0), }; WindingNumberAlgorithm algorithm = new WindingNumberAlgorithm(shell, new Coordinate(0, 5), true, PrecisionModel.Default); algorithm.Compute(); Assert.IsTrue(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(10, 5); algorithm.Compute(); Assert.IsTrue(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(5, 0); algorithm.Compute(); Assert.IsTrue(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(10, 10); algorithm.Compute(); Assert.IsTrue(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(5, 5); algorithm.Compute(); Assert.IsFalse(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(15, 5); algorithm.Compute(); Assert.IsFalse(algorithm.IsOnBoundary.Value); // simple convex polygon with negative coordinates shell = new Coordinate[] { new Coordinate(0, 0), new Coordinate(10, -5), new Coordinate(10, 15), new Coordinate(0, 10), new Coordinate(0, 0), }; algorithm = new WindingNumberAlgorithm(shell, new Coordinate(5, 12.5), true, PrecisionModel.Default); algorithm.Compute(); Assert.IsTrue(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(5, 10); algorithm.Compute(); Assert.IsFalse(algorithm.IsOnBoundary.Value); algorithm.Coordinate = new Coordinate(-5, 0); algorithm.Compute(); Assert.IsFalse(algorithm.IsOnBoundary.Value); }