示例#1
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g0"></param>
        /// <param name="g1"></param>
        public OverlayOp(IGeometry g0, IGeometry g1)
            : base(g0, g1)
        {
            graph = new PlanarGraph(new OverlayNodeFactory());

            /*
            * Use factory of primary point.
            * Note that this does NOT handle mixed-precision arguments
            * where the second arg has greater precision than the first.
            */
            geomFact = g0.Factory;
        }
示例#2
0
        private IList CreateSubgraphs(PlanarGraph graph)
        {
            ArrayList subgraphList = new ArrayList();
            foreach(object obj in graph.Nodes)
            {
                Node node = (Node)obj;
                if (!node.IsVisited)
                {
                    BufferSubgraph subgraph = new BufferSubgraph();
                    subgraph.Create(node);
                    subgraphList.Add(subgraph);
                }
            }

            /*
             * Sort the subgraphs in descending order of their rightmost coordinate.
             * This ensures that when the Polygons for the subgraphs are built,
             * subgraphs for shells will have been built before the subgraphs for
             * any holes they contain.
             */
            subgraphList.Sort();
            subgraphList.Reverse();
            return subgraphList;
        }
示例#3
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public IGeometry Buffer(IGeometry g, double distance)
        {
            IPrecisionModel precisionModel = workingPrecisionModel;
            if (precisionModel == null)
                precisionModel = g.PrecisionModel;

            // factory must be the same as the one used by the input
            geomFact = g.Factory;

            OffsetCurveBuilder curveBuilder = new OffsetCurveBuilder(precisionModel, quadrantSegments);
            curveBuilder.EndCapStyle = endCapStyle;
            OffsetCurveSetBuilder curveSetBuilder = new OffsetCurveSetBuilder(g, distance, curveBuilder);

            IList bufferSegStrList = curveSetBuilder.GetCurves();

            // short-circuit test
            if (bufferSegStrList.Count <= 0)
            {
                IGeometry emptyGeom = geomFact.CreateGeometryCollection(new IGeometry[0]);
                return emptyGeom;
            }

            ComputeNodedEdges(bufferSegStrList, precisionModel);
            graph = new PlanarGraph(new OverlayNodeFactory());
            graph.AddEdges(edgeList.Edges);

            IList subgraphList = CreateSubgraphs(graph);
            PolygonBuilder polyBuilder = new PolygonBuilder(geomFact);
            BuildSubgraphs(subgraphList, polyBuilder);
            IList resultPolyList = polyBuilder.Polygons;

            IGeometry resultGeom = geomFact.BuildGeometry(resultPolyList);
            return resultGeom;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <returns></returns>
        public bool IsInteriorsConnected()
        {
            // node the edges, in case holes touch the shell
            IList splitEdges = new ArrayList();
            geomGraph.ComputeSplitEdges(splitEdges);

            // form the edges into rings
            PlanarGraph graph = new PlanarGraph(new OverlayNodeFactory());
            graph.AddEdges(splitEdges);
            SetInteriorEdgesInResult(graph);
            graph.LinkResultDirectedEdges();
            IList edgeRings = BuildEdgeRings(graph.EdgeEnds);
            /*
             * Mark all the edges for the edgeRings corresponding to the shells
             * of the input polygons.  Note only ONE ring gets marked for each shell.
             */
            VisitShellInteriors((IGeometry) geomGraph.Geometry, graph);

            /*
             * If there are any unvisited shell edges
             * (i.e. a ring which is not a hole and which has the interior
             * of the parent area on the RHS)
             * this means that one or more holes must have split the interior of the
             * polygon into at least two pieces.  The polygon is thus invalid.
             */
            return !HasUnvisitedShellEdge(edgeRings);
        }
 /// <summary>
 /// Mark all the edges for the edgeRings corresponding to the shells of the input polygons.  
 /// Only ONE ring gets marked for each shell - if there are others which remain unmarked
 /// this indicates a disconnected interior.
 /// </summary>
 /// <param name="g"></param>
 /// <param name="graph"></param>
 private void VisitShellInteriors(IGeometry g, PlanarGraph graph)
 {
     if (g is IPolygon)
     {
         IPolygon p = (IPolygon) g;
         VisitInteriorRing(p.Shell, graph);
     }
     if (g is IMultiPolygon)
     {
         IMultiPolygon mp = (IMultiPolygon) g;
         foreach (IPolygon p in mp.Geometries)
             VisitInteriorRing(p.Shell, graph);
     }
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ring"></param>
 /// <param name="graph"></param>
 private void VisitInteriorRing(ILineString ring, PlanarGraph graph)
 {
     ICoordinate[] pts = ring.Coordinates;
     ICoordinate pt0 = pts[0];
     /*
      * Find first point in coord list different to initial point.
      * Need special check since the first point may be repeated.
      */
     ICoordinate pt1 = FindDifferentPoint(pts, pt0);
     Edge e = graph.FindEdgeInSameDirection(pt0, pt1);
     DirectedEdge de = (DirectedEdge) graph.FindEdgeEnd(e);
     DirectedEdge intDe = null;
     if (de.Label.GetLocation(0, Positions.Right) == Locations.Interior)
         intDe = de;
     else if (de.Sym.Label.GetLocation(0, Positions.Right) == Locations.Interior)
         intDe = de.Sym;
     Assert.IsTrue(intDe != null, "unable to find dirEdge with Interior on RHS");
     VisitLinkedDirectedEdges(intDe);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 private void SetInteriorEdgesInResult(PlanarGraph graph)
 {
     foreach (DirectedEdge de in graph.EdgeEnds)
         if (de.Label.GetLocation(0, Positions.Right) == Locations.Interior)
             de.InResult = true;
 }
示例#8
0
 /// <summary>
 /// Add a complete graph.
 /// The graph is assumed to contain one or more polygons,
 /// possibly with holes.
 /// </summary>
 /// <param name="graph"></param>
 public void Add(PlanarGraph graph)
 {
     Add(graph.EdgeEnds, graph.Nodes);
 }