Пример #1
0
        /*
         * /// <summary>
         * /// Updates the definition of this circle.
         * /// </summary>
         * /// <param name="center">The point at the center of the circle.</param>
         * /// <param name="radius">The radius of the circle, on the ground, in meters</param>
         * internal void MoveCircle(PointFeature center, double radius)
         * {
         *  // Remove this circle (and attached arcs) from the spatial index
         *  foreach (ArcFeature a in m_Arcs)
         *      a.PreMove();
         *
         *  m_Center.MapModel.EditingIndex.RemoveCircle(this);
         *
         *  // If the center location is changing then ensure that
         *  // the old location no longer refers to this circle,
         *  // and ensure the new one does.
         *
         *  // 08-DEC-99: Note that there appears to be inconsistency
         *  // in the cross-referencing of the center location to the
         *  // circle. Some places seem to do it, while other don't.
         *  // The extra reference shouldn't hurt, and at some stage
         *  // in the future, it would be good to enforce this.
         *
         *  if (!Object.ReferenceEquals(m_Center, center))
         *  {
         *      m_Center.CutReference(this);
         *      m_Center = center;
         *      m_Center.AddReference(this);
         *  }
         *
         *  // Change the radius
         *  m_Radius = radius;
         *
         *  // Re-index this circle and any attached arcs (this should also
         *  // mark the operations that created the arcs for rollforward).
         *  m_Center.MapModel.EditingIndex.AddCircle(this);
         *  foreach (ArcFeature a in m_Arcs)
         *      a.PostMove();
         * }
         */

        /// <summary>
        /// Checks whether this circle is referenced to arcs that terminaye at
        /// a specific point. This excludes arcs that correspond to the whole circle.
        /// </summary>
        /// <param name="p">The point to look for</param>
        /// <returns>True if an incident arc was found.</returns>
        internal bool HasArcsAt(PointFeature p)
        {
            // A location to check has to be specified!
            if (p == null)
            {
                return(false);
            }

            // Loop through each arc (including inactive ones).
            foreach (ArcFeature a in m_Arcs)
            {
                // Skip if the arc represents the whole circle.
                if (a.Geometry.IsCircle)
                {
                    continue;
                }

                // Check whether either end of the arc coincides with
                // the check location.
                if (p.IsCoincident(a.StartPoint) || p.IsCoincident(a.EndPoint))
                {
                    return(true);
                }
            }

            return(false);
        }
Пример #2
0
        PointFeature GetArcEndPoint(PointGeometry g, ILength tol, Operation creator)
        {
            // Ensure we've got a point at the required position
            PointFeature pt = EnsurePointExists(g, tol, creator);

            // If it's not exactly coincident, we've picked up a previously loaded point
            // that happens to be within tolerance. If it's not already connected to any
            // lines, shift it to where we want it.
            if (!pt.IsCoincident(g))
            {
                if (!pt.HasDependents)
                {
                    m_Index.Remove(pt);
                    PointFeature[] pts = pt.Node.Points;
                    pt.SetNode(new Node(pts, g));
                    m_Index.Add(pt);
                }
            }

            return(pt);
        }
Пример #3
0
        /// <summary>
        /// Defines any extra points that might coincide with this face.
        /// <c>m_Polygon</c> and <c>m_Line</c> must both be defined prior to call
        /// (via a call to <c>SetLine</c>).
        /// </summary>
        /// <returns>The number of extra points</returns>
        int SetExtraPoints()
        {
            Debug.Assert(m_Polygon != null);
            Debug.Assert(m_Divider != null);

            // Determine whether the order needs to be reversed
            // (the points should follow a clockwise cycle round
            // the polygon)
            bool reverse = (m_Divider.Left == m_Polygon);

            // Define the initial position
            if (reverse)
            {
                m_Begin = m_Divider.To;
                m_End   = m_Divider.From;
            }
            else
            {
                m_Begin = m_Divider.From;
                m_End   = m_Divider.To;
            }

            // Trash any old info kicking around (we shouldn't really have any)
            m_ExtraPoints = null;

            // Get any points along the divider (excluding end points)
            LineGeometry        line  = m_Divider.LineGeometry;
            ISpatialIndex       index = CadastralMapModel.Current.Index;
            ILength             tol   = new Length(Constants.XYTOL);
            List <PointFeature> xp    = new FindPointsOnLineQuery(index, line, false, tol).Result;

            if (xp.Count == 0)
            {
                return(0);
            }

            // If we've got more than one extra point, ensure they're sorted in
            // the same direction as the line.
            if (xp.Count == 1)
            {
                m_ExtraPoints = xp.ToArray();
            }
            else
            {
                // Sort the points so they're arranged along the divider
                List <TaggedObject <PointFeature, double> > pts =
                    new List <TaggedObject <PointFeature, double> >(xp.Count);

                foreach (PointFeature p in xp)
                {
                    double value = line.GetLength(p).Meters;
                    if (reverse)
                    {
                        value = -value;
                    }
                    pts.Add(new TaggedObject <PointFeature, double>(p, value));
                }

                pts.Sort(delegate(TaggedObject <PointFeature, double> a,
                                  TaggedObject <PointFeature, double> b)
                {
                    return(a.Tag.CompareTo(b.Tag));
                });

                // Retrieve the points in their sorted order, ignoring any coincident points
                // (this assumes that it doesn't matter which PointFeature we actually pick up)

                List <PointFeature> extraPoints = new List <PointFeature>(pts.Count);
                PointFeature        prev        = null;
                foreach (TaggedObject <PointFeature, double> tp in pts)
                {
                    PointFeature p = tp.Thing;

                    if (prev == null || !p.IsCoincident(prev))
                    {
                        extraPoints.Add(p);
                        prev = p;
                    }
                }

                // Allocate array of distinct extra positions
                m_ExtraPoints = extraPoints.ToArray();
            }

            return(m_ExtraPoints == null ? 0 : m_ExtraPoints.Length);
        }