Example #1
0
        private AlignmentPoint GetNearestObservedPoint(AxisPosition axisPosition, PierSide pierSide, out int checkSum)
        {
            AlignmentPoint alignmentPoint = AlignmentPoints
                                            .Where(p => p.PierSide == pierSide)
                                            .OrderBy(d => d.ObservedAxes.IncludedAngleTo(axisPosition)).FirstOrDefault();

            checkSum = alignmentPoint != null?GetChecksum(alignmentPoint.Id) : int.MinValue;

            return(alignmentPoint);
        }
Example #2
0
        public bool RemoveAlignmentPoint(AlignmentPoint pointToDelete)
        {
            try
            {
                bool result = AlignmentPoints.Remove(pointToDelete);
                if (result)
                {
                    SaveAlignmentPoints();
                }

                return(result);
            }
            catch (Exception ex)
            {
                LogException(ex, true);
                return(false);
            }
        }
Example #3
0
        internal static bool LoadAlignmentPreset(int preset)
        {
            object         HC         = null;
            string         tmptxt2    = "";
            string         VarStr     = "";
            int            pos        = 0;
            int            Index      = 0;
            int            ValidCount = 0;
            int            MaxCount   = 0;
            AlignmentPoint NewData    = new AlignmentPoint();

            bool ret = false;

            // set up a file path for the align.ini file
            //UPGRADE_TODO: (1067) Member oPersist is not defined in type Variant. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1067
            string Alignini = Convert.ToString(HC.oPersist.GetIniPath) + "\\ALIGN.ini";

            string key = "[alignment_preset" + preset.ToString() + "]";

            //UPGRADE_TODO: (1067) Member oPersist is not defined in type Variant. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1067
            string tmptxt = Convert.ToString(HC.oPersist.ReadIniValueEx("STAR_COUNT", key, Alignini));

            if (tmptxt != "")
            {
                MaxCount = Convert.ToInt32(Conversion.Val(tmptxt));
                if (MaxCount > MAX_STARS)
                {
                    MaxCount = MAX_STARS;
                }
            }
            else
            {
                MaxCount = 0;
            }

            //UPGRADE_TODO: (1065) Error handling statement (On Error Goto) could not be converted. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1065
            UpgradeHelpers.Helpers.NotUpgradedHelper.NotifyNotUpgradedElement("On Error Goto Label (DecodeError)");
            if (MaxCount != 0)
            {
                ValidCount = 0;
                int tempForEndVar = MaxCount;
                for (Index = 1; Index <= tempForEndVar; Index++)
                {
                    VarStr = "Star" + Index.ToString();
                    //UPGRADE_TODO: (1067) Member oPersist is not defined in type Variant. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1067
                    tmptxt = Convert.ToString(HC.oPersist.ReadIniValueEx(VarStr, key, Alignini));
                    if (tmptxt != "")
                    {
                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2           = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt            = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.AlignTime = DateTime.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2 = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt  = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.OrigTargetRA = Double.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2 = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt  = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.OrigTargetDEC = Double.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2          = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt           = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.TargetRA = Double.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2           = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt            = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.TargetDEC = Double.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2           = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        tmptxt            = tmptxt.Substring(Math.Max(tmptxt.Length - (Strings.Len(tmptxt) - pos), 0));
                        NewData.EncoderRA = Double.Parse(tmptxt2);

                        pos = (tmptxt.IndexOf(';') + 1);
                        if (pos == 0)
                        {
                            goto DecodeError;
                        }
                        tmptxt2            = tmptxt.Substring(0, Math.Min(pos - 1, tmptxt.Length));
                        NewData.EncoderDEC = Double.Parse(tmptxt2);

                        // all data read ok - copy to alignment stars
                        AlignmentStars[Index] = NewData;
                        ValidCount++;
                    }
                    else
                    {
                        goto DecodeError;
                    }
                }

DecodeError:
                //UPGRADE_TODO: (1069) Error handling statement (On Error Resume Next) was converted to a pattern that might have a different behavior. More Information: https://www.mobilize.net/vbtonet/ewis/ewi1069
                try
                {
                    gAlignmentStars_count = ValidCount;

                    // send to matrix will initialise the catalog and measured points arrays
                    SendtoMatrix();

                    ret = true;
                }
                catch (Exception exc)
                {
                    NotUpgradedHelper.NotifyNotUpgradedElement("Resume in On-Error-Resume-Next Block");
                }
            }

            return(ret);
        }
