/// <summary> /// Adjusts the path (Helmert adjustment). /// </summary> /// <param name="dN">Misclosure in northing.</param> /// <param name="dE">Misclosure in easting.</param> /// <param name="precision">Precision denominator (zero if no adjustment needed).</param> /// <param name="length">Total observed length.</param> /// <param name="rotation">The clockwise rotation to apply (in radians).</param> /// <param name="sfac">The scaling factor to apply.</param> void Adjust(out double dN, out double dE, out double precision, out double length, out double rotation, out double sfac) { dN = dE = precision = length = rotation = 0.0; sfac = 1.0; // Initialize position to the start of the path, corresponding to the initial // un-adjusted end point. IPosition start = m_From; IPosition gotend = new Position(m_From); // Initial bearing is due north. double bearing = 0.0; // Go through each leg, updating the end position, and getting // the total path length. foreach (Leg leg in m_Legs) { length += leg.Length.Meters; leg.Project(ref gotend, ref bearing, sfac); } // Get the bearing and distance of the end point we ended up with. double gotbear = Geom.BearingInRadians(m_From, gotend); double gotdist = Geom.Distance(m_From, gotend); // Get the bearing and distance we want. double wantbear = Geom.BearingInRadians(m_From, m_To); double wantdist = Geom.Distance(m_From, m_To); // Figure out the rotation. rotation = wantbear - gotbear; // Rotate the end point we got. gotend = Geom.Rotate(m_From, gotend, new RadianValue(rotation)); // Calculate the line scale factor. double linefac = m_From.MapModel.SpatialSystem.GetLineScaleFactor(m_From, gotend); // Figure out where the rotated end point ends up when we apply the line scale factor. gotend = Geom.Polar(m_From, wantbear, gotdist * linefac); // What misclosure do we have? dN = gotend.Y - m_To.Y; dE = gotend.X - m_To.X; double delta = Math.Sqrt(dN * dN + dE * dE); // What's the precision denominator (use a value of 0 to denote an exact match). if (delta > MathConstants.TINY) { precision = wantdist / delta; } else { precision = 0.0; } // Figure out the scale factor for the adjustment (use a value of 0 if the start and end // points are coincident). The distances here have NOT been adjusted for the line scale factor. if (gotdist > MathConstants.TINY) { sfac = wantdist / gotdist; } else { sfac = 0.0; } // Remember the rotation and scaling factor m_IsAdjusted = true; m_Rotation = rotation; m_ScaleFactor = sfac; m_Precision = precision; }