void ShowResult()
        {
            // If we have the first two points, get the distance between
            // them, format the result, and display it.
            if (m_Point1 != null && m_Point2 != null)
            {
                double metric = Geom.Distance(m_Point1, m_Point2);
                distance1TextBox.Text = Format(metric, m_Point1, m_Point2);
            }

            // Same for the second pair of points.
            if (m_Point2 != null && m_Point3 != null)
            {
                double metric = Geom.Distance(m_Point2, m_Point3);
                distance2TextBox.Text = Format(metric, m_Point2, m_Point3);
            }

            // If we have all 3 points, display the angle.
            if (m_Point1 != null && m_Point2 != null && m_Point3 != null)
            {
                // Get the clockwise angle.
                Turn   reft = new Turn(m_Point2, m_Point1);
                double ang  = reft.GetAngleInRadians(m_Point3);

                // Get the complement if we actually want it anti-clockwise.
                if (!m_Clockwise)
                {
                    ang = Constants.PIMUL2 - ang;
                }

                angleTextBox.Text = RadianValue.AsString(ang);
            }
        }
        /// <summary>
        /// Performs the data processing associated with this editing operation.
        /// </summary>
        /// <param name="ctx">The context in which the geometry is being calculated.</param>
        internal override void CalculateGeometry(EditingContext ctx)
        {
            //IPosition p = (base.CheckPosition == null ? Calculate() : base.CheckPosition);
            IPosition p = Calculate();

            if (p == null)
            {
                p = CheckPosition;
                Log(String.Format("Id={0} (CEdit={1:0.0}E {2:0.0}N", this.EditSequence, p.X, p.Y));
            }
            else if (CheckPosition != null)
            {
                double d = Geom.Distance(p, CheckPosition);
                if (d > 1.0)
                {
                    Log(String.Format("Id={0} (CEdit={1:0.0}E {2:0.0}N)  (Backsight={3:0.0}E {4:0.0}N)  Delta={5:0.000}",
                                      this.EditSequence, CheckPosition.Easting.Meters, CheckPosition.Northing.Meters, p.X, p.Y, d));
                }
                p = CheckPosition;
            }

            PointGeometry pg = PointGeometry.Create(p);

            m_Intersection.ApplyPointGeometry(ctx, pg);
        }
Example #3
0
        /// <summary>
        /// Returns the offset for the parallel, in units on the mapping plane. In order
        /// for this to work, a prior call to Calculate must be made.
        /// </summary>
        /// <returns>The offset distance on the mapping plane (>= 0).</returns>
        internal double GetPlanarOffset()
        {
            // If the reference line or the parallel points are undefined, there's nothing we can do.
            if (m_Line == null || m_Par1 == null || m_Par2 == null)
            {
                return(0.0);
            }

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

            if (arc != null)
            {
                // Get the (planar) radial offset from the circle to one of the parallel positions.
                double    radius = arc.Circle.Radius;
                IPosition center = arc.Circle.Center;
                return(Math.Abs(Geom.Distance(center, m_Par1) - radius));
            }

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

            // And its bearing.
            double bearing = Geom.BearingInRadians(spos, epos);

            // Get the perpendicular distance (signed) from one of the
            // parallel points to the reference line.
            double offdist = Geom.SignedDistance(spos.X, spos.Y, bearing, m_Par1.X, m_Par1.Y);

            return(Math.Abs(offdist));
        }
 internal virtual void ShowResult()
 {
     // If we have two points, get the distance between them,
     // format the result, and display it.
     if (m_Point1 != null && m_Point2 != null)
     {
         // Get the distance on the mapping plane.
         double metric = Geom.Distance(m_Point1, m_Point2);
         distanceTextBox.Text = Format(metric, m_Point1, m_Point2);
     }
 }
Example #5
0
        public void TestCrossPosition()
        {
            Vector a     = new Vector(0, 400);
            Vector b     = new Vector(640, 400);
            Vector c     = new Vector(50, 397.8131f);
            Vector e     = new Vector(500, 376.573f);
            Line   ab    = new Line(a, b);
            float  dist1 = Geom.Distance(ab, c);
            float  dist2 = Geom.Distance(ab, e);

            Console.Out.WriteLine("dist1 = " + dist1);
            Console.Out.WriteLine("dist2 = " + dist2);
        }
Example #6
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);
        }