Example #4
0
        internal override bool TrySetPair(DxfCodePair pair)
        {
            switch (pair.Code)
            {
            case 100:
                _lastSubclassMarker = pair.StringValue;
                break;

            case 1:
                Value = pair.StringValue;
                break;

            case 2:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    XRecordTag = pair.StringValue;
                }
                else
                {
                    TextTag = pair.StringValue;
                }
                break;

            case 3:
                Prompt = pair.StringValue;
                break;

            case 7:
                TextStyleName = pair.StringValue;
                break;

            case 10:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    AlignmentPoint = AlignmentPoint.WithUpdatedX(pair.DoubleValue);
                }
                else
                {
                    Location = Location.WithUpdatedX(pair.DoubleValue);
                }
                break;

            case 20:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    AlignmentPoint = AlignmentPoint.WithUpdatedY(pair.DoubleValue);
                }
                else
                {
                    Location = Location.WithUpdatedY(pair.DoubleValue);
                }
                break;

            case 30:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    AlignmentPoint = AlignmentPoint.WithUpdatedZ(pair.DoubleValue);
                }
                else
                {
                    Location = Location.WithUpdatedZ(pair.DoubleValue);
                }
                break;

            case 11:
                this.SecondAlignmentPoint = this.SecondAlignmentPoint.WithUpdatedX(pair.DoubleValue);
                break;

            case 21:
                this.SecondAlignmentPoint = this.SecondAlignmentPoint.WithUpdatedY(pair.DoubleValue);
                break;

            case 31:
                this.SecondAlignmentPoint = this.SecondAlignmentPoint.WithUpdatedZ(pair.DoubleValue);
                break;

            case 39:
                Thickness = pair.DoubleValue;
                break;

            case 40:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    AnnotationScale = pair.DoubleValue;
                }
                else
                {
                    TextHeight = pair.DoubleValue;
                }
                break;

            case 41:
                RelativeXScaleFactor = pair.DoubleValue;
                break;

            case 50:
                Rotation = pair.DoubleValue;
                break;

            case 51:
                ObliqueAngle = pair.DoubleValue;
                break;

            case 70:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    switch (_xrecCode70Count)
                    {
                    case 0:
                        MTextFlag = (DxfMTextFlag)pair.ShortValue;
                        break;

                    case 1:
                        IsReallyLocked = BoolShort(pair.ShortValue);
                        break;

                    case 2:
                        _secondaryAttributeCount = pair.ShortValue;
                        break;

                    default:
                        Debug.Assert(false, "Unexpected extra values");
                        break;
                    }

                    _xrecCode70Count++;
                }
                else
                {
                    Flags = pair.ShortValue;
                }
                break;

            case 71:
                TextGenerationFlags = pair.ShortValue;
                break;

            case 72:
                HorizontalTextJustification = (DxfHorizontalTextJustification)pair.ShortValue;
                break;

            case 73:
                FieldLength = pair.ShortValue;
                break;

            case 74:
                VerticalTextJustification = (DxfVerticalTextJustification)pair.ShortValue;
                break;

            case 210:
                this.Normal = this.Normal.WithUpdatedX(pair.DoubleValue);
                break;

            case 220:
                this.Normal = this.Normal.WithUpdatedY(pair.DoubleValue);
                break;

            case 230:
                this.Normal = this.Normal.WithUpdatedZ(pair.DoubleValue);
                break;

            case 280:
                if (_lastSubclassMarker == AcDbXrecordText)
                {
                    KeepDuplicateRecords = BoolShort(pair.ShortValue);
                }
                else if (!_isVersionSet)
                {
                    Version       = (DxfVersion)pair.ShortValue;
                    _isVersionSet = true;
                }
                else
                {
                    IsLockedInBlock = BoolShort(pair.ShortValue);
                }
                break;

            case 340:
                SecondaryAttributesPointers.Pointers.Add(new DxfPointer(UIntHandle(pair.StringValue)));
                break;

            default:
                return(base.TrySetPair(pair));
            }

            return(true);
        }
