/// <summary>
        /// Performs data processing that involves creating or retiring spatial features.
        /// Newly created features will not have any definition for their geometry - a
        /// subsequent call to <see cref="CalculateGeometry"/> is needed to to that.
        /// </summary>
        /// <param name="ff">The factory class for generating any spatial features</param>
        internal override void ProcessFeatures(FeatureFactory ff)
        {
            // If this method is being called during deserialization from the database, you
            // can't easily determine whether the parallel ends at an offset point (since we
            // haven't yet calculated where the parallel line is located). In that case, we
            // can utilize the IDs of the "From" and "To" items that should be there on
            // deserialization.

            // The problem is that during the initial execution, we don't have a way to
            // pass through the positions that were determined in the Execute method. To
            // cover that, the Execute method is expected to add an item description if
            // a new feature needs to be created.

            PointFeature from, to;

            if (ff.HasFeatureDescription(DataField.From))
            {
                from = ff.CreatePointFeature(DataField.From);
            }
            else
            {
                from = this.OffsetPoint;
            }

            if (ff.HasFeatureDescription(DataField.To))
            {
                to = ff.CreatePointFeature(DataField.To);
            }
            else
            {
                to = this.OffsetPoint;
            }

            Debug.Assert(from != null);
            Debug.Assert(to != null);

            // Create a circular arc (without any circle) if the reference line is a circular
            // arc, or a section that's based on a circular arc.

            if (m_RefLine.GetArcBase() == null)
            {
                m_ParLine = ff.CreateSegmentLineFeature(DataField.NewLine, from, to);
            }
            else
            {
                m_ParLine = ff.CreateArcFeature(DataField.NewLine, from, to);
            }
        }
Exemple #2
0
        /// <summary>
        /// Creates any new spatial features (without any geometry)
        /// </summary>
        /// <param name="ff">The factory class for generating spatial features</param>
        internal override void ProcessFeatures(FeatureFactory ff)
        {
            m_NewPoint = ff.CreatePointFeature(DataField.NewPoint);

            if (ff.HasFeatureDescription(DataField.NewLine))
            {
                PointFeature from = (m_IsExtendFromEnd ? m_ExtendLine.EndPoint : m_ExtendLine.StartPoint);
                ArcFeature   arc  = m_ExtendLine.GetArcBase();

                if (arc == null)
                {
                    m_NewLine = ff.CreateSegmentLineFeature(DataField.NewLine, from, m_NewPoint);
                }
                else
                {
                    m_NewLine = ff.CreateArcFeature(DataField.NewLine, from, m_NewPoint);
                }

                m_NewLine.ObservedLength = m_Length;
            }
        }
Exemple #3
0
        /// <summary>
        /// Calculates positions that are parallel to a line.
        /// </summary>
        /// <param name="line">The reference line.</param>
        /// <param name="offpoint">The point the parallel must pass through.</param>
        /// <param name="sres">The position of the start of the parallel.</param>
        /// <param name="eres">The position of the end of the parallel.</param>
        /// <returns>True if positions calculated ok</returns>
        internal static bool Calculate(LineFeature refline, PointFeature offpoint, out IPosition sres, out IPosition eres)
        {
            // No result positions so far.
            sres = eres = null;

            // Get the ends of the reference line.
            IPosition spos = refline.StartPoint;
            IPosition epos = refline.EndPoint;

            // If the reference line is a circular arc
            ArcFeature arc = refline.GetArcBase();

            if (arc != null)
            {
                // Get the curve info
                Circle    circle = arc.Circle;
                double    radius = circle.Radius;
                IPosition centre = circle.Center;
                bool      iscw   = arc.IsClockwise;

                // Get the (planar) distance from the centre of the
                // circle to the offset point.
                double offdist = Geom.Distance(offpoint, centre);

                // Project the BC/EC radially.
                double sbear = Geom.BearingInRadians(centre, spos);
                sres = Geom.Polar(centre, sbear, offdist);

                double ebear = Geom.BearingInRadians(centre, epos);
                eres = Geom.Polar(centre, ebear, offdist);
            }
            else
            {
                double bearing = Geom.BearingInRadians(spos, epos);

                // Get the perpendicular distance (signed) from the offset point
                // to the reference line.
                double offdist = Geom.SignedDistance(spos.X, spos.Y, bearing, offpoint.X, offpoint.Y);

                // Calculate the parallel points.
                bearing += Constants.PIDIV2;
                sres     = Geom.Polar(spos, bearing, offdist);
                eres     = Geom.Polar(epos, bearing, offdist);
            }

            return(true);
        }
