Esempio n. 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;
 }
        /// <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.  Notice only ONE ring gets marked for each shell.
             */
            VisitShellInteriors(_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>
 /// Add a complete graph.
 /// The graph is assumed to contain one or more polygons,
 /// possibly with holes.
 /// </summary>
 /// <param name="graph"></param>
 public virtual void Add(PlanarGraph graph)
 {
     Add(graph.EdgeEnds, graph.NodeValues);
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="ring"></param>
 /// <param name="graph"></param>
 private static void VisitInteriorRing(IBasicGeometry ring, PlanarGraph graph)
 {
     IList<Coordinate> pts = ring.Coordinates;
     Coordinate pt0 = pts[0];
     /*
      * Find first point in coord list different to initial point.
      * Need special check since the first point may be repeated.
      */
     Coordinate 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>
 /// 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 static void VisitShellInteriors(IGeometry g, PlanarGraph graph)
 {
     if (g is Polygon) 
     {
         Polygon p = (Polygon) g;
         VisitInteriorRing(p.Shell, graph);
     }
     if (g is MultiPolygon) 
     {
         MultiPolygon mp = (MultiPolygon) g;
         foreach (Polygon p in mp.Geometries) 
             VisitInteriorRing(p.Shell, graph);
     }
 }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="graph"></param>
 private static void SetInteriorEdgesInResult(PlanarGraph graph)
 {
     foreach (DirectedEdge de in graph.EdgeEnds)               
         if (de.Label.GetLocation(0, Positions.Right) == Locations.Interior)
             de.IsInResult = true;
 }
        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;
        }
        /// <summary>
        /// 
        /// </summary>
        /// <param name="g"></param>
        /// <param name="distance"></param>
        /// <returns></returns>
        public IGeometry Buffer(IGeometry g, double distance)
        {
            PrecisionModel precisionModel = workingPrecisionModel;
            if (precisionModel == null)
                precisionModel = new 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 Geometry[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;
        }