Example #5
0
 public ReferencePointData(SimplePoint2d point2d, AlignmentPoint alignmentPoint) =>
 (this.Point2d, this.AlignmentPoint) = (point2d, alignmentPoint);
Example #6
0
        /// <summary>
        /// Gets the observed axis positions for a given mount axis position.
        /// </summary>
        /// <param name="mountAxes">Mount Ra and Dec axis positions</param>
        /// <param name="pierSide">The pier side to use 0 = East, 1 = West, 2 = Unknown</param>
        /// <returns></returns>
        public double[] GetObservedAxes(double[] mountAxes, int pierSide)
        {
            if (!IsAlignmentOn || !AlignmentPoints.Any())
            {
                return(mountAxes);                                            // Fast exit as alignment modeling is switched off or there are no points.
            }
            lock (_accessLock)
            {
                try
                {
                    ClearSelectedGotoPoints();
                    AxisPosition mAxes = new AxisPosition(mountAxes);
                    if (mAxes.IncludedAngleTo(_homePosition) < ProximityLimit)
                    {
                        return(mountAxes); // Fast exist if we are going home.
                    }
                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                      $"GetObservedAxes for {mountAxes[0]}/{mountAxes[1]}");
                    PierSide pSide = (PierSide)pierSide;
                    WriteLastAccessTime();
                    Matrix offsets = Matrix.CreateInstance(1, 2);
                    if (AlignmentPoints.Count == 1)
                    {
                        if (AlignmentPoints[0].PierSide == pSide)
                        {
                            offsets[0, 0] = AlignmentPoints[0].ObservedAxes[0] - AlignmentPoints[0].MountAxes[0];
                            offsets[0, 1] = AlignmentPoints[0].ObservedAxes[1] - AlignmentPoints[0].MountAxes[1];
                            AlignmentPoints[0].SelectedForGoto = true;
                            _selectedGotoPoints.Add(AlignmentPoints[0]);
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                              $"Single alignment point selected {AlignmentPoints[0].Id:D3}, Mount axes: {AlignmentPoints[0].MountAxes.RaAxis}/{AlignmentPoints[0].MountAxes.RaAxis}, Observed axes: {AlignmentPoints[0].ObservedAxes.RaAxis}/{AlignmentPoints[0].ObservedAxes.RaAxis}");
                        }
                    }
                    else
                    {
                        AlignmentPoint[] alignmentPoints = GetNearestMountPoints(mAxes, pSide, SampleSize);
                        int rows = alignmentPoints.Length;

                        if (rows > 2)
                        {
                            // Build features and values from registered points
                            Matrix features = Matrix.CreateInstance(rows, 3);
                            Matrix values   = Matrix.CreateInstance(rows, 2);

                            _stringBuilder.Clear();
                            _stringBuilder.Append("Points chosen are");
                            for (int i = 0; i < rows; i++)
                            {
                                var pt = alignmentPoints[i];
                                _stringBuilder.Append($" ({pt.Id:D3})");
                                features[i, 0]     = 1f;
                                features[i, 1]     = pt.MountAxes[0] * pt.MountAxes[0];
                                features[i, 2]     = pt.MountAxes[1] * pt.MountAxes[1];
                                values[i, 0]       = Range.RangePlusOrMinus180(pt.ObservedAxes[0] - pt.MountAxes[0]);
                                values[i, 1]       = Range.RangePlusOrMinus180(pt.ObservedAxes[1] - pt.MountAxes[1]);
                                pt.SelectedForGoto = true;
                                _selectedGotoPoints.Add(pt);
                            }

                            _stringBuilder.AppendLine(".");



                            // Solve the normal equation to get theta
                            Matrix theta = SolveNormalEquation(features, values);

                            // Calculate the difference for the incoming points
                            Matrix target = Matrix.CreateInstance(1, 3);
                            target[0, 0] = 1f;
                            target[0, 1] = mAxes[0] * mAxes[0];
                            target[0, 2] = mAxes[1] * mAxes[1];

                            offsets = target * theta;


                            _stringBuilder.AppendLine("Features");
                            _stringBuilder.AppendLine(features.ToString());
                            _stringBuilder.AppendLine("Values");
                            _stringBuilder.AppendLine(values.ToString());
                            _stringBuilder.AppendLine("Theta");
                            _stringBuilder.AppendLine(theta.ToString());
                            _stringBuilder.AppendLine("Target");
                            _stringBuilder.AppendLine(target.ToString());
                            _stringBuilder.AppendLine("Offsets");
                            _stringBuilder.AppendLine(offsets.ToString());
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name, _stringBuilder.ToString());
                            _stringBuilder.Clear();
                        }
                        else if (rows > 0)
                        {
                            // Just use the nearest point of the two.
                            offsets[0, 0] = alignmentPoints[0].ObservedAxes[0] - alignmentPoints[0].MountAxes[0];
                            offsets[0, 1] = alignmentPoints[0].ObservedAxes[1] - alignmentPoints[0].MountAxes[1];
                            AlignmentPoints[0].SelectedForGoto = true;
                            _selectedGotoPoints.Add(AlignmentPoints[0]);
                            RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                              $"Using nearest point of two {alignmentPoints[0].Id:D3}, Mount axes: {alignmentPoints[0].MountAxes.RaAxis}/{alignmentPoints[0].MountAxes.RaAxis}, Observed axes: {alignmentPoints[0].ObservedAxes.RaAxis}/{alignmentPoints[0].ObservedAxes.RaAxis}");
                        }
                        else
                        {
                            // Otherwise default to just using the nearest point with the same pier side
                            AlignmentPoint alignmentPoint = GetNearestMountPoint(mAxes, pSide);
                            if (alignmentPoint != null)
                            {
                                offsets[0, 0] = alignmentPoint.ObservedAxes[0] - alignmentPoint.MountAxes[0];
                                offsets[0, 1] = alignmentPoint.ObservedAxes[1] - alignmentPoint.MountAxes[1];
                                alignmentPoint.SelectedForGoto = true;
                                _selectedGotoPoints.Add(alignmentPoint);
                                RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                  $"Using nearest point in whole sky {alignmentPoint.Id:D3}, Mount axes: {alignmentPoint.MountAxes.RaAxis}/{alignmentPoint.MountAxes.RaAxis}, Observed axes: {alignmentPoint.ObservedAxes.RaAxis}/{alignmentPoint.ObservedAxes.RaAxis}");
                            }
                            else
                            {
                                RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                  $"No alignment points selected, Observed axes: {mountAxes[0]}/{mountAxes[1]}, pier side: {pierSide}");
                            }
                        }
                    }

                    var observedAxes = new[]
                    {
                        mountAxes[0] + offsets[0, 0],
                        mountAxes[1] + offsets[0, 1]
                    };
                    RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                      $"Correction -> Observer = {offsets[0, 0]}/{offsets[0, 1]}");
                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                      $"Mount axes: {mountAxes[0]}/{mountAxes[1]} -> Observed axes: {observedAxes[0]}/{observedAxes[1]}");

                    return(observedAxes);
                }
                catch (Exception ex)
                {
                    LogException(ex, true);
                    return(mountAxes);
                }
            }
        }
