/// <summary> /// Compute the overall ON location for the list of EdgeStubs. /// (This is essentially equivalent to computing the self-overlay of a single Geometry) /// edgeStubs can be either on the boundary (e.g. Polygon edge) /// OR in the interior (e.g. segment of a LineString) /// of their parent Geometry. /// In addition, GeometryCollections use the <see cref="IBoundaryNodeRule"/> to determine /// whether a segment is on the boundary or not. /// Finally, in GeometryCollections it can occur that an edge is both /// on the boundary and in the interior (e.g. a LineString segment lying on /// top of a Polygon edge.) In this case the Boundary is given precedence. /// These observations result in the following rules for computing the ON location: /// if there are an odd number of Bdy edges, the attribute is Bdy /// if there are an even number >= 2 of Bdy edges, the attribute is Int /// if there are any Int edges, the attribute is Int /// otherwise, the attribute is Null. /// </summary> /// <param name="geomIndex"></param> /// <param name="boundaryNodeRule"></param> private void ComputeLabelOn(int geomIndex, IBoundaryNodeRule boundaryNodeRule) { // compute the On location value int boundaryCount = 0; bool foundInterior = false; Location loc; foreach (EdgeEnd e in _edgeEnds) { loc = e.Label.GetLocation(geomIndex); if (loc == Location.Boundary) { boundaryCount++; } if (loc == Location.Interior) { foundInterior = true; } } loc = Location.Null; if (foundInterior) { loc = Location.Interior; } if (boundaryCount > 0) { loc = GeometryGraph.DetermineBoundary(boundaryNodeRule, boundaryCount); } Label.SetLocation(geomIndex, loc); }
/// <summary> /// This computes the overall edge label for the set of /// edges in this EdgeStubBundle. It essentially merges /// the ON and side labels for each edge. /// These labels must be compatible /// </summary> /// <param name="boundaryNodeRule"></param> public override void ComputeLabel(IBoundaryNodeRule boundaryNodeRule) { // create the label. If any of the edges belong to areas, // the label must be an area label bool isArea = false; foreach (EdgeEnd e in _edgeEnds) { if (e.Label.IsArea()) { isArea = true; } } if (isArea) { Label = new Label(Location.Null, Location.Null, Location.Null); } else { Label = new Label(Location.Null); } // compute the On label, and the side labels if present for (int i = 0; i < 2; i++) { ComputeLabelOn(i, boundaryNodeRule); if (isArea) { ComputeLabelSides(i); } } }
/// <summary> /// Computes the <see cref="IntersectionMatrix"/> for the spatial relationship /// between two <see cref="IGeometry"/>s, using the specified Boundary Node Rule /// </summary> /// <param name="a">A geometry to test</param> /// <param name="b">A geometry to test</param> /// <param name="boundaryNodeRule">The Boundary Node Rule to use</param> /// <returns>The <c>IntersectionMatrix</c> for the spatial relationship between the geometries</returns> public static IntersectionMatrix Relate(IGeometry a, IGeometry b, IBoundaryNodeRule boundaryNodeRule) { var relOp = new RelateOp(a, b, boundaryNodeRule); var im = relOp.IntersectionMatrix; return(im); }
/// <summary> /// Initializes a new instance of the <see cref="PointLocator"/> class using the provided /// <paramref name="boundaryRule">boundary rule</paramref>. /// </summary> /// <param name="boundaryRule">The boundary rule to use.</param> public PointLocator(IBoundaryNodeRule boundaryRule) { if (boundaryRule == null) { throw new ArgumentException("Rule must be non-null"); } _boundaryRule = boundaryRule; }
/// <summary> /// /// </summary> private void ComputeEdgeEndLabels(IBoundaryNodeRule boundaryNodeRule) { // Compute edge label for each EdgeEnd foreach (var ee in Edges) { ee.ComputeLabel(boundaryNodeRule); } }
/// <summary> /// /// </summary> /// <param name="argIndex"></param> /// <param name="parentGeom"></param> /// <param name="boundaryNodeRule"></param> public GeometryGraph(int argIndex, IGeometry parentGeom, IBoundaryNodeRule boundaryNodeRule) { _argIndex = argIndex; _boundaryNodeRule = boundaryNodeRule; _parentGeom = parentGeom; if (parentGeom != null) Add(parentGeom); }
void RunRelateTest(string wkt1, string wkt2, IBoundaryNodeRule bnRule, string expectedIM) { var g1 = _rdr.Read(wkt1); var g2 = _rdr.Read(wkt2); var im = RelateOp.Relate(g1, g2, bnRule); string imStr = im.ToString(); //TestContext.WriteLine(imStr); Assert.IsTrue(im.Matches(expectedIM)); }
void RunRelateTest(String wkt1, String wkt2, IBoundaryNodeRule bnRule, String expectedIM) { IGeometry g1 = rdr.Read(wkt1); IGeometry g2 = rdr.Read(wkt2); IntersectionMatrix im = RelateOp.Relate(g1, g2, bnRule); String imStr = im.ToString(); Console.WriteLine(imStr); Assert.IsTrue(im.Matches(expectedIM)); }
public GeometryGraphOperation(IGeometry g0, IGeometry g1, IBoundaryNodeRule boundaryNodeRule) { // use the most precise model for the result if (g0.PrecisionModel.CompareTo(g1.PrecisionModel) >= 0) ComputationPrecision = g0.PrecisionModel; else ComputationPrecision = g1.PrecisionModel; arg = new GeometryGraph[2]; arg[0] = new GeometryGraph(0, g0, boundaryNodeRule); arg[1] = new GeometryGraph(1, g1, boundaryNodeRule); }
/// <summary> /// /// </summary> /// <param name="boundaryNodeRule"></param> /// <param name="e"></param> public EdgeEndBundle(IBoundaryNodeRule boundaryNodeRule, EdgeEnd e) : base(e.Edge, e.Coordinate, e.DirectedCoordinate, new Label(e.Label)) { /* * if (boundaryNodeRule != null) * this.boundaryNodeRule = boundaryNodeRule; * else * boundaryNodeRule = BoundaryNodeRules.OgcSfsBoundaryRule; */ Insert(e); }
/// <summary> /// /// </summary> /// <param name="boundaryNodeRule"></param> /// <param name="e"></param> public EdgeEndBundle(IBoundaryNodeRule boundaryNodeRule, EdgeEnd e) : base(e.Edge, e.Coordinate, e.DirectedCoordinate, new Label(e.Label)) { /* if (boundaryNodeRule != null) this.boundaryNodeRule = boundaryNodeRule; else boundaryNodeRule = BoundaryNodeRules.OgcSfsBoundaryRule; */ Insert(e); }
private static void RunBoundaryTest(String wkt, IBoundaryNodeRule bnRule, String wktExpected) { IGeometry g = rdr.Read(wkt); IGeometry expected = rdr.Read(wktExpected); BoundaryOp op = new BoundaryOp(g, bnRule); IGeometry boundary = op.GetBoundary(); boundary.Normalize(); // System.out.println("Computed Boundary = " + boundary); Assert.IsTrue(boundary.EqualsExact(expected)); }
private void RunBoundaryTest(string wkt, IBoundaryNodeRule bnRule, string wktExpected) { var g = _rdr.Read(wkt); var expected = _rdr.Read(wktExpected); var op = new BoundaryOp(g, bnRule); var boundary = op.GetBoundary(); boundary.Normalize(); // System.out.println("Computed Boundary = " + boundary); Assert.IsTrue(boundary.EqualsExact(expected)); }
public GeometryGraphOperation(IGeometry g0, IGeometry g1, IBoundaryNodeRule boundaryNodeRule) { // use the most precise model for the result if (g0.PrecisionModel.CompareTo(g1.PrecisionModel) >= 0) { ComputationPrecision = g0.PrecisionModel; } else { ComputationPrecision = g1.PrecisionModel; } arg = new GeometryGraph[2]; arg[0] = new GeometryGraph(0, g0, boundaryNodeRule); arg[1] = new GeometryGraph(1, g1, boundaryNodeRule); }
private static void RunIsSimpleTest(String wkt, IBoundaryNodeRule bnRule, bool expectedResult, Coordinate expectedLocation) { IGeometry g = rdr.Read(wkt); IsSimpleOp op = new IsSimpleOp(g, bnRule); bool isSimple = op.IsSimple(); Coordinate nonSimpleLoc = op.NonSimpleLocation; // if geom is not simple, should have a valid location Assert.IsTrue(isSimple || nonSimpleLoc != null); Assert.IsTrue(expectedResult == isSimple); if (!isSimple && expectedLocation != null) { Assert.IsTrue(expectedLocation.Distance(nonSimpleLoc) < Tolerance); } }
/// <summary> /// This computes the overall edge label for the set of /// edges in this EdgeStubBundle. It essentially merges /// the ON and side labels for each edge. /// These labels must be compatible /// </summary> /// <param name="boundaryNodeRule"></param> public override void ComputeLabel(IBoundaryNodeRule boundaryNodeRule) { // create the label. If any of the edges belong to areas, // the label must be an area label bool isArea = false; foreach (EdgeEnd e in _edgeEnds) { if (e.Label.IsArea()) isArea = true; } if (isArea) Label = new Label(Location.Null, Location.Null, Location.Null); else Label = new Label(Location.Null); // compute the On label, and the side labels if present for (int i = 0; i < 2; i++) { ComputeLabelOn(i, boundaryNodeRule); if (isArea) ComputeLabelSides(i); } }
public static IGeometry GetBoundary(IGeometry g, IBoundaryNodeRule bnRule) { var bop = new BoundaryOp(g, bnRule); return bop.GetBoundary(); }
public BoundaryOp(IGeometry geom, IBoundaryNodeRule bnRule) { _geom = geom; _geomFact = geom.Factory; _bnRule = bnRule; }
public static IGeometry GetBoundary(IGeometry g, IBoundaryNodeRule bnRule) { var bop = new BoundaryOp(g, bnRule); return(bop.GetBoundary()); }
/// <summary> /// Compute the overall ON location for the list of EdgeStubs. /// (This is essentially equivalent to computing the self-overlay of a single Geometry) /// edgeStubs can be either on the boundary (eg Polygon edge) /// OR in the interior (e.g. segment of a LineString) /// of their parent Geometry. /// In addition, GeometryCollections use the <see cref="IBoundaryNodeRule"/> to determine /// whether a segment is on the boundary or not. /// Finally, in GeometryCollections it can occur that an edge is both /// on the boundary and in the interior (e.g. a LineString segment lying on /// top of a Polygon edge.) In this case the Boundary is given precendence. /// These observations result in the following rules for computing the ON location: /// if there are an odd number of Bdy edges, the attribute is Bdy /// if there are an even number >= 2 of Bdy edges, the attribute is Int /// if there are any Int edges, the attribute is Int /// otherwise, the attribute is Null. /// </summary> /// <param name="geomIndex"></param> /// <param name="boundaryNodeRule"></param> private void ComputeLabelOn(int geomIndex, IBoundaryNodeRule boundaryNodeRule) { // compute the On location value int boundaryCount = 0; bool foundInterior = false; Location loc; foreach (EdgeEnd e in _edgeEnds) { loc = e.Label.GetLocation(geomIndex); if (loc == Location.Boundary) boundaryCount++; if (loc == Location.Interior) foundInterior = true; } loc = Location.Null; if (foundInterior) loc = Location.Interior; if (boundaryCount > 0) loc = GeometryGraph.DetermineBoundary(boundaryNodeRule, boundaryCount); Label.SetLocation(geomIndex, loc); }
/// <summary> /// Computes the <see cref="IntersectionMatrix"/> for the spatial relationship /// between two <see cref="IGeometry"/>s, using the specified Boundary Node Rule /// </summary> /// <param name="a">A geometry to test</param> /// <param name="b">A geometry to test</param> /// <param name="boundaryNodeRule">The Boundary Node Rule to use</param> /// <returns>The IntersectonMatrix for the spatial relationship between the geometries</returns> public static IntersectionMatrix Relate(IGeometry a, IGeometry b, IBoundaryNodeRule boundaryNodeRule) { RelateOp relOp = new RelateOp(a, b, boundaryNodeRule); IntersectionMatrix im = relOp.IntersectionMatrix; return im; }
/// <summary> /// Creates a new Relate operation, using the default (OGC SFS) Boundary Node Rule. /// </summary> /// <param name="g0">a Geometry to relate</param> /// <param name="g1">another Geometry to relate</param> /// <param name="boundaryNodeRule">The Boundary Node Rule to use</param> public RelateOp(IGeometry g0, IGeometry g1, IBoundaryNodeRule boundaryNodeRule) : base(g0, g1, boundaryNodeRule) { _relate = new RelateComputer(arg); }
/// <summary> /// Subclasses should override this if they are using labels /// </summary> /// <param name="boundaryNodeRule"></param> public virtual void ComputeLabel(IBoundaryNodeRule boundaryNodeRule) { }
///<summary> /// Creates a simplicity checker using a given <see cref="IBoundaryNodeRule"/> ///</summary> /// <param name="geom">The geometry to test</param> /// <param name="boundaryNodeRule">The rule to use</param> public IsSimpleOp(IGeometry geom, IBoundaryNodeRule boundaryNodeRule) { _inputGeom = geom; _isClosedEndpointsInInterior = !boundaryNodeRule.IsInBoundary(2); }
public PointLocator(IBoundaryNodeRule boundaryRule) { if (boundaryRule == null) throw new ArgumentException("Rule must be non-null"); _boundaryRule = boundaryRule; }
/// <summary> /// This method implements the Boundary Determination Rule /// for determining whether /// a component (node or edge) that appears multiple times in elements /// of a MultiGeometry is in the boundary or the interior of the Geometry. /// The SFS uses the "Mod-2 Rule", which this function implements. /// An alternative (and possibly more intuitive) rule would be /// the "At Most One Rule": /// isInBoundary = (componentCount == 1) /// </summary> /* * public static bool IsInBoundary(int boundaryCount) * { * // the "Mod-2 Rule" * return boundaryCount % 2 == 1; * }*/ public static Location DetermineBoundary(IBoundaryNodeRule boundaryNodeRule, int boundaryCount) { return(boundaryNodeRule.IsInBoundary(boundaryCount) ? Location.Boundary : Location.Interior); }
private static void RunIsSimpleTest(String wkt, IBoundaryNodeRule bnRule, bool expectedResult) { RunIsSimpleTest(wkt, bnRule, expectedResult, null); }
/// <summary> /// Creates a simplicity checker using a given <see cref="IBoundaryNodeRule"/> /// </summary> /// <param name="geom">The geometry to test</param> /// <param name="boundaryNodeRule">The rule to use</param> public IsSimpleOp(Geometry geom, IBoundaryNodeRule boundaryNodeRule) { _inputGeom = geom; _isClosedEndpointsInInterior = !boundaryNodeRule.IsInBoundary(2); }
/// <summary> /// This method implements the Boundary Determination Rule /// for determining whether /// a component (node or edge) that appears multiple times in elements /// of a MultiGeometry is in the boundary or the interior of the Geometry. /// The SFS uses the "Mod-2 Rule", which this function implements. /// An alternative (and possibly more intuitive) rule would be /// the "At Most One Rule": /// isInBoundary = (componentCount == 1) /// </summary> /* public static bool IsInBoundary(int boundaryCount) { // the "Mod-2 Rule" return boundaryCount % 2 == 1; }*/ public static Location DetermineBoundary(IBoundaryNodeRule boundaryNodeRule, int boundaryCount) { return boundaryNodeRule.IsInBoundary(boundaryCount) ? Location.Boundary : Location.Interior; }