Пример #1
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geomIndex"></param>
        public void PropagateSideLabels(int geomIndex)
        {
            // Since edges are stored in CCW order around the node,
            // As we move around the ring we move from the right to the left side of the edge
            Location startLoc = Location.Null;

            // initialize loc to location of last Curve side (if any)
            foreach (EdgeEnd e in Edges)
            {
                Label label = e.Label;
                if (label.IsArea(geomIndex) && label.GetLocation(geomIndex, Positions.Left) != Location.Null)
                {
                    startLoc = label.GetLocation(geomIndex, Positions.Left);
                }
            }
            // no labelled sides found, so no labels to propagate
            if (startLoc == Location.Null)
            {
                return;
            }

            Location currLoc = startLoc;

            foreach (EdgeEnd e in Edges)
            {
                Label label = e.Label;
                // set null On values to be in current location
                if (label.GetLocation(geomIndex, Positions.On) == Location.Null)
                {
                    label.SetLocation(geomIndex, Positions.On, currLoc);
                }
                // set side labels (if any)
                if (label.IsArea(geomIndex))
                {
                    Location leftLoc  = label.GetLocation(geomIndex, Positions.Left);
                    Location rightLoc = label.GetLocation(geomIndex, Positions.Right);
                    // if there is a right location, that is the next location to propagate
                    if (rightLoc != Location.Null)
                    {
                        if (rightLoc != currLoc)
                        {
                            throw new TopologyException("side location conflict", e.Coordinate);
                        }
                        if (leftLoc == Location.Null)
                        {
                            Assert.ShouldNeverReachHere("found single null side (at " + e.Coordinate + ")");
                        }
                        currLoc = leftLoc;
                    }
                    else
                    {
                        /* RHS is null - LHS must be null too.
                         *  This must be an edge from the other point, which has no location
                         *  labelling for this point.  This edge must lie wholly inside or outside
                         *  the other point (which is determined by the current location).
                         *  Assign both sides to be the current location.
                         */
                        Assert.IsTrue(label.GetLocation(geomIndex, Positions.Left) == Location.Null, "found single null side");
                        label.SetLocation(geomIndex, Positions.Right, currLoc);
                        label.SetLocation(geomIndex, Positions.Left, currLoc);
                    }
                }
            }
        }
Пример #2
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="geomGraph"></param>
        public virtual void ComputeLabelling(GeometryGraph[] geomGraph)
        {
            ComputeEdgeEndLabels(geomGraph[0].BoundaryNodeRule);
            // Propagate side labels  around the edges in the star
            // for each parent Geometry
            PropagateSideLabels(0);
            PropagateSideLabels(1);

            /*
             * If there are edges that still have null labels for a point
             * this must be because there are no area edges for that point incident on this node.
             * In this case, to label the edge for that point we must test whether the
             * edge is in the interior of the point.
             * To do this it suffices to determine whether the node for the edge is in the interior of an area.
             * If so, the edge has location Interior for the point.
             * In all other cases (e.g. the node is on a line, on a point, or not on the point at all) the edge
             * has the location Exterior for the point.
             *
             * Note that the edge cannot be on the Boundary of the point, since then
             * there would have been a parallel edge from the Geometry at this node also labelled Boundary
             * and this edge would have been labelled in the previous step.
             *
             * This code causes a problem when dimensional collapses are present, since it may try and
             * determine the location of a node where a dimensional collapse has occurred.
             * The point should be considered to be on the Exterior
             * of the polygon, but locate() will return Interior, since it is passed
             * the original Geometry, not the collapsed version.
             *
             * If there are incident edges which are Line edges labelled Boundary,
             * then they must be edges resulting from dimensional collapses.
             * In this case the other edges can be labelled Exterior for this Geometry.
             *
             * MD 8/11/01 - NOT True!  The collapsed edges may in fact be in the interior of the Geometry,
             * which means the other edges should be labelled Interior for this Geometry.
             * Not sure how solve this...  Possibly labelling needs to be split into several phases:
             * area label propagation, symLabel merging, then finally null label resolution.
             */
            bool[] hasDimensionalCollapseEdge = { false, false };
            foreach (var e in Edges)
            {
                Label label = e.Label;
                for (int geomi = 0; geomi < 2; geomi++)
                {
                    if (label.IsLine(geomi) && label.GetLocation(geomi) == Location.Boundary)
                    {
                        hasDimensionalCollapseEdge[geomi] = true;
                    }
                }
            }
            foreach (var e in Edges)
            {
                Label label = e.Label;
                for (int geomi = 0; geomi < 2; geomi++)
                {
                    if (label.IsAnyNull(geomi))
                    {
                        Location loc;
                        if (hasDimensionalCollapseEdge[geomi])
                        {
                            loc = Location.Exterior;
                        }
                        else
                        {
                            Coordinate p = e.Coordinate;
                            loc = GetLocation(geomi, p, geomGraph);
                        }
                        label.SetAllLocationsIfNull(geomi, loc);
                    }
                }
            }
        }