Example #7
0
        /// <summary>
        /// Uses the currently displayed information to try to construct a
        /// circle representing the distance.
        /// </summary>
        /// <returns>The constructed circle (null if a circle cannot be created
        /// based on the information that's currently displayed)</returns>
        Circle GetCurrentCircle()
        {
            Circle result = null;

            // Undefine the address of the relevant distance observation.
            m_ObservedDistance = null;

            if (m_From == null)
            {
                return(null);
            }

            if (m_DistancePoint != null || (m_Distance != null && m_Distance.Meters > Constants.TINY))
            {
                double radius;

                // If we have an offset point, get the radius.
                if (m_DistancePoint != null)
                {
                    radius = Geom.Distance(m_From, m_DistancePoint);
                }
                else
                {
                    radius = m_Distance.Meters;
                }

                // Construct the circle
                result = new Circle(m_From, radius);

                // Create the appropriate distance observation (this is what
                // gets picked up when we actually go to work out the
                // intersection on the last page of the intersect dialog.

                if (m_DistancePoint != null)
                {
                    m_OffsetPoint      = new OffsetPoint(m_DistancePoint);
                    m_ObservedDistance = m_OffsetPoint;
                }
                else
                {
                    m_ObservedDistance = m_Distance;
                }
            }

            return(result);
        }
        /// <summary>
        /// Performs the data processing associated with this editing operation.
        /// </summary>
        /// <param name="ctx">The context in which the geometry is being calculated.</param>
        internal override void CalculateGeometry(EditingContext ctx)
        {
            // Calculate the end positions
            IPosition spos, epos;

            if (!Calculate(out spos, out epos))
            {
                throw new Exception("Failed to calculate parallel line positions");
            }

            // Apply the calculated positions so long as the end points of the parallel line
            // were created by this edit
            if (m_ParLine.StartPoint.Creator == this)
            {
                m_ParLine.StartPoint.ApplyPointGeometry(ctx, PointGeometry.Create(spos));
            }

            if (m_ParLine.EndPoint.Creator == this)
            {
                m_ParLine.EndPoint.ApplyPointGeometry(ctx, PointGeometry.Create(epos));
            }

            // If the parallel is an arc, define the geometry
            if (m_ParLine is ArcFeature)
            {
                // Get the center of the reference line
                ArcFeature   refArc = m_RefLine.GetArcBase();
                PointFeature center = refArc.Circle.CenterPoint;

                // Obtain a circle for the parallel
                double radius = Geom.Distance(center, m_ParLine.StartPoint);
                Circle circle = MapModel.AddCircle(center, radius);

                // Define arc direction
                bool iscw = refArc.IsClockwise;
                if (IsArcReversed)
                {
                    iscw = !iscw;
                }

                ArcGeometry geom = new ArcGeometry(circle, m_ParLine.StartPoint, m_ParLine.EndPoint, iscw);
                (m_ParLine as ArcFeature).Geometry = geom;
            }
        }
Example #9
0
        /// <summary>
        /// Uses the currently displayed information to try to construct a
        /// circle object.
        /// </summary>
        /// <returns>The constructed circle (null if a circle cannot be created
        /// based on the information that's currently displayed)</returns>
        Circle GetCurrentCircle()
        {
            Circle result = null;

            // Get rid of any previous radius observation.
            m_Radius = null;

            if (m_Center != null && (m_RadiusPoint != null || m_RadiusDistance != null))
            {
                double radius;

                // If we have an offset point, get the radius.
                if (m_RadiusPoint != null)
                {
                    radius = Geom.Distance(m_Center, m_RadiusPoint);
                }
                else
                {
                    radius = m_RadiusDistance.Meters;
                }

                // Create the circle
                result = new Circle(m_Center, radius);

                // Create the appropriate distance observation.
                // (not sure why these were needed, it certainly looks out of place as
                // part of this method)
                if (m_RadiusPoint != null)
                {
                    m_Radius = new OffsetPoint(m_RadiusPoint);
                }
                else
                {
                    m_Radius = new Distance(m_RadiusDistance);
                }
            }

            return(result);
        }
Example #10
0
        /// <summary>
        /// The diagonal length of a line that spans the display when it is
        /// drawn at the overview scale.
        /// </summary>
        /// <param name="display"></param>
        /// <returns></returns>
        double GetMaxDiagonal(ISpatialDisplay display)
        {
            IWindow x = display.MaxExtent;

            return(Geom.Distance(x.Min, x.Max));
        }