Exemple #4
0
        internal void Draw() // was Paint
        {
            // Nothing to do if parallel points undefined.
            if (m_South == null || m_North == null)
            {
                return;
            }

            Debug.Assert(m_Line != null);
            ISpatialDisplay draw        = m_Cmd.ActiveDisplay;
            IDrawStyle      solidStyle  = EditingController.Current.Style(Color.Magenta);
            IDrawStyle      dottedStyle = new DottedStyle();

            ArcFeature arc = m_Line.GetArcBase();

            if (arc != null)
            {
                // The parallel portion is solid, while the remaining portion of the circle is dotted.
                CircularArcGeometry cg = new CircularArcGeometry(arc.Circle.Center, m_South, m_North, arc.IsClockwise);
                solidStyle.Render(draw, cg);
                cg.IsClockwise = !cg.IsClockwise;
                dottedStyle.Render(draw, cg);
            }
            else
            {
                // What's the bearing from the start to the end of the parallel?
                double bearing = Geom.BearingInRadians(m_South, m_North);

                // What's the max length of a diagonal crossing the entire screen?
                double maxdiag = m_Cmd.MaxDiagonal;

                // Project to a point below the southern end of the parallel, as
                // well as a point above the northern end.
                IPosition below = Geom.Polar(m_South, bearing + Constants.PI, maxdiag);
                IPosition above = Geom.Polar(m_North, bearing, maxdiag);

                LineSegmentGeometry.Render(below, m_South, draw, dottedStyle);
                LineSegmentGeometry.Render(m_South, m_North, draw, solidStyle);
                LineSegmentGeometry.Render(m_North, above, draw, dottedStyle);

                // If we have an offset point, draw it in green.
                if (m_Point != null)
                {
                    m_Point.Draw(draw, Color.Green);
                }
            }
        }
Exemple #5
0
        /// <summary>
        /// Calculates positions that are parallel to a line.
        /// </summary>
        /// <param name="line">The reference line.</param>
        /// <param name="offset">The offset to the parallel, in ground units. Signed to denote
        /// which side (less than zero means it's to the left of the reference line).</param>
        /// <param name="sres">The position of the start of the parallel.</param>
        /// <param name="eres">The position of the end of the parallel.</param>
        /// <returns>True if positions calculated ok</returns>
        static bool Calculate(LineFeature line, Distance offset, out IPosition sres, out IPosition eres)
        {
            // No result positions so far.
            sres = eres = null;

            // Get the ends of the reference line.
            IPosition spos = line.StartPoint;
            IPosition epos = line.EndPoint;

            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = line.GetArcBase();

            if (arc != null)
            {
                Circle    circle = arc.Circle;
                double    radius = circle.Radius;
                IPosition centre = circle.Center;
                bool      iscw   = arc.IsClockwise;

                // Get the midpoint of the curve. The reduction of the
                // ground distance will be along the line that goes
                // from the centre of the circle & through this position.

                ILength   len     = line.Length;
                ILength   halfLen = new Length(len.Meters * 0.5);
                IPosition middle;
                line.LineGeometry.GetPosition(halfLen, out middle);

                // Get the bearing from the centre to the mid-position
                // and use that to reduce the offset to the mapping plane.
                double bearing = Geom.BearingInRadians(centre, middle);
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // No parallel if the offset exceeds the radius.
                // if ( offdist > radius ) return FALSE;

                // Calculate the parallel points.
                double sbear = Geom.BearingInRadians(centre, spos);
                sres = Geom.Polar(centre, sbear, offdist + radius);

                double ebear = Geom.BearingInRadians(centre, epos);
                eres = Geom.Polar(centre, ebear, offdist + radius);
            }
            else
            {
                // Get the bearing.of the line.
                double bearing = Geom.BearingInRadians(spos, epos);

                // Get the planar distance for a perpendicular line that passes
                // through the midpoint of the reference line. The planar distance
                // will have the same sign as the ground value.

                IPosition middle = Position.CreateMidpoint(spos, epos);
                bearing += Constants.PIDIV2;
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // Calculate the parallel points.
                sres = Geom.Polar(spos, bearing, offdist);
                eres = Geom.Polar(epos, bearing, offdist);
            }

            return(true);
        }
