public static void Ctg255NRZ_CrtPrd(RLS rls,
                                     FOTrace trace,
                                     UInt16 fstIndex,
                                     double curPos)
 {
     // Дальность
     rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)0x20; rls.Ctgs[2].CdgInd++;
     rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)(fstIndex / 256); rls.Ctgs[2].CdgInd++;
     rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)(fstIndex % 256); rls.Ctgs[2].CdgInd++;
     if (rls.ReqSignal == RLSReqSignal.IndvNumb)
     {
         // Индивидуальный номер
         rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)(0x60 + (trace.IndvNumb / 65536)); rls.Ctgs[2].CdgInd++;
         rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)((trace.IndvNumb % 65536) / 256); rls.Ctgs[2].CdgInd++;
         rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)((trace.IndvNumb % 256)); rls.Ctgs[2].CdgInd++;
     }
     else
     {
         // Высота / топливо
         // Остаток топлива
         double k;
         if (trace.Speed != 0.0)
         {
             if (curPos <= 3600000 * trace.Length / trace.Speed)
             {
                 k = 3600000 * trace.Length / trace.Speed;
             }
             else
             {
                 k = 1.0;
             }
         }
         else
         {
             k = 0.0;
         }
         double ot = trace.BgnOT + (trace.EndOT - trace.BgnOT) * k;
         double h  = trace.BgnH + (trace.EndH - trace.BgnH) * k;
         if (ot <= 50.0)
         {
             rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)(0x70 + ot / 5.0);
         }
         else
         {
             rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = (byte)(0x70 + 10.0 + (ot - 50.0) / 10);
         }
         rls.Ctgs[2].CdgInd++;
         // Бедствие/норма
         if (trace.Trouble)
         {
             rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = 0xC0;
         }
         else
         {
             rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] = 0x40;
         }
         rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd] += (byte)(h * 100.0 / 256); rls.Ctgs[2].CdgInd++;
         rls.Ctgs[2].Cdg[rls.Ctgs[2].CdgInd]  = (byte)(h * 100.0 % 256); rls.Ctgs[2].CdgInd++;
     }
 }