Example #11
0
        /// <summary>
        /// Intersects this direction with a line.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="closeTo">The point that the intersection should be closest to.
        /// Specify null if you don't care. In that case, if there are multiple intersections,
        /// you get the intersection that is closest to one of 3 points: the start of the
        /// direction line, the start of the line, or the end of the line.</param>
        /// <param name="xsect">The position of the intersection (if any). Null if not found.</param>
        /// <param name="closest">The default point that is closest to the intersection. Null if
        /// intersection wasn't found.</param>
        /// <returns>True if intersection was found.</returns>
        internal bool Intersect(LineFeature line
                                , PointFeature closeTo
                                , out IPosition xsect
                                , out PointFeature closest)
        {
            // Initialize results
            xsect   = null;
            closest = null;

            // Define the length of the direction line as the length
            // of a diagonal that crosses the map's extent.
            IWindow mapWin = SpatialController.Current.MapModel.Extent;

            Debug.Assert(mapWin != null);

            // If the window is currently undefined (e.g. during deserialization),
            // just use a really big distance.
            // TODO: This is a hack, but hopefully it may be shortlived, because
            // new logic is in the works for handling updates.
            double dist = (mapWin.IsEmpty ? 100000.0 : Geom.Distance(mapWin.Min, mapWin.Max));

            // Define the position of the direction line. DON'T use the from-
            // point, because there may be an offset to the direction.
            IPosition fromPos = this.StartPosition;
            IPosition toPos   = Geom.Polar(fromPos, this.Bearing.Radians, dist);

            // Construct a corresponding line segment.
            ITerminal       start = new FloatingTerminal(fromPos);
            ITerminal       end   = new FloatingTerminal(toPos);
            SegmentGeometry seg   = new SegmentGeometry(start, end);

            // Intersect the line segment with the other one.
            IntersectionResult xres = new IntersectionResult(line);
            uint nx = seg.Intersect(xres);

            if (nx == 0)
            {
                return(false);
            }

            // Determine which terminal point is the best. Start with the
            // ends of the intersected line.
            double mindsq = Double.MaxValue;

            if (xres.GetCloserPoint(line.StartPoint, ref mindsq, ref xsect))
            {
                closest = line.StartPoint;
            }

            if (xres.GetCloserPoint(line.EndPoint, ref mindsq, ref xsect))
            {
                closest = line.EndPoint;
            }

            // Check whether the direction from-point is any closer (the position may be
            // different from the start of the direction line, because the direction may
            // have an offset).

            if (xres.GetCloserPoint(this.From, ref mindsq, ref xsect))
            {
                closest = this.From;
            }

            // If a close-to point has been specified, that overrides
            // everything else (however, doing the above has the desired
            // effect of defining the best of the default points). In
            // this case, we allow an intersection that coincides with
            // the line being intersected.
            // -- actually, we don't, since GetClosest uses a > 0 test

            if (closeTo != null)
            {
                xres.GetClosest(closeTo, out xsect, 0.0);

                /*
                 * IPosition xCloseTo;
                 * xres.GetClosest(closeTo, out xCloseTo, 0.0);
                 *
                 * if (xCloseTo != null)
                 *  xsect = xCloseTo;
                 */
            }

            return(xsect != null);
        }
Example #12
0
        /// <summary>
        /// Returns the intersection of the parallel with a line. A prior call to Calculate is required.
        /// </summary>
        /// <param name="line">The line to intersect with.</param>
        /// <param name="isEndParallel">Is the intersection biased towards the end of the parallel?</param>
        /// <returns>The intersection (if any). In cases where the line intersects the parallel
        /// more than once, you get an arbitrary intersection.</returns>
        internal IPosition GetIntersect(LineFeature line, bool isEndParallel)
        {
            // Make sure the intersection is undefined.
            IPosition result = null;

            // Return if the parallel points are undefined.
            if (m_Par1 == null || m_Par2 == null)
            {
                return(null);
            }

            // If the reference line is a circular arc, get the curve info.
            ArcFeature arc = m_Line.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 parallel points (assumed to have the same distance
                // with respect to the centre of the circle).
                double parrad = Geom.Distance(centre, m_Par1);

                // 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 parallel point
                // that has the bias.
                if (isEndParallel)
                {
                    xres.GetClosest(m_Par2, out result, 0.0);
                }
                else
                {
                    xres.GetClosest(m_Par1, out result, 0.0);
                }
            }
            else
            {
                // Get the bearing from the start to the end of the parallel.
                double bearing = Geom.BearingInRadians(m_Par1, m_Par2);

                // Get the ground dimension of a line that crosses the
                // extent of the draw window.
                double dist = MaxDiagonal;

                // Project the parallel line to positions that are well
                // beyond the draw extent.
                IPosition start = Geom.Polar(m_Par1, bearing + Constants.PI, dist);
                IPosition end   = Geom.Polar(m_Par2, bearing, dist);

                // Intersect the line segment with the line to intersect with.
                IntersectionResult xres = new IntersectionResult(line);
                IPointGeometry     sg   = PointGeometry.Create(start);
                IPointGeometry     eg   = PointGeometry.Create(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 parallel point
                // that has the bias.
                if (isEndParallel)
                {
                    xres.GetClosest(m_Par2, out result, 0.0);
                }
                else
                {
                    xres.GetClosest(m_Par1, out result, 0.0);
                }
            }

            return(result);
        }
Example #13
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);
        }