Exemple #6
0
        /// <summary>
        /// Draws the current state of the edit
        /// </summary>
        internal void Draw()
        {
            Debug.Assert(m_Line != null);
            ISpatialDisplay view = ActiveDisplay;

            // Figure out the positions for the ends of the parallel line (if any) ...

            // Assume we already know both terminals.
            IPosition start = m_Term1;
            IPosition end   = m_Term2;

            // If either one is undefined, but a dialog for it is active,
            // try to get the terminal from there instead.
            if (m_TermDial1 != null && start == null)
            {
                start = m_TermDial1.TerminalPosition;
            }

            if (m_TermDial2 != null && end == null)
            {
                end = m_TermDial2.TerminalPosition;
            }

            // If they weren't actually defined, use the parallel points instead.
            if (start == null)
            {
                start = m_Par1;
            }

            if (end == null)
            {
                end = m_Par2;
            }

            // If those weren't defined either, try to calculate them now.
            if (end == null && Calculate())
            {
                start = m_Par1;
                end   = m_Par2;
            }

            // Any offset point
            if (m_OffsetPoint != null)
            {
                m_OffsetPoint.Draw(view, Color.Green);
            }

            // Everything else should draw in usual command-style colour.
            IDrawStyle style       = EditingController.Current.Style(Color.Magenta);
            IDrawStyle dottedStyle = new DottedStyle();

            // If the reference line is a curve, get the curve info.
            ArcFeature arc = m_Line.GetArcBase();

            if (arc != null)
            {
                bool iscw = arc.IsClockwise;

                // Reverse the direction if necessary.
                if (m_IsReversed)
                {
                    iscw = !iscw;
                }

                // Draw the parallel line (the rest of the circle being dotted).
                if (start != null)
                {
                    CircularArcGeometry parArc = new CircularArcGeometry(arc.Circle, start, end, iscw);
                    style.Render(view, parArc);

                    parArc.IsClockwise = !parArc.IsClockwise;
                    dottedStyle.Render(view, parArc);
                }
            }
            else
            {
                // PARALLEL IS STRAIGHT

                // If we've got something, figure out positions for dotted portion.
                if (start != null)
                {
                    // What's the max length of a diagonal crossing the entire screen?
                    double maxdiag = this.MaxDiagonal;

                    // What's the bearing from the start to the end of the parallel?
                    double bearing = Geom.BearingInRadians(start, end);

                    // Project to a point before the start end of the parallel, as
                    // well as a point after the end.
                    IPosition before = Geom.Polar(start, bearing + Constants.PI, maxdiag);
                    IPosition after  = Geom.Polar(end, bearing, maxdiag);

                    LineSegmentGeometry.Render(before, start, view, dottedStyle);
                    LineSegmentGeometry.Render(start, end, view, style);
                    LineSegmentGeometry.Render(end, after, view, dottedStyle);
                }
            }

            // Draw terminal positions (if defined).

            if (m_Term1 != null)
            {
                style.Render(view, m_Term1);
            }

            if (m_Term2 != null)
            {
                style.Render(view, m_Term2);
            }

            // The terminal lines.

            if (m_TermLine1 != null)
            {
                m_TermLine1.Render(view, style);
            }

            if (m_TermLine2 != null)
            {
                m_TermLine2.Render(view, style);
            }

            // Do the active dialog last so their stuff draws on top.
            if (m_ParDial != null)
            {
                m_ParDial.Draw();
            }

            if (m_TermDial1 != null)
            {
                m_TermDial1.Draw();
            }

            if (m_TermDial2 != null)
            {
                m_TermDial2.Draw();
            }
        }
