/// <summary>
 /// получение обработанного трека
 /// </summary>
 /// <param name="track">Исходный трек</param>
 /// <returns>Обработанный трек</returns>
 public ProccessedTrack ProccessTrack(Track track)
 {
     ProccessedTrack pTrack = new ProccessedTrack(Message);
     avg = Parameters[0].IntegerValue;
     TrackItem[] trackItems = track.TrackItems;
     for (int i = 0; i < avg / 2; i++)
     {
         ProccessedTrackItem pItem = new ProccessedTrackItem(trackItems[i], trackItems[i].Latitude, trackItems[i].Longitude);
         pTrack.AddProccessedTrackItem(pItem);
     }
     for (int i = avg / 2; i < trackItems.Length - avg / 2; i++)
     {
         double sumLat = 0;
         double sumLon = 0;
         for (int j = i - avg / 2; j <= i + avg / 2; j++)
         {
             sumLat += trackItems[j].Latitude;
             sumLon += trackItems[j].Longitude;
         }
         sumLat /= avg + (avg + 1) % 2;
         sumLon /= avg + (avg + 1) % 2;
         ProccessedTrackItem pItem = new ProccessedTrackItem(trackItems[i], sumLat, sumLon);
         pTrack.AddProccessedTrackItem(pItem);
     }
     for (int i = trackItems.Length - avg / 2; i < trackItems.Length; i++)
     {
         ProccessedTrackItem pItem = new ProccessedTrackItem(trackItems[i], trackItems[i].Latitude, trackItems[i].Longitude);
         pTrack.AddProccessedTrackItem(pItem);
     }
     return pTrack;
 }
 public ProccessedTrack ProccessTrack(Track track)
 {
     ProccessedTrack pTrack = new ProccessedTrack(Message, false);
     foreach (TrackItem item in track.TrackItems)
     {
         double[] vec = new double[] {item.Longitude,item.Latitude };
         double[] newVec = CalcEstimation(vec);
         ProccessedTrackItem pItem = new ProccessedTrackItem(item, newVec[1], newVec[0]);
         pTrack.AddProccessedTrackItem(pItem);
     }
     return pTrack;
 }
 /// <summary>
 /// Создание трека по прогнозу
 /// </summary>
 /// <param name="track">Исходный трек</param>
 /// <returns>Прогнозируемый трек</returns>
 public ProccessedTrack ProccessTrack(Track track)
 {
     avg = Parameters[0].IntegerValue;
     ProccessedTrack res = GetDifferences(track);
     res = GetAvgDifferences(res, track);
     res = GetAverageFromDiffrences(res, track);
     ProccessedTrackItem[] pItems = res.ProccessedTrackItems;
     TrackItem[] trackItems = track.TrackItems;
     ProccessedTrack pTrack = new ProccessedTrack("ARIMAX");
     int vars = Parameters[1].IntegerValue;
     int eqCount = Parameters[2].IntegerValue;
     eqCount = eqCount < vars ? vars : eqCount;
     for (int i = 0; i < vars+eqCount;i++ )
     {
         pTrack.AddProccessedTrackItem(new ProccessedTrackItem(trackItems[i], trackItems[i].Latitude, trackItems[i].Longitude));
     }
     for (int i = vars+eqCount; i < pItems.Length;i++ )
     {
         double[,] mriLat = new double[eqCount, vars];
         double[,] mriLon = new double[eqCount, vars];
         double[] vecLat = new double[eqCount];
         double[] vecLon = new double[eqCount];
         for (int x = 0; x < eqCount; x++)
         {
             for (int y = 0; y < vars; y++)
             {
                 mriLat[x, y] = pItems[i - 2 - x - y].ProccessedLatitude;
                 mriLon[x, y] = pItems[i - 2 - x - y].ProccessedLongitude;
             }
             vecLat[x] = pItems[i - 1 - x].ProccessedLatitude;
             vecLon[x] = pItems[i - 1 - x].ProccessedLongitude;
         }
         double[] coefsLat = Solver.SolveLSM(mriLat, vecLat);
         double[] coefsLon = Solver.SolveLSM(mriLon, vecLon);
         double resLat = 0;
         double resLon = 0;
         if (double.IsNaN(coefsLat[0]) || double.IsNaN(coefsLon[0]))
         {
             resLat = trackItems[i].Latitude;
             resLon = trackItems[i].Longitude;
         }
         else
         {
             for (int count = 0; count < vars; count++)
             {
                 resLat += pItems[i - 1 - count].ProccessedLatitude * coefsLat[count];
                 resLon += pItems[i - 1 - count].ProccessedLongitude * coefsLon[count];
             }
         }
         pTrack.AddProccessedTrackItem(new ProccessedTrackItem(trackItems[i], resLat, resLon));
     }
     return pTrack;
 }
 public ProccessedTrack ProccessTrack(Track track)
 {
     ProccessedTrack pTrack = new ProccessedTrack("Фильтр Калмана",false);
     pTaL = new double[3];
     InitializeP();
     NormalRandom normRand = new NormalRandom();
     aX = Parameters[0].DoubleValue;
     aY = Parameters[1].DoubleValue;
     r = Parameters[2].DoubleValue;
     double predLatForAdd = 0;
     double predLonForAdd = 0;
     for (int i = 0; i < track.TrackItems.Length; i++)
     {
         DateTime date = track.TrackItems[i].Date;
         double[] kTal = new double[2];
         for (int j = 0; j < 2; j++)
         {
             kTal[j] = pTaL[j] / (pTaL[j] + r);
             /*pTaL[j] = (1 - kTal[j]) * pTaL[j];*/
             pTaL[j] -= (pTaL[j] > r) ? r : 0;
         }
         double predLat = predLatForAdd + aX * normRand.Next();
         double predLon = predLonForAdd + aY * normRand.Next();
         predLatForAdd = predLat + kTal[0] * (track.TrackItems[i].Latitude - predLat);
         predLonForAdd = predLon + kTal[1] * (track.TrackItems[i].Longitude - predLon);
         ProccessedTrackItem temp = new ProccessedTrackItem(track.TrackItems[i],predLatForAdd, predLonForAdd);
         pTrack.AddProccessedTrackItem(temp);
     }
     return pTrack;
 }
 /// <summary>
 /// обработать таблицу с обработанным треком
 /// </summary>
 /// <param name="dataTable">Таблица</param>
 /// <returns>Обработанный трек</returns>
 private ProccessedTrack ParseProccessedDataTable(DataTable dataTable)
 {
     bool isVector = dataTable.Columns.Count > 7;
     ProccessedTrack pTrack = new ProccessedTrack(dataTable.TableName.Replace('_', ' ').Replace("$", ""), isVector);
     DataRow[] dataRows = dataTable.Select();
     if (isVector)
     {
         foreach (DataRow row in dataRows)
         {
             double stlat = (double)row[1];
             double stlon = (double)row[2];
             DateTime stdate = (DateTime)row[3];
             double enlat = (double)row[4];
             double enlon = (double)row[5];
             DateTime endate = (DateTime)row[6];
             TimeSpan lapse = endate - stdate;
             double oSpeed = (double)row[8];
             double pSpeed = (double)row[9];
             double oDist = (double)row[10];
             double pDist = (double)row[11];
             double oHead = (double)row[12];
             double pHead = (double)row[13];
             TrackItem stItem = new TrackItem(stlat, stlon, stdate);
             TrackItem enItem = new TrackItem(enlat, enlon, endate);
             TrackVectorItem vItem = new TrackVectorItem(stItem, enItem);
             ProccessedTrackVectorItem pVector = new ProccessedTrackVectorItem(vItem, pSpeed, pDist, pHead);
             pTrack.AddProccedTrackVectorItem(pVector);
         }
     }
     else
     {
         foreach (DataRow row in dataRows)
         {
             double lat = (double)row[1];
             double lon = (double)row[2];
             DateTime date = (DateTime)row[3];
             double plat = (double)row[4];
             double plon = (double)row[5];
             double dist = (double)row[6];
             TrackItem item = new TrackItem(lat, lon, date);
             ProccessedTrackItem pItem = new ProccessedTrackItem(item, plat, plon);
             pTrack.AddProccessedTrackItem(pItem);
         }
     }
     return pTrack;
 }
 /// <summary>
 /// Получить трек с разностями
 /// </summary>
 /// <param name="track">Исходный трек</param>
 /// <returns>Трек с разносятми</returns>
 private ProccessedTrack GetDifferences(Track track)
 {
     ProccessedTrack res = new ProccessedTrack("Разности");
     if (track.TrackItems.Length>0)
     {
         res.AddProccessedTrackItem(new ProccessedTrackItem(track.TrackItems[0], track.TrackItems[0].Latitude, track.TrackItems[0].Longitude));
     }
     TrackItem[] trackItems = track.TrackItems;
     for (int i = 1; i < trackItems.Length; i++)
     {
         res.AddProccessedTrackItem(new ProccessedTrackItem(trackItems[i], trackItems[i].Latitude - trackItems[i - 1].Latitude, trackItems[i].Longitude - trackItems[i - 1].Longitude));
     }
     return res;
 }
 /// <summary>
 /// Получить трек со средними разносятми
 /// </summary>
 /// <param name="pTrack">Трек с разносятми</param>
 /// <param name="track">Исходный трек</param>
 /// <returns>Трек со средними разносятми</returns>
 private ProccessedTrack GetAvgDifferences(ProccessedTrack pTrack, Track track)
 {
     ProccessedTrackItem[] pItems = pTrack.ProccessedTrackItems;
     ProccessedTrack res = new ProccessedTrack("Средние разности");
     for (int i = 0; i < avg / 2 + 1;i++ )
     {
         res.AddProccessedTrackItem(pItems[i]);
     }
     TrackItem[] trackItems = track.TrackItems;
     for (int i = avg / 2 + 1;i<pItems.Length-avg/2 ; i++)
     {
         double sumLat = 0;
         double sumLon = 0;
         for (int j = i - avg / 2; j <= i + avg / 2; j++)
         {
             sumLat += pItems[j].ProccessedLatitude;
             sumLon += pItems[j].ProccessedLongitude;
         }
         sumLat /= avg;
         sumLon /= avg;
         ProccessedTrackItem pItem = new ProccessedTrackItem(trackItems[i], sumLat, sumLon);
         res.AddProccessedTrackItem(pItem);
     }
     for (int i = trackItems.Length - avg / 2; i < trackItems.Length; i++)
     {
         res.AddProccessedTrackItem(pItems[i]);
     }
     return res;
 }
 /// <summary>
 /// Получить среднее скользящее по средним разностям 
 /// </summary>
 /// <param name="pTrack">Трек со средними разностями</param>
 /// <param name="track">Исходный трек</param>
 /// <returns>Трек со средним скользящим</returns>
 private ProccessedTrack GetAverageFromDiffrences(ProccessedTrack pTrack, Track track)
 {
     ProccessedTrackItem[] pItems = pTrack.ProccessedTrackItems;
     ProccessedTrack res = new ProccessedTrack("Среднее из разностей");
     TrackItem[] trackItems = track.TrackItems;
     if (pItems.Length > 0)
     {
         res.AddProccessedTrackItem(pItems[0]);
     }
     for (int i = 1; i < pItems.Length; i++)
     {
         res.AddProccessedTrackItem(new ProccessedTrackItem(trackItems[i], res.ProccessedTrackItems[i - 1].ProccessedLatitude + pItems[i].ProccessedLatitude, res.ProccessedTrackItems[i - 1].ProccessedLongitude + pItems[i].ProccessedLongitude));
     }
     return res;
 }