Example #14
0
        private void okButton_Click(object sender, EventArgs e)
        {
            // Get the northing & easting.
            double y;

            if (!Double.TryParse(northingTextBox.Text, out y))
            {
                MessageBox.Show("Bad northing");
                northingTextBox.Focus();
                return;
            }

            double x;

            if (!Double.TryParse(eastingTextBox.Text, out x))
            {
                MessageBox.Show("Bad easting");
                eastingTextBox.Focus();
                return;
            }

            if (Math.Abs(x) < Double.Epsilon || Math.Abs(y) < Double.Epsilon)
            {
                MessageBox.Show("Position has not been specified.");
                return;
            }

            // See if there is an elevation (get 0.0 if not).
            double z = 0.0;

            if (elevationTextBox.Text.Length > 0)
            {
                if (!Double.TryParse(elevationTextBox.Text, out z))
                {
                    MessageBox.Show("Bad elevation");
                    elevationTextBox.Focus();
                    return;
                }
            }

            m_Position  = new Position(x, y);
            m_Elevation = z;

            // Check whether the position is on screen. If not, issue a warning
            // message, and let the user cancel if desired.
            ISpatialDisplay display = EditingController.Current.ActiveDisplay;
            IWindow         extent  = display.Extent;

            if (extent == null || !extent.IsOverlap(m_Position))
            {
                if (MessageBox.Show("Specified position does not overlap current draw window. Continue?",
                                    "Off screen", MessageBoxButtons.YesNo) == DialogResult.No)
                {
                    return;
                }
            }

            // Are we doing an update?
            PointFeature pupt = this.UpdatePoint;

            // Confirm that there is no selectable point already at the specified position. Allow
            // a tolerance of 1cm on the ground. Only check in 2D.
            // The seatch should be restricted to those points that are currently visible.

            CadastralMapModel map   = CadastralMapModel.Current;
            ILength           tol   = new Length(0.01);
            PointFeature      close = (PointFeature)map.QueryClosest(m_Position, tol, SpatialType.Point);

            if (close != null)
            {
                // Get the ground distance between the existing point & the new one.
                double dist = Geom.Distance(m_Position, close);

                // Confirm if the points are coincident. Unless we're doing an update,
                // and it's the one we're doing.

                if (pupt == null || !Object.ReferenceEquals(close, pupt))
                {
                    if (dist < Constants.TINY)
                    {
                        string msg = String.Format("Specified position coincides with existing point {0}. Continue?",
                                                   close.FormattedKey);
                        if (MessageBox.Show(msg, "Coincident point", MessageBoxButtons.YesNo) == DialogResult.No)
                        {
                            return;
                        }
                    }
                    else
                    {
                        string msg = String.Format("Specified position is only {0:0.000} metres away from point {1}. Continue?",
                                                   dist, close.FormattedKey);

                        if (MessageBox.Show(msg, "Very near another point", MessageBoxButtons.YesNo) == DialogResult.No)
                        {
                            return;
                        }
                    }
                }
            }

            // If we're updating a 3D position, update ONLY the elevation
            // now. We must leave the planimetric change to NewPointUI,
            // since it is in charge of controlling rollforward.

            if (pupt != null)
            {
                // For the time being, we do not provide the ability to change
                // a 2D location into a 3D one. Would need to modify the location,
                // thereby changing its address (or possibly create a duplicate
                // location in XY, although that could cause problems elsewhere).


                if (m_Elevation > Constants.TINY && !(pupt is IEditPosition3D))
                {
                    MessageBox.Show("Cannot convert a 2D point into 3D");
                    return;
                }

                // The point MUST be associated with a creating operation (either
                // a eNewPoint or a GetControl operation).
                Operation creator = (Operation)pupt.Creator;
                if (creator == null)
                {
                    MessageBox.Show("Point cannot be updated because it has no associated edit.");
                    return;
                }

                if (!(creator.EditId == EditingActionId.NewPoint ||
                      creator.EditId == EditingActionId.GetControl))
                {
                    MessageBox.Show("Unexpected editing operation");
                    return;
                }

                // Define new elevation if we have a 3D location.
                if (m_Elevation > Constants.TINY)
                {
                    IEditPosition3D p3D = (pupt as IEditPosition3D);
                    if (p3D == null)
                    {
                        MessageBox.Show("Unable to assign elevation");
                    }
                    else
                    {
                        p3D.Z = m_Elevation;
                    }
                }
            }

            m_Cmd.DialFinish(this);
        }