Example #7
0
        /// <summary>
        /// Gets the mount axis positions for a given observed axis position.
        /// </summary>
        /// <param name="observedAxes">Observed Ra and Dec axis positions</param>
        /// <param name="pierSide">The pier side to use 0 = East, 1 = West, 2 = Unknown</param>
        /// <returns></returns>
        public double[] GetMountAxes(double[] observedAxes, int pierSide)
        {
            if (!IsAlignmentOn || !AlignmentPoints.Any())
            {
                return(observedAxes);                                          // Fast exit as alignment modeling is switched off or there are no points.
            }
            lock (_accessLock)
            {
                try
                {
                    bool         postLogMessages = false;
                    AxisPosition sAxes           = new AxisPosition(observedAxes);
                    if (sAxes.IncludedAngleTo(_homePosition) < ProximityLimit)
                    {
                        return(observedAxes); // Fast exit if we are going home.
                    }
                    PierSide pSide = (PierSide)pierSide;
                    WriteLastAccessTime();
                    Matrix offsets = Matrix.CreateInstance(1, 2);
                    int    checksum;

                    if (AlignmentPoints.Count == 1)
                    {
                        checksum = GetChecksum(AlignmentPoints[0].Id);
                        if (checksum == _currentChecksum)
                        {
                            // Checksum hasn't changed so use the last offsets
                            offsets = _lastOffsets;
                        }
                        else
                        {
                            if (AlignmentPoints[0].PierSide == pSide)
                            {
                                RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                                  $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");
                                ClearSelectedPoints();
                                offsets[0, 0] = AlignmentPoints[0].MountAxes[0] - AlignmentPoints[0].ObservedAxes[0];
                                offsets[0, 1] = AlignmentPoints[0].MountAxes[1] - AlignmentPoints[0].ObservedAxes[1];
                                AlignmentPoints[0].Selected = true;
                                _selectedPoints.Add(AlignmentPoints[0]);
                                // Cache the offsets and checksum
                                _lastOffsets     = offsets;
                                _currentChecksum = checksum;
                                RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                  $"Single alignment point selected {AlignmentPoints[0].Id:D3}, Mount axes: {AlignmentPoints[0].MountAxes.RaAxis}/{AlignmentPoints[0].MountAxes.RaAxis}, Observed axes: {AlignmentPoints[0].ObservedAxes.RaAxis}/{AlignmentPoints[0].ObservedAxes.RaAxis}");
                                postLogMessages = true;
                            }
                        }
                    }
                    else
                    {
                        // Get the nearest points and their corresponding checksum value
                        AlignmentPoint[] alignmentPoints =
                            GetNearestObservedPoints(sAxes, pSide, SampleSize, out checksum);
                        if (checksum == _currentChecksum)
                        {
                            // Checksum hasn't changed to use the last offsets
                            offsets = _lastOffsets;
                        }
                        else
                        {
                            int rows = alignmentPoints.Length;
                            if (rows > 2)
                            {
                                RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                                  $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");
                                ClearSelectedPoints();
                                // Build features and values from registered points
                                Matrix features = Matrix.CreateInstance(rows, 3);
                                Matrix values   = Matrix.CreateInstance(rows, 2);
                                _stringBuilder.Clear();
                                _stringBuilder.Append("Points chosen are");
                                for (int i = 0; i < rows; i++)
                                {
                                    var pt = alignmentPoints[i];
                                    _stringBuilder.Append($" ({pt.Id:D3})");
                                    features[i, 0] = 1f;
                                    features[i, 1] = pt.ObservedAxes[0] * pt.ObservedAxes[0];
                                    features[i, 2] = pt.ObservedAxes[1] * pt.ObservedAxes[1];
                                    values[i, 0]   = Range.RangePlusOrMinus180(pt.MountAxes[0] - pt.ObservedAxes[0]);
                                    values[i, 1]   = Range.RangePlusOrMinus180(pt.MountAxes[1] - pt.ObservedAxes[1]);
                                    pt.Selected    = true;
                                    _selectedPoints.Add(pt);
                                }

                                _stringBuilder.AppendLine(".");

                                // Solve the normal equation to get theta
                                Matrix theta = SolveNormalEquation(features, values);

                                // Calculate the difference for the incoming points
                                Matrix target = Matrix.CreateInstance(1, 3);
                                target[0, 0] = 1f;
                                target[0, 1] = sAxes[0] * sAxes[0];
                                target[0, 2] = sAxes[1] * sAxes[1];

                                offsets = target * theta;


                                _stringBuilder.AppendLine("Features");
                                _stringBuilder.AppendLine(features.ToString());
                                _stringBuilder.AppendLine("Values");
                                _stringBuilder.AppendLine(values.ToString());
                                _stringBuilder.AppendLine("Theta");
                                _stringBuilder.AppendLine(theta.ToString());
                                _stringBuilder.AppendLine("Target");
                                _stringBuilder.AppendLine(target.ToString());
                                _stringBuilder.AppendLine("Offsets");
                                _stringBuilder.AppendLine(offsets.ToString());
                                RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name, _stringBuilder.ToString());
                                _stringBuilder.Clear();

                                // Cache the offsets and the checksum
                                _lastOffsets     = offsets;
                                _currentChecksum = checksum;
                                postLogMessages  = true;
                            }
                            else if (rows > 0)
                            {
                                checksum = GetChecksum(alignmentPoints[0].Id);
                                if (checksum == _currentChecksum)
                                {
                                    // Checksum hasn't changed so use the last offsets
                                    offsets = _lastOffsets;
                                }
                                else
                                {
                                    RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                                      $"GetMountAxes for {observedAxes[0]}/{observedAxes[1]}");

                                    ClearSelectedPoints();
                                    // Use the nearest point of the two.
                                    offsets[0, 0] =
                                        alignmentPoints[0].MountAxes[0] - alignmentPoints[0].ObservedAxes[0];
                                    offsets[0, 1] =
                                        alignmentPoints[0].MountAxes[1] - alignmentPoints[0].ObservedAxes[1];
                                    alignmentPoints[0].Selected = true;
                                    _selectedPoints.Add(alignmentPoints[0]);
                                    // Cache the offsets and checksum
                                    _lastOffsets     = offsets;
                                    _currentChecksum = checksum;
                                    postLogMessages  = true;
                                    RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                      $"Using nearest point of two {alignmentPoints[0].Id:D3}, Mount axes: {alignmentPoints[0].MountAxes.RaAxis}/{alignmentPoints[0].MountAxes.RaAxis}, Observed axes: {alignmentPoints[0].ObservedAxes.RaAxis}/{alignmentPoints[0].ObservedAxes.RaAxis}");
                                }
                            }
                            else
                            {
                                // Otherwise default to just using the nearest point in the whole
                                ClearSelectedPoints();
                                AlignmentPoint alignmentPoint = GetNearestObservedPoint(sAxes, pSide, out checksum);
                                if (alignmentPoint != null)
                                {
                                    offsets[0, 0]           = alignmentPoint.MountAxes[0] - alignmentPoint.ObservedAxes[0];
                                    offsets[0, 1]           = alignmentPoint.MountAxes[1] - alignmentPoint.ObservedAxes[1];
                                    alignmentPoint.Selected = true;
                                    _selectedPoints.Add(alignmentPoint);
                                    // Cache the offsets and checksum
                                    _lastOffsets     = offsets;
                                    _currentChecksum = checksum;
                                    postLogMessages  = true;
                                    RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                      $"Using nearest point in whole sky {alignmentPoint.Id:D3}, Mount axes: {alignmentPoint.MountAxes.RaAxis}/{alignmentPoint.MountAxes.RaAxis}, Observed axes: {alignmentPoint.ObservedAxes.RaAxis}/{alignmentPoint.ObservedAxes.RaAxis}");
                                }
                                else
                                {
                                    if (_currentChecksum != int.MinValue)
                                    {
                                        _currentChecksum = int.MinValue;
                                        RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                                          $"No alignment points selected, Observed axes: {observedAxes[0]}/{observedAxes[1]}, pier side: {pierSide}");
                                    }
                                }
                            }
                        }

                        // Otherwise default to using zero offset
                    }

                    var mountAxes = new[]
                    {
                        observedAxes[0] + offsets[0, 0],
                        observedAxes[1] + offsets[0, 1]
                    };
                    if (postLogMessages)
                    {
                        RaiseNotification(NotificationType.Data, MethodBase.GetCurrentMethod().Name,
                                          $"Correction -> Mount = {offsets[0, 0]}/{offsets[0, 1]}");
                        RaiseNotification(NotificationType.Information, MethodBase.GetCurrentMethod().Name,
                                          $"Observed axes: {observedAxes[0]}/{observedAxes[1]} -> Mount axes: {mountAxes[0]}/{mountAxes[1]}");
                    }

                    return(mountAxes);
                }
                catch (Exception ex)
                {
                    LogException(ex);
                    return(observedAxes);
                }
            }
        }