Пример #2
0
        private void TraceDraw(FOTrace trace)
        {
            Path         tracePath = new Path();
            PathGeometry traceGeom = new PathGeometry();
            PathFigure   traceFig  = new PathFigure();

            traceFig.StartPoint = new Point(trace.PntList[0].X * RLModel.PX2KM,
                                            trace.PntList[0].Y * RLModel.PX2KM);
            for (int i = 1; i < trace.PntList.Count; i++)
            {
                traceFig.Segments.Add(new LineSegment(new Point(trace.PntList[i].X * RLModel.PX2KM,
                                                                trace.PntList[i].Y * RLModel.PX2KM),
                                                      true));
            }
            traceGeom.Figures.Add(traceFig);
            tracePath.Data            = traceGeom;
            tracePath.Stroke          = Brushes.DarkBlue;
            tracePath.StrokeThickness = 3.0;
            tracePath.StrokeDashArray.Add(10.0);
            tracePath.StrokeDashArray.Add(5.0);

            Path         foPath = new Path();
            PathGeometry foGeom = new PathGeometry();
            PathFigure   foFig  = new PathFigure(new Point(0, 0),
                                                 new List <PathSegment>
            {
                new LineSegment(new Point(-10, 4), true),
                new LineSegment(new Point(0, -14), true),
                new LineSegment(new Point(10, 4), true),
            }, true);

            foGeom.Figures.Add(foFig);
            foPath.Data            = foGeom;
            foPath.Stroke          = Brushes.Cyan;
            foPath.StrokeThickness = 3.0;
            foPath.Fill            = new SolidColorBrush(Color.FromRgb(0xFF, 0xFF, 0xFF));
            TransformGroup foTransGroup = new TransformGroup();

            foTransGroup.Children.Add(new RotateTransform(90.0, 0.0, 0.0));
            foTransGroup.Children.Add(trace.FORotateTransform);
            foTransGroup.Children.Add(trace.FOTransTransform);
            foPath.RenderTransform = foTransGroup;

            modelCanvas.Children.Add(tracePath);
            modelCanvas.Children.Add(foPath);

            trace.FOXAnim.PathGeometry = traceGeom;
            trace.FOYAnim.PathGeometry = traceGeom;
            trace.FOAAnim.PathGeometry = traceGeom;
        }
        private void buildAction()
        {
            progValue = 0.0;
            double durTime = rlModel.Duration.TotalMilliseconds;
            Point  foPos   = new Point();
            Point  foDrct  = new Point();

            // Построение отдельно для каждой РЛС / Категории
            for (int i = 0; i < rlModel.RLSPositionList.Count; i++)
            {
                for (int j = 0; j < rlModel.RLSPositionList[i].rlsList.Count; j++)
                {
                    // Псевдонимы
                    RLS rls = rlModel.RLSPositionList[i].rlsList[j];

                    // Инициализация раскадровки для построения
                    int rfCnt = 0;
                    curRLSName = rls.Name;
                    // mainUIDispatcher.Invoke(new DispatcherDelegate(buildInit));
                    buildInit();
                    drctDiag = new DrctDiag();
                    switch (rls.DiagType)
                    {
                    case RLSDiagType.Uniform:
                    { drctDiag.uniformInit(rls.Width); } break;

                    case RLSDiagType.SinX:
                    { drctDiag.sinxInit(rls.Width); } break;
                    }
                    double curVsrAzm = rls.Visir; double prvVsrAzm = rls.Visir;
                    double progStep = 100.0 * 2 * rls.Distance /
                                      (rlModel.RLSPositionList.Count * rlModel.RLSPositionList[i].rlsList.Count *
                                       consts.LIGHT_VEL * durTime / 1000.0);
                    double strpPeriod = TimeSpan.FromTicks((long)(TimeSpan.TicksPerSecond *
                                                                  2 * rls.Distance / consts.LIGHT_VEL)).TotalMilliseconds;

                    CtgPrcs.distList = new List <DistTrace> {
                    };
                    CtgPrcs.Prepare(rls);

                    while (curPos < durTime)
                    {
                        CtgPrcs.distList.Clear();
                        // Начало нового периода
                        switch (rls.Type)
                        {
                        case RLSType.PRL: { if (rls.Ctgs[1].IsEnabled)
                                            {
                                                CtgPrcs.Ctg255PRL_BgnPrd(rls, curVsrAzm);
                                            }
                        } break;

                        case RLSType.VRL: { if (rls.Ctgs[2].IsEnabled)
                                            {
                                                CtgPrcs.Ctg255VRL_BgnPrd(rls, curVsrAzm);
                                            }
                        } break;

                        case RLSType.NRZ: { if (rls.Ctgs[2].IsEnabled)
                                            {
                                                CtgPrcs.Ctg255NRZ_BgnPrd(rls, curVsrAzm);
                                            }
                        } break;
                        }

                        // Предварительные вычисления
                        for (int l = 0; l < rlModel.FOTraceList.Count; l++)
                        {
                            // Псевдоним
                            FOTrace trace = rlModel.FOTraceList[l];
                            // Определение взаиморасположения РЛС и ВО
                            if (trace.Speed != 0.0)
                            {
                                if (curPos <= 3600000 * trace.Length / trace.Speed)
                                {
                                    trace.buildGeom.GetPointAtFractionLength(curPos / (3600000.0 * trace.Length / trace.Speed), out foPos, out foDrct);
                                }
                                else
                                {
                                    trace.buildGeom.GetPointAtFractionLength(1.0, out foPos, out foDrct);
                                }
                            }
                            else
                            {
                                trace.buildGeom.GetPointAtFractionLength(0.0, out foPos, out foDrct);
                            }

                            double range = Math.Sqrt(Math.Pow(rlModel.RLSPositionList[i].Position.X - foPos.X, 2) +
                                                     Math.Pow(rlModel.RLSPositionList[i].Position.Y - foPos.Y, 2));

                            double angle = 90.0 + Math.Atan2((foPos.Y - rlModel.RLSPositionList[i].Position.Y),
                                                             (foPos.X - rlModel.RLSPositionList[i].Position.X)) * 180.0 / Math.PI;
                            if (angle < 0.0)
                            {
                                angle += 360.0;
                            }
                            double delta = curVsrAzm - angle;
                            if (delta >= 180.0)
                            {
                                delta -= 360.0;
                            }
                            else if (delta < -180.0)
                            {
                                delta += 360.0;
                            }

                            // Список дальностей
                            switch (rls.Type)
                            {
                                #region ПРЛ
                            case RLSType.PRL:
                            {
                                if ((range < rls.Distance) &&
                                    (Math.Abs(delta) < 22.5) &&
                                    (drctDiag.form[(int)(512 * (22.5 + delta) / 45.0)] > rls.Trsh))
                                {
                                    CtgPrcs.distList.Add(new DistTrace(l, range, delta));
                                }
                            } break;
                                #endregion ПРЛ

                                #region ВРЛ/НРЗ
                            case RLSType.VRL:
                            case RLSType.NRZ:
                            {
                                if ((range < rls.Distance) &&
                                    (Math.Abs(delta) < rls.Width * 360.0 / 4096.0))
                                {
                                    CtgPrcs.distList.Add(new DistTrace(l, range, delta));
                                }
                            } break;
                                #endregion ВРЛ/НРЗ
                            }
                        }

                        // Основная обработка
                        IEnumerable <DistTrace> ordDistBfr = CtgPrcs.distList.OrderBy(da => da.Range);
                        switch (rls.Type)
                        {
                            #region ПРЛ
                        case RLSType.PRL:
                        {
                            // Обработка текущего периода
                            double        implDur = (4 / 3) * rls.StrDuration * 0.3; // в километрах
                            UInt16        curFstInd = 0; UInt16 curLstInd = 0;
                            UInt16        clsFstInd = 0; UInt16 clsLstInd = 0;
                            List <double> amplList = new List <double> {
                            };
                            for (int d = 0; d < ordDistBfr.Count(); d++)
                            {
                                // Псевдонимы
                                DistTrace dt    = ordDistBfr.ElementAt(d);
                                FOTrace   trace = rlModel.FOTraceList[dt.TraceIndex];

                                int    ai   = (int)(512 * (22.5 + dt.Delta) / 45.0);
                                double ampl = drctDiag.form[ai];
                                curFstInd = (UInt16)Math.Ceiling(((dt.Range + (rls.Trsh / ampl) * (implDur / 4)) / consts.DSC));
                                curLstInd = (UInt16)Math.Floor(((dt.Range + implDur - (rls.Trsh / ampl) * (implDur / 4)) / consts.DSC));

                                if (amplList.Count == 0)
                                {
                                    for (int q = curFstInd; q <= curLstInd; q++)
                                    {
                                        amplList.Add(ampl * StrpForm(q * consts.DSC - dt.Range, implDur));
                                    }
                                    clsFstInd = curFstInd; clsLstInd = curLstInd;
                                }
                                else
                                {
                                    if (curFstInd > clsLstInd + 1)
                                    {
                                        // Выдача данных
                                        if (rls.Ctgs[0].IsEnabled)
                                        {
                                            CtgPrcs.Ctg107PRL_CrtPrd(rls, clsFstInd, clsLstInd, curVsrAzm);
                                        }
                                        if (rls.Ctgs[1].IsEnabled)
                                        {
                                            CtgPrcs.Ctg255PRL_CrtPrd(rls, clsFstInd, amplList);
                                        }

                                        // Очистка буфера амплитуд
                                        amplList.Clear();

                                        for (int q = curFstInd; q <= curLstInd; q++)
                                        {
                                            amplList.Add(ampl * StrpForm(q * consts.DSC - dt.Range, implDur));
                                        }
                                        clsFstInd = curFstInd; clsLstInd = curLstInd;
                                    }
                                    else
                                    {
                                        // Наложение амплитуд
                                        for (int q = curFstInd; q <= curLstInd; q++)
                                        {
                                            if (q - clsFstInd < amplList.Count)
                                            {
                                                double a = Math.Sqrt(Math.Pow(amplList[q - clsFstInd], 2) +
                                                                     Math.Pow(ampl * StrpForm(q * consts.DSC - ordDistBfr.ElementAt(d).Range, implDur), 2));
                                                if (a <= 100.0)
                                                {
                                                    amplList[q - clsFstInd] = a;
                                                }
                                                else
                                                {
                                                    amplList[q - clsFstInd] = 100.0;
                                                }
                                            }
                                            else
                                            {
                                                amplList.Add(ampl * StrpForm(q * consts.DSC - ordDistBfr.ElementAt(d).Range, implDur));
                                            }
                                        }
                                        if (curLstInd > clsLstInd)
                                        {
                                            clsLstInd = curLstInd;
                                        }
                                    }
                                }

                                if (d == ordDistBfr.Count() - 1)
                                {
                                    // Выдача данных
                                    if (rls.Ctgs[0].IsEnabled)
                                    {
                                        CtgPrcs.Ctg107PRL_CrtPrd(rls, clsFstInd, clsLstInd, curVsrAzm);
                                    }
                                    if (rls.Ctgs[1].IsEnabled)
                                    {
                                        CtgPrcs.Ctg255PRL_CrtPrd(rls, clsFstInd, amplList);
                                    }

                                    // Очистка буфера амплитуд
                                    amplList.Clear();
                                }
                            }

                            // Завершение текущего периода
                            if (rls.Ctgs[1].IsEnabled)
                            {
                                CtgPrcs.Ctg255PRL_EndPrd(rls, curPos, rlModel.SyncDoub);
                            }

                            // Завершение текущего сектора
                            if ((rls.Ctgs[0].IsEnabled) &&
                                ((byte)(curVsrAzm / consts.SCT_WDT) !=
                                 (byte)(prvVsrAzm / consts.SCT_WDT)))
                            {
                                CtgPrcs.Ctg107PRL_EndSct(rls, curVsrAzm, curPos, rlModel.SyncDoub);
                            }
                        } break;
                            #endregion ПРЛ

                            #region ВРЛ
                        case RLSType.VRL:
                        {
                            // Обработка текущего периода
                            for (int d = 0; d < ordDistBfr.Count(); d++)
                            {
                                // Псевдоним
                                DistTrace dt = ordDistBfr.ElementAt(d);
                                // Выдача данных
                                if (rls.Ctgs[2].IsEnabled)
                                {
                                    CtgPrcs.Ctg255VRL_CrtPrd(rls,
                                                             rlModel.FOTraceList[dt.TraceIndex],
                                                             (UInt16)(dt.Range * 40),
                                                             curPos);
                                }
                            }
                            // Завершение текущего периода
                            if (rls.Ctgs[2].IsEnabled)
                            {
                                CtgPrcs.Ctg255VRL_EndPrd(rls,
                                                         curPos,
                                                         rlModel.SyncDoub);
                            }
                        } break;
                            #endregion ВРЛ

                            #region НРЗ
                        case RLSType.NRZ:
                        {
                            // Обработка текущего периода
                            for (int d = 0; d < ordDistBfr.Count(); d++)
                            {
                                // Псевдоним
                                DistTrace dt = ordDistBfr.ElementAt(d);
                                // Выдача данных
                                if (rls.Ctgs[2].IsEnabled)
                                {
                                    CtgPrcs.Ctg255NRZ_CrtPrd(rls,
                                                             rlModel.FOTraceList[dt.TraceIndex],
                                                             (UInt16)(dt.Range * 40),
                                                             curPos);
                                }
                            }
                            // Завершение текущего периода
                            if (rls.Ctgs[2].IsEnabled)
                            {
                                CtgPrcs.Ctg255NRZ_EndPrd(rls,
                                                         curPos,
                                                         rlModel.SyncDoub);
                            }
                        } break;
                            #endregion НРЗ
                        }

                        // Шаг вперед
                        curPos    += strpPeriod;
                        progValue += progStep;
                        prvVsrAzm  = curVsrAzm;
                        curVsrAzm += 360.0 * rlModel.RLSPositionList[i].rlsList[j].Rate * strpPeriod / 60000;
                        if (curVsrAzm >= 360.0)
                        {
                            curVsrAzm -= 360.0;
                        }

                        if (rfCnt < int.MaxValue)
                        {
                            rfCnt++;
                        }
                        else
                        {
                            rfCnt = 0;
                        }
                        if (rfCnt % 1000 == 0)
                        {
                            mainUIDispatcher.Invoke(new DispatcherDelegate(buildUpdate));
                        }
                    }
                }
            }

            #region Сборка общего потока кодограмм
            cdgStream = new CdgStream();
            for (int i = 0; i < rlModel.RLSPositionList.Count; i++)
            {
                for (int j = 0; j < rlModel.RLSPositionList[i].rlsList.Count; j++)
                {
                    for (int k = 0; k < rlModel.RLSPositionList[i].rlsList[j].Ctgs.LongLength; k++)
                    {
                        if (rlModel.RLSPositionList[i].rlsList[j].Ctgs[k].IsEnabled)
                        {
                            cdgStream.ctgEPList.Add(
                                new System.Net.IPEndPoint(rlModel.RLSPositionList[i].rlsList[j].Ctgs[k].EndPoint.Address,
                                                          rlModel.RLSPositionList[i].rlsList[j].Ctgs[k].EndPoint.Port));
                            #region Построение имени категории
                            string ctgName = rlModel.RLSPositionList[i].rlsList[j].Name + " - ";
                            switch (rlModel.RLSPositionList[i].rlsList[j].Type)
                            {
                            case RLSType.PRL:
                            {
                                switch (k)
                                {
                                case 0: { ctgName += "Категория 107"; } break;

                                case 1: { ctgName += "Категория 255"; } break;
                                }
                            } break;

                            case RLSType.VRL:
                            {
                                switch (k)
                                {
                                case 0: { ctgName += "Категория 1"; } break;

                                case 1: { ctgName += "Категория 2"; } break;
                                }
                            } break;

                            case RLSType.NRZ:
                            {
                                switch (k)
                                {
                                case 0: { ctgName += "Категория 1"; } break;

                                case 1: { ctgName += "Категория 2"; } break;
                                }
                            } break;
                            }
                            #endregion
                            cdgStream.ctgNameList.Add(ctgName);
                            rlModel.RLSPositionList[i].rlsList[j].Ctgs[k].CdgInd = 0;
                        }
                    }
                }
            }
            bool notRdy = true;
            while (notRdy)
            {
                notRdy = false;
                int[] sel = new int[3] {
                    -1, -1, -1
                };
                int    chCnt  = -1;
                int    selCh  = -1;
                double minPos = double.MaxValue;
                for (int i = 0; i < rlModel.RLSPositionList.Count; i++)
                {
                    for (int j = 0; j < rlModel.RLSPositionList[i].rlsList.Count; j++)
                    {
                        for (int k = 0; k < rlModel.RLSPositionList[i].rlsList[j].Ctgs.Length; k++)
                        {
                            Category ctg = rlModel.RLSPositionList[i].rlsList[j].Ctgs[k];
                            if (ctg.IsEnabled)
                            {
                                chCnt++;
                            }
                            if (ctg.CdgInd != ctg.CdgList.Count)
                            {
                                notRdy = true;
                                if (ctg.CdgList[ctg.CdgInd].pos < minPos)
                                {
                                    sel[0] = i; sel[1] = j; sel[2] = k;
                                    selCh  = chCnt;
                                    minPos = ctg.CdgList[ctg.CdgInd].pos;
                                }
                            }
                        }
                    }
                }
                if (sel[0] != -1)
                {
                    if (selCh < consts.MAX_CDG_CHN)
                    {
                        cdgStream.cdgList.Add(new StrmCdg(rlModel.RLSPositionList[sel[0]].rlsList[sel[1]].Ctgs[sel[2]].CdgList[rlModel.RLSPositionList[sel[0]].rlsList[sel[1]].Ctgs[sel[2]].CdgInd],
                                                          selCh));
                    }
                    rlModel.RLSPositionList[sel[0]].rlsList[sel[1]].Ctgs[sel[2]].CdgInd++;
                }
            }
            #endregion Сборка общего потока кодограмм

            // Отображение готовности
            curPos    = durTime;
            progValue = 100.0;
            mainUIDispatcher.Invoke(new DispatcherDelegate(buildUpdate));

            // Остановка после проигрывания
            mainUIDispatcher.Invoke(new DispatcherDelegate(buildRestore));
        }
        public void modelCanvas_MouseLeftButtonDown(object sender, MouseEventArgs e)
        {
            Point mViewerPos = Mouse.GetPosition(modelScrollViewer);
            Point mCanvasPos = Mouse.GetPosition(modelCanvas);

            switch (editMode)
            {
            case (EditMode.Hand):
            {
                prvMousePosition = mViewerPos;
                crtMousePosition = prvMousePosition;
            } break;

            case (EditMode.RLS):
            {
                if (trgObject == TargetObject.None)
                {
                    RLSListWindow dlg = new RLSListWindow();
                    dlg.rlsList = new List <RLS> {
                    };
                    dlg.ShowDialog();
                    if (dlg.DialogResult == (bool?)true)
                    {
                        RLSPosition rlsPos = new RLSPosition(mCanvasPos);
                        rlModel.RLSPositionList.Add(rlsPos);
                        foreach (RLS rls in dlg.rlsList)
                        {
                            rls.RateAnimation = new DoubleAnimation(0.0, 360.0,
                                                                    TimeSpan.FromMinutes(1 / rls.Rate));
                            rls.RateAnimation.RepeatBehavior = RepeatBehavior.Forever;
                            string UID = SetUID();
                            this.RegisterName(UID, rls.RateTransform);
                            rlModel.playStrBoard.Children.Add(rls.RateAnimation);
                            RLSDraw(rlsPos.Position, rls);
                            Storyboard.SetTargetName(rls.RateAnimation, UID);
                            Storyboard.SetTargetProperty(rls.RateAnimation, new PropertyPath(RotateTransform.AngleProperty));
                            rlsPos.rlsList.Add(rls);
                            rls.Pathes[GRID].Tag = rlModel.RLSPositionList.IndexOf(rlsPos);
                            rls.Pathes[VSR].Tag  = rlModel.RLSPositionList.IndexOf(rlsPos);
                        }
                    }
                }
                else if (trgObject == TargetObject.RLS)
                {
                    prvMousePosition = mCanvasPos;
                    crtMousePosition = prvMousePosition;
                    //MessageBox.Show("РЛС. Индекс = " + trgIndex.ToString() + Environment.NewLine +
                    //                "Выделана РЛС = " + selTrgIndex);
                }
            } break;

            case (EditMode.Path):
            {
                if (trgObject == TargetObject.None)
                {
                    newTracePolyLine                 = new Polyline();
                    newTracePolyLine.Stroke          = Brushes.Blue;
                    newTracePolyLine.StrokeThickness = 5.0;
                    newTracePolyLine.StrokeDashArray.Add(10.0);
                    newTracePolyLine.StrokeDashArray.Add(5.0);
                    newTracePolyLine.Points.Add(mCanvasPos);
                    newTracePolyLine.Points.Add(mCanvasPos);
                    modelCanvas.Children.Add(newTracePolyLine);
                    editMode = EditMode.PathDraw;
                }
            } break;

            case (EditMode.PathDraw):
            {
                if ((newTracePolyLine.Points.Count > 1) &&
                    (newTracePolyLine.Points[newTracePolyLine.Points.Count - 2] == mCanvasPos))
                {
                    double traceLength = 0.0;
                    for (int i = 1; i < newTracePolyLine.Points.Count; i++)
                    {
                        traceLength += Math.Sqrt(Math.Pow((newTracePolyLine.Points[i].Y - newTracePolyLine.Points[i - 1].Y), 2) +
                                                 Math.Pow((newTracePolyLine.Points[i].X - newTracePolyLine.Points[i - 1].X), 2));
                    }
                    traceLength /= RLModel.PX2KM;         // graphic to real length
                    TraceOptionsWindow dlg = new TraceOptionsWindow();
                    dlg.lenghtTextBox.Text = traceLength.ToString("F");
                    dlg.ShowDialog();
                    if (dlg.DialogResult == (bool?)true)
                    {
                        FOTrace newFOTrace = new FOTrace();
                        newFOTrace.Length   = traceLength;
                        newFOTrace.Speed    = dlg.speedSlider.Value;
                        newFOTrace.IndvNumb = UInt32.Parse(dlg.indvNumbTextBox.Text);
                        newFOTrace.BgnOT    = double.Parse(dlg.bgnOTTextBox.Text);
                        newFOTrace.EndOT    = double.Parse(dlg.endOTTextBox.Text);
                        newFOTrace.BgnH     = double.Parse(dlg.bgnHTextBox.Text);
                        newFOTrace.EndH     = double.Parse(dlg.endHTextBox.Text);
                        newFOTrace.Trouble  = dlg.troubleCheckBox.IsChecked.Value;

                        for (int i = 0; i < newTracePolyLine.Points.Count; i++)
                        {
                            newFOTrace.PntList.Add(new Point(newTracePolyLine.Points[i].X / RLModel.PX2KM,
                                                             newTracePolyLine.Points[i].Y / RLModel.PX2KM));
                        }
                        double a = -Math.Atan((newTracePolyLine.Points[1].X - newTracePolyLine.Points[0].X) /
                                              (newTracePolyLine.Points[1].Y - newTracePolyLine.Points[0].Y)) * 180 / Math.PI;
                        if (newTracePolyLine.Points[1].Y - newTracePolyLine.Points[0].Y >= 0)
                        {
                            a += 180;
                        }
                        newFOTrace.FORotateTransform = new RotateTransform(a - 90.0, 0.0, 0.0);
                        newFOTrace.FOTransTransform  = new TranslateTransform(newTracePolyLine.Points[0].X,
                                                                              newTracePolyLine.Points[0].Y);

                        #region SetPlayAnimation
                        newFOTrace.FOXAnim = new DoubleAnimationUsingPath();
                        newFOTrace.FOXAnim.RepeatBehavior = new RepeatBehavior(1);
                        if (newFOTrace.Speed != 0.0)
                        {
                            newFOTrace.FOXAnim.Duration = new Duration(TimeSpan.FromHours(newFOTrace.Length / newFOTrace.Speed));
                        }
                        else
                        {
                            newFOTrace.FOXAnim.Duration = Duration.Forever;
                        }
                        string UID = SetUID();
                        this.RegisterName(UID, newFOTrace.FOTransTransform);
                        Storyboard.SetTargetName(newFOTrace.FOXAnim, UID);
                        Storyboard.SetTargetProperty(newFOTrace.FOXAnim, new PropertyPath(TranslateTransform.XProperty));
                        newFOTrace.FOXAnim.Source = PathAnimationSource.X;

                        newFOTrace.FOYAnim = new DoubleAnimationUsingPath();
                        newFOTrace.FOYAnim.RepeatBehavior = new RepeatBehavior(1);
                        if (newFOTrace.Speed != 0.0)
                        {
                            newFOTrace.FOYAnim.Duration = new Duration(TimeSpan.FromHours(newFOTrace.Length / newFOTrace.Speed));
                        }
                        else
                        {
                            newFOTrace.FOYAnim.Duration = Duration.Forever;
                        }
                        UID = SetUID();
                        this.RegisterName(UID, newFOTrace.FOTransTransform);
                        Storyboard.SetTargetName(newFOTrace.FOYAnim, UID);
                        Storyboard.SetTargetProperty(newFOTrace.FOYAnim, new PropertyPath(TranslateTransform.YProperty));
                        newFOTrace.FOYAnim.Source = PathAnimationSource.Y;

                        newFOTrace.FOAAnim = new DoubleAnimationUsingPath();
                        newFOTrace.FOAAnim.RepeatBehavior = new RepeatBehavior(1);
                        if (newFOTrace.Speed != 0.0)
                        {
                            newFOTrace.FOAAnim.Duration = new Duration(TimeSpan.FromHours(newFOTrace.Length / newFOTrace.Speed));
                        }
                        else
                        {
                            newFOTrace.FOAAnim.Duration = Duration.Forever;
                        }
                        UID = SetUID();
                        this.RegisterName(UID, newFOTrace.FORotateTransform);
                        Storyboard.SetTargetName(newFOTrace.FOAAnim, UID);
                        Storyboard.SetTargetProperty(newFOTrace.FOAAnim, new PropertyPath(RotateTransform.AngleProperty));
                        newFOTrace.FOAAnim.Source = PathAnimationSource.Angle;
                        #endregion SetPlayAnimation

                        TraceDraw(newFOTrace);

                        rlModel.playStrBoard.Children.Add(newFOTrace.FOXAnim);
                        rlModel.playStrBoard.Children.Add(newFOTrace.FOYAnim);
                        rlModel.playStrBoard.Children.Add(newFOTrace.FOAAnim);

                        rlModel.FOTraceList.Add(newFOTrace);
                    }
                    newTracePolyLine.Points.Clear();
                    editMode = EditMode.Path;
                }
                else
                {
                    newTracePolyLine.Points.Add(mCanvasPos);
                }
            } break;
            }
        }