Exemple #7
0
        /// <summary>
        /// Returns the intersection of the parallel with a line.
        /// </summary>
        /// <param name="refline">The reference line.</param>
        /// <param name="parpos">Search position that coincides with the parallel.</param>
        /// <param name="line">The line to intersect with.</param>
        /// <returns>The intersection (if any). In cases where the line intersects the
        /// parallel more than once, you get the intersection that is closest to the
        /// search position.</returns>
        internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel point is undefined.
            if (parpos == null)
            {
                return(null);
            }

            // If the reference line is a circular arc (or a section based on an arc), get the curve info.
            ArcFeature arc = refline.GetArcBase();

            if (arc != null)
            {
                Circle         circle = arc.Circle;
                double         radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool           iscw   = arc.IsClockwise;

                // Construct a circle that passes through the search position
                double parrad = Geom.Distance(centre, parpos);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the search position.
                xres.GetClosest(parpos, out result, 0.0);
            }
            else
            {
                // Get the bearing from the start to the end of the reference line.
                IPosition spos    = refline.StartPoint;
                IPosition epos    = refline.EndPoint;
                double    bearing = Geom.BearingInRadians(spos, epos);

                // Project the parallel line to positions that are a long way away (but make sure we
                // don't end up with negative numbers).
                Window searchWindow = new Window(line.Extent);
                searchWindow.Union(refline.Extent);
                searchWindow.Union(parpos);
                double dist = Geom.Distance(searchWindow.Min, searchWindow.Max);

                IPosition start = Geom.Polar(parpos, bearing + Constants.PI, dist);
                IPosition end   = Geom.Polar(parpos, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry     sg   = new PointGeometry(start);
                IPointGeometry     eg   = new PointGeometry(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx == 0)
                {
                    return(null);
                }

                // If there is only one intersection, that's what we want.
                if (nx == 1)
                {
                    return(xres.Intersections[0].P1);
                }

                // Get the intersection that is closest to the search position
                xres.GetClosest(parpos, out result, 0.0);
            }

            return(result);
        }
        /// <summary>
        /// Calculates positions that are parallel to a line.
        /// </summary>
        /// <param name="line">The reference line.</param>
        /// <param name="offset">The offset to the parallel, in ground units. Signed to denote
        /// which side (less than zero means it's to the left of the reference line).</param>
        /// <param name="sres">The position of the start of the parallel.</param>
        /// <param name="eres">The position of the end of the parallel.</param>
        /// <returns>True if positions calculated ok</returns>
        static bool Calculate(LineFeature line, Distance offset, out IPosition sres, out IPosition eres)
        {
            // No result positions so far.
            sres = eres = null;

            // Get the ends of the reference line.
            IPosition spos = line.StartPoint;
            IPosition epos = line.EndPoint;

            ISpatialSystem sys = CadastralMapModel.Current.SpatialSystem;

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = line.GetArcBase();
            if (arc != null)
            {
                Circle circle = arc.Circle;
                double radius = circle.Radius;
                IPosition centre = circle.Center;
                bool iscw = arc.IsClockwise;

                // Get the midpoint of the curve. The reduction of the
                // ground distance will be along the line that goes
                // from the centre of the circle & through this position.

                ILength len = line.Length;
                ILength halfLen = new Length(len.Meters * 0.5);
                IPosition middle;
                line.LineGeometry.GetPosition(halfLen, out middle);

                // Get the bearing from the centre to the mid-position
                // and use that to reduce the offset to the mapping plane.
                double bearing = Geom.BearingInRadians(centre, middle);
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // No parallel if the offset exceeds the radius.
                // if ( offdist > radius ) return FALSE;

                // Calculate the parallel points.
                double sbear = Geom.BearingInRadians(centre, spos);
                sres = Geom.Polar(centre, sbear, offdist+radius);

                double ebear = Geom.BearingInRadians(centre, epos);
                eres = Geom.Polar(centre, ebear, offdist+radius);
            }
            else
            {
                // Get the bearing.of the line.
                double bearing = Geom.BearingInRadians(spos, epos);

                // Get the planar distance for a perpendicular line that passes
                // through the midpoint of the reference line. The planar distance
                // will have the same sign as the ground value.

                IPosition middle = Position.CreateMidpoint(spos, epos);
                bearing += Constants.PIDIV2;
                double offdist = offset.GetPlanarMetric(middle, bearing, sys);

                // Calculate the parallel points.
                sres = Geom.Polar(spos, bearing, offdist);
                eres = Geom.Polar(epos, bearing, offdist);
            }

            return true;
        }
        /// <summary>
        /// Returns the intersection of the parallel with a line.
        /// </summary>
        /// <param name="refline">The reference line.</param>
        /// <param name="parpos">Search position that coincides with the parallel.</param>
        /// <param name="line">The line to intersect with.</param>
        /// <returns>The intersection (if any). In cases where the line intersects the
        /// parallel more than once, you get the intersection that is closest to the
        /// search position.</returns>
        internal static IPosition GetIntersect(LineFeature refline, IPosition parpos, LineFeature line)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel point is undefined.
            if (parpos==null)
                return null;

            // If the reference line is a circular arc (or a section based on an arc), get the curve info.
            ArcFeature arc = refline.GetArcBase();
            if (arc != null)
            {
                Circle circle = arc.Circle;
                double radius = circle.Radius;
                IPointGeometry centre = circle.Center;
                bool iscw = arc.IsClockwise;

                // Construct a circle that passes through the search position
                double parrad = Geom.Distance(centre, parpos);

                // Intersect the circle with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                uint nx = xres.Intersect(centre, parrad);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the search position.
                xres.GetClosest(parpos, out result, 0.0);
            }
            else
            {
                // Get the bearing from the start to the end of the reference line.
                IPosition spos = refline.StartPoint;
                IPosition epos = refline.EndPoint;
                double bearing = Geom.BearingInRadians(spos, epos);

                // Project the parallel line to positions that are a long way away (but make sure we
                // don't end up with negative numbers).
                Window searchWindow = new Window(line.Extent);
                searchWindow.Union(refline.Extent);
                searchWindow.Union(parpos);
                double dist = Geom.Distance(searchWindow.Min, searchWindow.Max);

                IPosition start = Geom.Polar(parpos, bearing+Constants.PI, dist);
                IPosition end = Geom.Polar(parpos, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry sg = new PointGeometry(start);
                IPointGeometry eg = new PointGeometry(end);
                uint nx = xres.Intersect(sg, eg);
                if (nx==0)
                    return null;

                // If there is only one intersection, that's what we want.
                if (nx==1)
                    return xres.Intersections[0].P1;

                // Get the intersection that is closest to the search position
                xres.GetClosest(parpos, out result, 0.0);
            }

            return result;
        }
        /// <summary>
        /// Calculates positions that are parallel to a line.
        /// </summary>
        /// <param name="line">The reference line.</param>
        /// <param name="offpoint">The point the parallel must pass through.</param>
        /// <param name="sres">The position of the start of the parallel.</param>
        /// <param name="eres">The position of the end of the parallel.</param>
        /// <returns>True if positions calculated ok</returns>
        internal static bool Calculate(LineFeature refline, PointFeature offpoint, out IPosition sres, out IPosition eres)
        {
            // No result positions so far.
            sres = eres = null;

            // Get the ends of the reference line.
            IPosition spos = refline.StartPoint;
            IPosition epos = refline.EndPoint;

            // If the reference line is a circular arc
            ArcFeature arc = refline.GetArcBase();
            if (arc != null)
            {
                // Get the curve info
                Circle circle = arc.Circle;
                double radius = circle.Radius;
                IPosition centre = circle.Center;
                bool iscw = arc.IsClockwise;

                // Get the (planar) distance from the centre of the
                // circle to the offset point.
                double offdist = Geom.Distance(offpoint, centre);

                // Project the BC/EC radially.
                double sbear = Geom.BearingInRadians(centre, spos);
                sres = Geom.Polar(centre, sbear, offdist);

                double ebear = Geom.BearingInRadians(centre, epos);
                eres = Geom.Polar(centre, ebear, offdist);
            }
            else
            {
                double bearing = Geom.BearingInRadians(spos, epos);

                // Get the perpendicular distance (signed) from the offset point
                // to the reference line.
                double offdist = Geom.SignedDistance(spos.X, spos.Y, bearing, offpoint.X, offpoint.Y);

                // Calculate the parallel points.
                bearing += Constants.PIDIV2;
                sres = Geom.Polar(spos, bearing, offdist);
                eres = Geom.Polar(epos, bearing, offdist);
            }

            return true;
        }