Пример #1
0
        /// <summary>
        /// загружает ряд наблюдений с ближайшей МС
        /// </summary>
        /// <param name="from">начало ряда</param>
        /// <param name="to">конец ряда</param>
        /// <param name="coordinates">координаты исходного ряда</param>
        /// <returns></returns>
        private static RawRange getNearestRange(DateTime from, DateTime to, PointLatLng coordinates)
        {
            if (from > to)
            {
                throw new WindEnergyException("Дата from больше, чем to");
            }
            RawRange res = null;

            RP5MeteostationInfo nearestMS = Vars.RP5Meteostations.GetNearestMS(coordinates);

            if (nearestMS == null)
            {
                throw new Exception("Не удалось найти ближайшую метеостанцию в заданном радиусе");
            }

            RP5ru provider = new RP5ru(Vars.Options.CacheFolder + "\\rp5.ru");

            provider.GetMeteostationExtInfo(ref nearestMS);

            if (from < nearestMS.MonitoringFrom) //если исходный ряд начинается
            {
                from = nearestMS.MonitoringFrom;
            }
            if (from > to)
            {
                throw new Exception("Ряды не пересекаются: один из рядов заканчивается раньше, чем начинается другой");
            }
            res = provider.GetRange(from, to, nearestMS);
            return(res);
        }
Пример #2
0
        public FormLoadFromNASA(PointLatLng selectedPoint)
        {
            InitializeComponent();
            Result       = null;
            DialogResult = DialogResult.None;
            geocoder     = new Arcgis(Vars.Options.CacheFolder + "\\arcgis");
            comboBoxSpeedHeight.Items.AddRange(NasaWindSpeedHeight.WS10M.GetItems().ToArray());
            comboBoxSpeedHeight.SelectedItem = NasaWindSpeedHeight.WS10M.Description();

            point = selectedPoint;
            if (point.IsEmpty) //если точка пустая, то надо попробовать взять из последних
            {
                point = Vars.Options.LoadNasaLastPoint;
            }
            if (!point.IsEmpty)
            {
                spoint                     = new RP5MeteostationInfo();
                spoint.Position            = point;
                labelPointCoordinates.Text = $"Широта: {point.Lat:0.000} Долгота: {point.Lng:0.000}";

                loadAddressAsync(point);

                buttonDownload.Enabled         = true;
                dateTimePickerFromDate.Enabled = true;
                dateTimePickerToDate.Enabled   = true;
            }
        }
        private void gmapControlMap_OnMarkerClick(GMapMarker item, MouseEventArgs e)
        {
            item = item ?? throw new ArgumentNullException(nameof(item));
            if (item.Tag.GetType() != typeof(RP5MeteostationInfo))
            {
                return;
            }
            RP5MeteostationInfo mi = (RP5MeteostationInfo)item.Tag;

            if (IsDialog)
            {
                Result       = mi;
                DialogResult = DialogResult.OK;
                Close();
            }
            else
            {
                FormLoadFromRP5 frm = new FormLoadFromRP5(mi);
                if (frm.ShowDialog(this) == DialogResult.OK)
                {
                    RawRange res = frm.Result;
                    WindEnergy.UI.Ext.TabPageExt tab = Program.winMain.mainTabControl.OpenNewTab(res, res.Name);
                    tab.HasNotSavedChanges = true;
                    _ = Program.winMain.Focus();
                }
            }
        }
Пример #4
0
        private void linkLabelShowOnMap_LinkClicked(object sender, LinkLabelLinkClickedEventArgs e)
        {
            FormShowMeteostationsMap fsmon = new FormShowMeteostationsMap(true);

            if (fsmon.ShowDialog(this) == DialogResult.OK)
            {
                this.selectedMeteostation = fsmon.Result;

                //установка времени начала и конца наблюдений
                dateTimePickerFromDate.MinDate = selectedMeteostation.MonitoringFrom;
                dateTimePickerToDate.MaxDate   = DateTime.Now;
                labelDateRange.Text            = "Выберите диапазон дат: (дата начала наблюдений: " + selectedMeteostation.MonitoringFrom.ToString() + ")";

                //разблокировка элементов
                dateTimePickerFromDate.Enabled = true;
                dateTimePickerToDate.Enabled   = true;
                buttonDownload.Enabled         = true;
                linkLabelOpenNasa.Enabled      = true;

                comboBoxPoint.Items.Clear();
                comboBoxPoint.Items.Add(selectedMeteostation);
                comboBoxPoint.SelectedItem = selectedMeteostation;

                //запись координат
                labelCoordinates.Text = $"Координаты метеостанции: {selectedMeteostation.Position.ToString(4)}";
            }
        }
Пример #5
0
        /// <summary>
        /// кнопка выбора точки на карте
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonSelectPoint_Click(object sender, EventArgs e)
        {
            FormSelectMapPointDialog spt = new FormSelectMapPointDialog("Выберите точку на карте", point, Vars.Options.CacheFolder, Resources.rp5_marker, Vars.Options.MapProvider);

            if (spt.ShowDialog(this) == DialogResult.OK)
            {
                point                      = spt.Result;
                spoint                     = new RP5MeteostationInfo();
                spoint.Position            = point;
                labelPointCoordinates.Text = $"Широта: {point.Lat:0.000} Долгота: {point.Lng:0.000}";

                loadAddressAsync(point);

                buttonDownload.Enabled         = true;
                dateTimePickerFromDate.Enabled = true;
                dateTimePickerToDate.Enabled   = true;
            }
        }
Пример #6
0
        /// <summary>
        /// загрузка ряда из локальной БД
        /// </summary>
        /// <param name="fromDate">начальная дата</param>
        /// <param name="toDate">конечная дата</param>
        /// <param name="point_info">информация о МС</param>
        /// <param name="onPercentChange">не используется</param>
        /// <param name="checkStop">не используется</param>
        /// <returns></returns>
        public RawRange GetRange(DateTime fromDate, DateTime toDate, RP5MeteostationInfo point_info, Action <double> onPercentChange = null, Func <bool> checkStop = null)
        {
            //проверка параметров
            if (toDate < fromDate)
            {
                throw new WindEnergyException("Даты указаны неверно");
            }
            if (string.IsNullOrWhiteSpace(point_info.ID))
            {
                throw new ArgumentException("Поле ID не заполнено", nameof(point_info));
            }
            if (!Directory.Exists(folder))
            {
                throw new IOException("Папка БД Расписание Погоды не существует:\r\n" + folder);
            }
            string filename = folder + "\\" + PREFIX + point_info.ID + ".xlsx";

            if (!File.Exists(filename))
            {
                throw new FileNotFoundException("Файл не найден: " + filename);
            }

            //загрузка файла
            RawRange range = new ExcelFile().LoadRange(filename);

            if (range.First().Date > fromDate)
            {
                throw new WindEnergyException($"Начальной даты нет в локальной БД (доступны данные с {range.First().Date})");
            }
            if (toDate > range.Last().Date)
            {
                throw new WindEnergyException($"Конечной даты нет в локальной БД (доступны данные до {range.Last().Date})");
            }
            var res = range.Where(new Func <RawItem, bool>((item) => { return((item.Date >= fromDate) && (item.Date <= toDate)); }));

            RawRange result = new RawRange(res);

            if (result.Meteostation == null)
            {
                result.Meteostation = point_info;
            }
            result.Height = 10; //наблюдения в РП5 всегда на высоте 10м
            return(result);
        }
Пример #7
0
        /// <summary>
        /// фильтрация по началу города
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBoxPoint_TextUpdate(object sender, EventArgs e)
        {
            buttonDownload.Enabled         = false;
            selectedMeteostation           = null;
            dateTimePickerFromDate.Enabled = false;
            dateTimePickerToDate.Enabled   = false;
            string curTextBox = comboBoxPoint.Text.Trim();

            switch (Vars.Options.RP5SearchEngine)
            {
            case RP5SearchEngine.DBSearch:
                List <RP5MeteostationInfo> results = Vars.RP5Meteostations.Search(curTextBox);
                comboBoxPoint.Items.Clear();
                comboBoxPoint.Items.AddRange(results.ToArray());
                comboBoxPoint.SelectionStart = comboBoxPoint.Text.Length;
                break;

            case RP5SearchEngine.OnlineAPI:
                updateWMOListAsync(curTextBox);
                break;
            }
        }
Пример #8
0
        /// <summary>
        /// загрузка ряда из формата WindEnergy
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        private RawRange loadCSVFile(string filename)
        {
            StreamReader sr          = new StreamReader(filename, Encoding.UTF8);
            string       title       = sr.ReadLine();
            string       coordinates = sr.ReadLine();
            string       name        = sr.ReadLine();

            sr.ReadLine();//пропуск заголовка таблицы
            string data = sr.ReadToEnd();

            sr.Close();
            RawRange res = new RawRange()
            {
                Name = name
            };

            //чтение координат файла
            string      regex   = @"^\d+[\.\,].\d*\s+\d+[\.\,].\d*$";
            bool        isMatch = new Regex(regex).IsMatch(coordinates);
            PointLatLng coord;

            if (isMatch)
            {
                string[] s   = coordinates.Split(' ');
                double   lat = double.Parse(s[0].Trim().Replace('.', Constants.DecimalSeparator));
                double   lon = double.Parse(s[1].Trim().Replace('.', Constants.DecimalSeparator));
                coord = new PointLatLng(lat, lon);
            }
            else
            {
                coord = PointLatLng.Empty;
            }
            res.Position = coord;
            res.BeginChange();


            string[] lines = data.Split('\n');
            foreach (string line in lines)
            {
                string[] elems = line.Split(';');
                if (elems.Length < 6)
                {
                    continue;
                }
                if (elems[3] == "")
                {
                    continue;
                }
                if (elems[4] == "")
                {
                    continue;
                }

                double   temp  = elems[1] == "" ? double.NaN : double.Parse(elems[1].Replace('.', Constants.DecimalSeparator));
                DateTime dt    = DateTime.Parse(elems[0]);
                double   spd   = double.Parse(elems[4].Replace('.', Constants.DecimalSeparator));
                double   press = double.Parse(elems[5].Replace('.', Constants.DecimalSeparator));
                double   wet   = elems[2] == "" ? double.NaN : double.Parse(elems[2].Replace('.', Constants.DecimalSeparator));
                double   dirs  = double.Parse(elems[3].Replace('.', Constants.DecimalSeparator));
                try
                { res.Add(new RawItem()
                    {
                        Date = dt, Direction = dirs, Speed = spd, Temperature = temp, Wetness = wet, Pressure = press
                    }); }
                catch (Exception)
                { continue; }
            }

            //поиск информации о МС
            RP5MeteostationInfo meteostation = null;
            int    start = title.IndexOf("ID=") + "ID=".Length;
            string id_s  = title.Substring(start);

            meteostation     = Vars.RP5Meteostations.GetByID(id_s);
            res.Meteostation = meteostation;


            res.EndChange();
            return(res);
        }
Пример #9
0
 /// <summary>
 /// открытие формы с уже выбранной МС
 /// </summary>
 public FormLoadFromRP5(RP5MeteostationInfo meteostaion) : this()
 {
     selectedMeteostation = meteostaion;
 }
Пример #10
0
        /// <summary>
        /// проверка после выбора метеостанции
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void comboBoxPoint_SelectionChangeCommitted(object sender, EventArgs e)
        {
            //после того, как из поиска выбрана точка, надо проверить, есть ли на ней архив погоды. и вывести предупреждение, если ближайший архив далеко

            try
            {
                if (comboBoxPoint.SelectedItem == null)
                {
                    return;
                }

                //выбор метеостанции
                if (comboBoxPoint.SelectedItem.GetType() == typeof(RP5ru.WmoInfo))
                {
                    List <RP5MeteostationInfo> meteost = engine.GetMeteostationsAtPoint(comboBoxPoint.SelectedItem as RP5ru.WmoInfo);
                    RP5MeteostationInfo        meteostation;
                    if (meteost.Count == 0)
                    {
                        return;
                    }
                    if (meteost.Count == 1)
                    {
                        meteostation = meteost[0];
                    }
                    else
                    {
                        string text = "Ближайшие метеостанции к выбранной точке:\r\n\r\n";
                        text += meteost[0].Name + ", (" + meteost[0].OwnerDistance + " км)\r\n\r\n";
                        text += meteost[1].Name + ", (" + meteost[1].OwnerDistance + " км)\r\n\r\n";
                        FormChooseMeteostAirportDialog dlg = new FormChooseMeteostAirportDialog("Загрузка ряда с rp5.ru", text, meteost[0].Name, meteost[1].Name);
                        if (dlg.ShowDialog(this) == DialogResult.OK)
                        {
                            meteostation = meteost[dlg.Result - 1];
                        }
                        else
                        {
                            return;
                        }
                    }
                    this.selectedMeteostation = meteostation;
                }
                else
                {
                    this.selectedMeteostation = comboBoxPoint.SelectedItem as RP5MeteostationInfo;
                }

                //установка времени начала и конца наблюдений
                dateTimePickerFromDate.MinDate = selectedMeteostation.MonitoringFrom;
                dateTimePickerToDate.MaxDate   = DateTime.Now;
                labelDateRange.Text            = "Выберите диапазон дат: (дата начала наблюдений: " + selectedMeteostation.MonitoringFrom.ToString() + ")";

                //разблокировка элементов
                dateTimePickerFromDate.Enabled = true;
                dateTimePickerToDate.Enabled   = true;
                buttonDownload.Enabled         = true;
                linkLabelOpenNasa.Enabled      = true;

                //запись координат
                labelCoordinates.Text = $"Координаты метеостанции: {selectedMeteostation.Position.ToString(4)}";
            }
            catch (WebException)
            {
                _ = MessageBox.Show(this, "Ошибка подключения, проверьте соединение с Интернет", "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
        }
Пример #11
0
        /// <summary>
        /// асинхронная загрузка списка адресов метеостанций
        /// </summary>
        /// <param name="query">запрос</param>
        private async void updateWMOListAsync(string query)
        {
            if (query.Length < 2)
            {
                return;
            }

            //действие обновления списка подсказок
            Action <List <RP5ru.WmoInfo> > updList = new Action <List <RP5ru.WmoInfo> >((list) =>
            {
                comboBoxPoint.Items.Clear();
                comboBoxPoint.Items.AddRange(list.ToArray());
                comboBoxPoint.SelectionStart = comboBoxPoint.Text.Length;
            });

            try
            {
                List <RP5ru.WmoInfo> results;
                await Task.Run(() =>
                {
                    Thread.Sleep(1000); //ждем 1 с

                    //получаем новый текст
                    string curTextBox = "";
                    if (InvokeRequired)
                    {
                        _ = Invoke(new Action(() => { curTextBox = comboBoxPoint.Text.Trim(); }));
                    }
                    else
                    {
                        curTextBox = comboBoxPoint.Text.Trim();
                    }

                    if (query != curTextBox) //если этот текст  изменился, то выходим
                    {
                        return;
                    }

                    selectedMeteostation = null;
                    results = engine.Search(query);
                    //обновление списка
                    if (InvokeRequired)
                    {
                        _ = Invoke(updList, results);
                    }
                    else
                    {
                        updList.Invoke(results);
                    }
                }).ConfigureAwait(false);
            }
            catch (WebException)
            {
                _ = MessageBox.Show(this, "Ошибка подключения, проверьте соединение с Интернет", "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            catch (ApplicationException exc)
            {
                _ = MessageBox.Show(this, exc.Message, "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }
            Debug.WriteLine("updateList end");
        }
Пример #12
0
        /// <summary>
        /// получить ряд данных за указанный промежуток в заданной точке
        /// </summary>
        /// <param name="fromDate"></param>
        /// <param name="toDate"></param>
        /// <param name="point_info"></param>
        /// <param name="onPercentChange">Метод, вызываемый при изменении процента выполнения</param>
        /// <param name="checkStop"></param>
        /// <returns></returns>
        public RawRange GetRange(DateTime fromDate, DateTime toDate, RP5MeteostationInfo point_info, Action <double> onPercentChange = null, Func <bool> checkStop = null)
        {
            PointLatLng coord = point_info.Position;

            string fields = "";

            foreach (string param in parameters.Values)
            {
                fields += param + ",";
            }
            fields = fields.Trim(',');

            //https://power.larc.nasa.gov/api/temporal/hourly/point?start=20200901&end=20210901&latitude=55&longitude=37&community=sb&parameters=WD10M&format=csv&user=anonimous&header=true&time-standard=lst
            string url = "https://power.larc.nasa.gov/api/temporal/hourly/point?start={1}&end={2}&latitude={3}&longitude={4}&community=sb&parameters={0}&format=csv&user=anonimous&header=true&time-standard=lst";

            url = string.Format(url,
                                fields,
                                fromDate.ToString("yyyyMMdd"),
                                toDate.ToString("yyyyMMdd"),
                                coord.Lat.ToString("00.00").Replace(Constants.DecimalSeparator, '.'),
                                coord.Lng.ToString("00.00").Replace(Constants.DecimalSeparator, '.'));

            string data = SendStringGetRequest(url, out HttpStatusCode code, false);

            if (checkStop != null && checkStop.Invoke()) //проверка остановки процесса
            {
                return(null);
            }

            if (code != HttpStatusCode.OK) //если есть ошибки, то выход с ошибкой
            {
                throw new ApplicationException("Произошла ошибка при запросе");
            }

            RawRange res = new RawRange();

            if (checkStop != null && checkStop.Invoke()) //проверка остановки процесса
            {
                return(null);
            }

            string dlines = data.Substring(data.IndexOf("-END HEADER-") + "-END HEADER-".Length);

            string[]      lines  = dlines.Split('\n');
            List <string> header = new List <string>(lines[1].Split(','));

            for (int i = 2; i < lines.Length - 1; i++)
            {
                string line = lines[i].Replace("\r", "");
                line = Regex.Replace(line, @"[ ]+", " ");
                string[] elems = line.Trim().Split(',');

                if (header.Count != elems.Length)
                {
                    continue;
                }

                try
                {
                    Dictionary <MeteorologyParameters, double> values = new Dictionary <MeteorologyParameters, double>();
                    DateTime dt = DateTime.Parse(elems[0] + "." + elems[1] + "." + elems[2] + " " + elems[3] + ":00");
                    foreach (MeteorologyParameters key in parameters.Keys)
                    {
                        int    index = header.IndexOf(parameters[key]);
                        double val   = double.Parse(elems[index].Replace('.', Constants.DecimalSeparator));
                        if (key == MeteorologyParameters.Pressure)
                        {
                            val *= Constants.MMHGART_IN_1KPA; //переводим в мм рт. ст.
                        }
                        values.Add(key, val);
                    }
                    RawItem item = new RawItem(dt, values);
                    res.Add(item);
                }
                catch (ArgumentException)
                { continue; }
            }
            res.Position = point_info.Position;

            switch (speedHeight)
            {
            case NasaWindSpeedHeight.WS10M:
                res.Height = 10;
                break;

            case NasaWindSpeedHeight.WS50M:
                res.Height = 50;
                break;

            default: throw new Exception("Этот тип скорости не реализован");
            }

            return(res);
        }
Пример #13
0
        /// <summary>
        /// найти ближайшие метеостанции к выбранной точке прогноза погоды
        /// </summary>
        /// <param name="wmoInfo">информация о точке с погодой</param>
        /// <param name="loadExtInfo">загружать доп информацию о метеостанции (id, дата начала наблюдения)</param>
        /// <param name="forceDisableCache">откюлчение кэша</param>
        /// <returns></returns>
        public List <RP5MeteostationInfo> GetMeteostationsAtPoint(WmoInfo wmoInfo, bool loadExtInfo = true, bool forceDisableCache = false)
        {
            //страница погоды в заданной точке
            HtmlDocument point_page = SendHtmlGetRequest(wmoInfo.Link, out HttpStatusCode code, forceDisableCache: forceDisableCache);

            if (code != HttpStatusCode.OK)
            {
                throw new Exception("При загрузке страницы произошла ошибка " + code.ToString());
            }

            //поиск ссылок на метеостанции
            Dictionary <string, IEnumerable <HtmlNode> > archives = new Dictionary <string, IEnumerable <HtmlNode> >();
            List <RP5MeteostationInfo>  res       = new List <RP5MeteostationInfo>();
            Dictionary <string, string> selectors = new Dictionary <string, string>()
            {
                { "a[id='archive_link']", "list" },              //архив погоды на метеостанции (старый вариант страницы)
                { "div.ArchiveInfo a.ArchiveStrLink", "block" }, //архив погоды на метеостанции (новый вариант страницы)
                { "a[id='wug_link']", "list" },                  //на неофициальной метеостанции (этот архив пока что качать нельзя, но селектор оставим)
                { "a[id='metar_link']", "list" } //аэропорт
            };

            foreach (string i in selectors.Keys)
            {
                var a = point_page.DocumentNode.QuerySelectorAll(i); //получаем все теги по такому селекторы
                if (a != null && a.Count() > 0)                      //если что-то нашлось, то парсим дальше
                {
                    foreach (HtmlNode some_link in a)
                    {
                        RP5MeteostationInfo nm = new RP5MeteostationInfo();
                        nm.Name = wmoInfo.name;                       //искомая точка
                        nm.Link = some_link.Attributes["href"].Value; //ссылка на страницу

                        //дальнейшее зависит от типа блока
                        switch (selectors[i])
                        {
                        case "list":     //СТАРЫЕ ВАРИАНТЫ БЛОКОВ ССЫЛОК НА МЕТЕОСТАНЦИИ И АЭРОПОРТЫ
                            //название
                            int    s1          = some_link.InnerText.IndexOf(" (");
                            string onmouseover = some_link.Attributes["onmouseover"].Value;     //значение атрибута вывода подсказки
                            string nmm         = onmouseover.Replace("tooltip(this, '", "").Replace("' , 'hint')", "");
                            nm.Name = some_link.InnerText.Substring(0, s1) + " (" + nmm + ")";

                            //расстояние до точки
                            string content = some_link.InnerText;
                            int    start   = content.IndexOf("( ");
                            int    end     = content.IndexOf(" км");
                            if (start == -1 || end == -1)
                            {
                                nm.OwnerDistance = 0;
                            }
                            else
                            {
                                int    l    = end - (start + 2);
                                string dist = content.Substring(start + 2, l);
                                nm.OwnerDistance = double.Parse(dist.Replace('.', Constants.DecimalSeparator));
                            }

                            //тип источника
                            string a_id = some_link.Attributes["id"].Value;
                            switch (a_id)
                            {
                            case "archive_link":
                                nm.MeteoSourceType = MeteoSourceType.Meteostation;
                                break;

                            case "metar_link":
                                nm.MeteoSourceType = MeteoSourceType.Airport;
                                break;

                            case "wug_link":
                                continue;         //для неофициальных метеостанций нельзя получить архив погоды =(

                            //nm.MeteoSourceType = MeteoSourceType.UnofficialMeteostation;
                            //break;
                            default: throw new Exception("Этот тип метеостанции не реализован");
                            }
                            break;


                        case "block":                                                //НОВЫЙ ТИП ССЫЛОК В ВИДЕ БЛОКА С ИНФОРМАЦИЕЙ
                            //название
                            onmouseover = some_link.Attributes["onmouseover"].Value; //значение атрибута вывода подсказки
                            nmm         = onmouseover.Replace("tooltip(this, '", "").Replace("' , 'hint')", "");
                            nm.Name     = nmm;

                            //расстояние до источника не указывается, значит 0
                            nm.OwnerDistance = 0;

                            //пока в таких блоках только метеостанции
                            nm.MeteoSourceType = MeteoSourceType.Meteostation;

                            break;

                        default: throw new Exception("Этот тип блока ещё не реализован");
                        }



                        if (loadExtInfo)
                        {
                            try
                            {
                                GetMeteostationExtInfo(ref nm); //запись информации об id метеостанции, дате начала наблюдений
                            }
                            catch (Exception) { continue; }
                        }
                        if (nm != null)
                        {
                            res.Add(nm);
                        }
                    }
                }
            }
            return(res);
        }
Пример #14
0
        /// <summary>
        /// ищет наиболее подходящую к заданной точке МС и получает её ряд. Если ряд не найден, то возвращает null
        /// </summary>
        /// <param name="coordinates"></param>
        /// <param name="r"></param>
        /// <param name="actionPercent"></param>
        /// <param name="Range">ряд, для которого подбирается функция</param>
        /// <exception cref="GetBaseRangeException">Возвращает иснформацию о параметрах, мешающих получить ближайшую МС</exception>
        /// <returns></returns>
        internal static RawRange TryGetBaseRange(RawRange Range, PointLatLng coordinates, out double r, Action <int, string> actionPercent)
        {
            bool nlaw = CheckNormalLaw(Range, Vars.Options.NormalLawPirsonCoefficientDiapason);

            if (!nlaw)
            {
                throw new WindEnergyException("Исходный ряд не подчиняется нормальному закону распределения");
            }

            DateTime from = Range.Min((ri) => ri.Date).Date, to = Range.Max((ri) => ri.Date).Date;

            List <RP5MeteostationInfo>  mts = Vars.RP5Meteostations.GetNearestMS(coordinates, Vars.Options.NearestMSRadius, false);
            Dictionary <double, double> funcSpeed = Range.GetFunction(MeteorologyParameters.Speed); //функция скорости на заданном ряде
            RawRange res = null;
            double   rmax = double.MinValue, total_rmax = double.MinValue;
            RP5ru    provider = new RP5ru(Vars.Options.CacheFolder + "\\rp5.ru");

            for (int i = 0; i < mts.Count; i++)
            {
                if (actionPercent != null)
                {
                    actionPercent.Invoke((int)((i * 1d / mts.Count) * 100d), "Поиск подходящей МС...");
                }

                RP5MeteostationInfo m = mts[i];

                //если нет диапазона измерений в БД, то загружаем с сайта
                if (m.MonitoringFrom == DateTime.MinValue)
                {
                    provider.GetMeteostationExtInfo(ref m);
                }

                //если для этой МС нет наблюдений в этом периоде, то переходим на другую
                if (m.MonitoringFrom > from)
                {
                    continue;
                }

                //загрузка ряда с очередной МС
                RawRange curRange = null;
                try
                { curRange = provider.GetRange(from, to, m); }
                catch (WindEnergyException wex) // если не удалось получить ряд этой МС, то переходим к следующей
                { continue; }


                curRange = new Checker().ProcessRange(curRange, new CheckerParameters(LimitsProviders.StaticLimits, curRange.Position), out CheckerInfo info, null); //исправляем ошибки


                //СКОРОСТЬ
                MeteorologyParameters parameter = MeteorologyParameters.Speed;

                Dictionary <double, double> funcSpeedCurrentNearest = curRange.GetFunction(parameter); //функция скорости на текущей МС

                //проверка на нормальный закон распределения
                bool normal = CheckNormalLaw(curRange, Vars.Options.NormalLawPirsonCoefficientDiapason);
                if (!normal)
                {
                    continue;
                }

                //расчёт и проверка коэфф корреляции
                List <double>[] table     = calcTableCoeff(funcSpeed, funcSpeedCurrentNearest); //таблица для расчет коэффициентов
                double          current_r = getParameterR(table);                               //коэффициент корреляции

                //общий максимальный коэфф корреляции
                if (current_r > total_rmax)
                {
                    total_rmax = current_r;
                }

                //проверяем, можно ли взять эту МС
                if (current_r > rmax)
                {
                    //истина, если надо проверять этот параметр на допустимый диапазон корреляции
                    bool needCheck = Vars.Options.MinimalCorrelationControlParametres.Contains(parameter);
                    if ((needCheck && current_r >= Vars.Options.MinimalCorrelationCoeff) || !needCheck)
                    {
                        rmax = current_r;
                        res  = curRange;
                    }
                }
            }
            r = rmax;
            if (res == null)
            {
                RP5MeteostationInfo mi = Vars.RP5Meteostations.GetNearestMS(coordinates);
                double l = EarthModel.CalculateDistance(mi.Position, coordinates);
                throw new GetBaseRangeException(total_rmax, Vars.Options.MinimalCorrelationCoeff, l, mts.Count, Vars.Options.NearestMSRadius, coordinates);
            }
            return(res);
        }
 /// <summary>
 /// создание окна с выделенной метеостанцией на карте
 /// </summary>
 /// <param name="meteostation"></param>
 public FormShowMeteostationsMap(RP5MeteostationInfo meteostation) : this()
 {
     meteostation            = meteostation ?? throw new ArgumentNullException(nameof(meteostation));
     gmapControlMap.Position = meteostation.Position;
 }
        /// <summary>
        /// выводит на карту только видимые метеостанции
        /// </summary>
        private void showVisibleMeteostations()
        {
            //загрузка списка метеостанций
            if (lay != null)
            {
                //расчет областей экрана
                int    h  = 15;                                //кол-во по высоте
                int    w  = 15;                                //кол-во по ширине
                double hd = gmapControlMap.ViewArea.HeightLat; //высота в градусах
                double wd = gmapControlMap.ViewArea.WidthLng;  //ширина в градусах
                double sh = hd / h;                            // шаг по высоте
                double sw = wd / w;                            //шаг по ширине

                RP5MeteostationInfo[][] mts_map = new RP5MeteostationInfo[h][];
                for (int i = 0; i < h; i++)
                {
                    mts_map[i] = new RP5MeteostationInfo[w];
                }

                RectLatLng[][] rec_map = new RectLatLng[h][];
                for (int i = 0; i < h; i++)
                {
                    rec_map[i] = new RectLatLng[w];
                }

                for (int i = 0; i < h; i++)
                {
                    for (int j = 0; j < w; j++)
                    {
                        //левый верхний угол
                        double lat = gmapControlMap.ViewArea.Lat - (i) * sh;
                        double lng = gmapControlMap.ViewArea.Lng + (j) * sw;
                        rec_map[i][j] = new RectLatLng(lat, lng, sw, sh);
                    }
                }

                //выборка точек из БД
                List <RP5MeteostationInfo> pts = new List <RP5MeteostationInfo>();
                foreach (var mts in Vars.RP5Meteostations.List)
                {
                    if (gmapControlMap.ViewArea.Contains(mts.Position))
                    {
                        pts.Add(mts); //добавление в общий список

                        //поиск по всем областям
                        bool exit = false;
                        for (int i = 0; i < h && !exit; i++)
                        {
                            for (int j = 0; j < w; j++)
                            {
                                // если попадает в маленькую область и эта область ещё не заполнена
                                if (rec_map[i][j].Contains(mts.Position) && mts_map[i][j] == null)
                                {//добавляем на карту и выходим
                                    mts_map[i][j] = mts;
                                    exit          = true;
                                    break;
                                }
                            }
                        }
                    }
                }

                List <RP5MeteostationInfo> res;
                if (pts.Count < h * w)
                {
                    res = pts;
                }
                else
                {
                    res = new List <RP5MeteostationInfo>();
                    for (int i = 0; i < mts_map.Length; i++)
                    {
                        if (mts_map[i] != null)
                        {
                            foreach (var dd in mts_map[i])
                            {
                                if (dd != null)
                                {
                                    res.Add(dd);
                                }
                            }
                        }
                    }
                }

                //вывод на карту
                lay.Clear();
                showVisibleAMS();//вывод АМС без фильтрации, их мало
                foreach (var a in res)
                {
                    showMarker(a.Position, a.Name, a);
                }
            }
        }
Пример #17
0
        /// <summary>
        /// Загрузить ряд из файла csv, полученного с сайта
        /// </summary>
        /// <param name="file">файл csv</param>
        /// <param name="meteostation">Привязка к метеостанции. Если null, то будет найдена из БД по ID из заголовка</param>
        /// <returns></returns>
        public static RawRange LoadCSV(string file, RP5MeteostationInfo meteostation = null)
        {
            using (StreamReader sr = new StreamReader(file, Encoding.UTF8, true))
            {
                RawRange res = new RawRange();
                res.BeginChange(); //приостановка обработки событий изменения ряда

                //определение формата файла csv
                MeteoSourceType type;
                string          title = sr.ReadLine();
                if (title.Contains("WMO_ID"))
                {
                    type = MeteoSourceType.Meteostation;
                }
                else if (title.Contains("METAR"))
                {
                    type = MeteoSourceType.Airport;
                }
                else
                {
                    throw new Exception("Файл повреждён или имеет неизвестный формат данных rp5.ru");
                }

                //пропуск пустых строк (одна уже пропущена при чтении заголовка)
                for (int i = 0; i < 6; i++)
                {
                    sr.ReadLine();
                }
                switch (type)
                {
                case MeteoSourceType.Meteostation:     //загрузка архива с метеостанции

                    string data = sr.ReadToEnd();
                    sr.Close();
                    string[] lines = data.Replace("\"", "").Split('\n');
                    foreach (string line in lines)
                    {
                        string[] elems = line.Split(';');
                        if (elems.Length < 8)
                        {
                            continue;
                        }
                        if (elems[6] == "")
                        {
                            continue;
                        }
                        if (elems[7] == "")
                        {
                            continue;
                        }

                        double           temp   = elems[1] == "" ? double.NaN : double.Parse(elems[1].Replace('.', Constants.DecimalSeparator));
                        DateTime         dt     = DateTime.Parse(elems[0]);
                        double           spd    = double.Parse(elems[7].Replace('.', Constants.DecimalSeparator));
                        double           wet    = elems[5] == "" ? double.NaN : double.Parse(elems[5].Replace('.', Constants.DecimalSeparator));
                        double           press  = elems[2] == "" ? double.NaN : double.Parse(elems[2].Replace('.', Constants.DecimalSeparator));
                        string           dirs   = elems[6];
                        WindDirections16 direct = GetWindDirectionFromString(dirs);
                        try
                        { res.Add(new RawItem()
                            {
                                Date = dt, DirectionRhumb = direct, Speed = spd, Temperature = temp, Wetness = wet, Pressure = press
                            }); }
                        catch (Exception)
                        { continue; }
                    }

                    //поиск информации о МС
                    if (meteostation == null)
                    {
                        int    start = title.IndexOf("WMO_ID=") + "WMO_ID=".Length;
                        int    end   = title.IndexOf(',', start);
                        string id_s  = title.Substring(start, end - start);
                        meteostation = Vars.RP5Meteostations.GetByID(id_s);
                    }
                    break;

                case MeteoSourceType.Airport:     //загрузка архива с аэропорта

                    string data2 = sr.ReadToEnd();
                    sr.Close();
                    string[] lines2 = data2.Replace("\"", "").Split('\n');
                    foreach (string line in lines2)
                    {
                        string[] elems = line.Split(';');
                        if (elems.Length < 8)
                        {
                            continue;
                        }
                        if (elems[5] == "")
                        {
                            continue;
                        }
                        if (elems[6] == "")
                        {
                            continue;
                        }

                        double           temp   = elems[1] == "" ? double.NaN : double.Parse(elems[1].Replace('.', Constants.DecimalSeparator));
                        DateTime         dt     = DateTime.Parse(elems[0]);
                        double           spd    = double.Parse(elems[6].Replace('.', Constants.DecimalSeparator));
                        double           wet    = elems[4] == "" ? double.NaN : double.Parse(elems[4].Replace('.', Constants.DecimalSeparator));
                        double           press  = elems[2] == "" ? double.NaN : double.Parse(elems[2].Replace('.', Constants.DecimalSeparator));
                        string           dirs   = elems[5];
                        WindDirections16 direct = RP5ru.GetWindDirectionFromString(dirs);
                        res.Add(new RawItem()
                        {
                            Date = dt, DirectionRhumb = direct, Speed = spd, Temperature = temp, Wetness = wet, Pressure = press
                        });
                    }
                    //поиск информации о МС
                    if (meteostation == null)
                    {
                        int    start = title.IndexOf("METAR=") + "METAR=".Length;
                        int    end   = title.IndexOf(',', start);
                        string id_s  = title.Substring(start, end - start);
                        meteostation = Vars.RP5Meteostations.GetByCC_code(id_s);
                    }
                    break;

                case MeteoSourceType.UnofficialMeteostation:
                    throw new Exception("Этот тип файла не поддерживается");
                }

                res.Meteostation = meteostation;
                res.EndChange();
                return(res);
            }
        }
Пример #18
0
        /// <summary>
        /// получить из страницы архива погоды id метеостанции, дату начала наблюдений. Двнные запишутся в структуру info, где уже должна быть записана ссылка на страницу
        /// </summary>
        /// <returns></returns>
        public void GetMeteostationExtInfo(ref RP5MeteostationInfo info)
        {
            if (info == null)
            {
                throw new ArgumentException("info");
            }
            if (string.IsNullOrWhiteSpace(info.Link))
            {
                throw new ArgumentException("В структуре info должна быть ссылка на страницу архива погоды");
            }

            HtmlDocument page = SendHtmlGetRequest(info.Link, out HttpStatusCode code);


            HtmlNode wmo   = page.GetElementbyId("wmo_id"); //архив погоды на метеостанции
            HtmlNode metar = page.GetElementbyId("cc_str"); //аэропорт
            HtmlNode wug   = page.GetElementbyId("wug");    //на неофициальной метеостанции

            //получение ID
            if (wmo != null) //метеостанция
            {
                info.ID = wmo.Attributes["value"].Value;
                info.MeteoSourceType = MeteoSourceType.Meteostation;
            }
            else if (metar != null) //аэропорт
            {
                //символьный код аэропорта
                HtmlNode cc_code_node = page.GetElementbyId("cc_str");
                string   cc_code      = cc_code_node.Attributes["value"].Value.ToString();
                info.CC_Code = cc_code;

                //id в системе рп5
                string pg1    = page.Text;
                int    start1 = pg1.IndexOf("fFileMetarGet(");
                int    end1   = pg1.IndexOf(')', start1);
                if (start1 == -1 || end1 == -1)
                {
                    throw new Exception("Что-то не так");
                }
                start1 += +"fFileMetarGet(1317900300".Length;
                string id = pg1.Substring(start1 + 1, end1 - 1 - start1);
                info.ID = id;
                info.MeteoSourceType = MeteoSourceType.Airport;
            }
            else if (wug != null) //неофициальная метеостанция
            {
                info = null;
                return;
            }
            else
            {
                throw new WindEnergyException("Для этой метеостанции невозможно получить данные");
            }


            //получение даты начала наблюдений
            string pg    = page.Text;
            int    start = pg.IndexOf("наблюдения с ");
            int    end   = pg.IndexOf("</span>", start);

            if (start == -1 || end == -1)
            {
                throw new Exception("Что-то не так");
            }
            start += "наблюдения с ".Length;
            string   fdate    = pg.Substring(start, end - 1 - start);
            DateTime mon_from = DateTime.Parse(fdate);

            info.MonitoringFrom = mon_from;

            //получение координат метеостанции
            string pg2    = page.Text;
            int    start2 = pg2.IndexOf("show_map(");
            int    end2   = pg2.IndexOf(", 9);", start2);

            if (start2 == -1 || end2 == -1)
            {
                throw new Exception("Что-то не так");
            }
            start2 += "show_map(".Length;
            string coordinates = pg2.Substring(start2, end2 - 1 - start2);

            //55.833333333333, 37.616666666667
            string[] ar  = coordinates.Split(',');
            double   lat = double.Parse(ar[0].Trim().Replace('.', Constants.DecimalSeparator));
            double   lon = double.Parse(ar[1].Trim().Replace('.', Constants.DecimalSeparator));

            info.Position = new PointLatLng(lat, lon);
        }
Пример #19
0
        /// <summary>
        /// Загрузка ряда из файла xlsx
        /// </summary>
        /// <param name="fileName">адрес файла</param>
        /// <returns></returns>
        public override RawRange LoadRange(string fileName)
        {
            FileInfo fi = new FileInfo(fileName);

            using (ExcelPackage excelPackage = new ExcelPackage(fi))
            {
                if (excelPackage.Workbook.Worksheets.Count == 0)
                {
                    return(null);
                }

                ExcelWorksheet worksheet = excelPackage.Workbook.Worksheets[0];

                if (worksheet.Cells[3, 1].Value == null)
                {
                    return(null);
                }
                string title       = worksheet.Cells[1, 1].Value.ToString();
                string coordinates = worksheet.Cells[2, 1].Value.ToString();
                string name        = worksheet.Cells[3, 1].Value.ToString();
                string height      = worksheet.Cells[2, 2].Value != null ? worksheet.Cells[2, 2].Value.ToString() : "не число";
                if (!double.TryParse(height, out double rangeHeight))
                {
                    rangeHeight = double.NaN;
                }

                RawRange res = new RawRange()
                {
                    Name = name
                };

                //чтение координат файла
                string      regex   = @"^\d+[\.\,].\d*\s+\d+[\.\,].\d*$";
                bool        isMatch = new Regex(regex).IsMatch(coordinates);
                PointLatLng coord;
                if (isMatch)
                {
                    string[] s   = coordinates.Split(' ');
                    double   lat = double.Parse(s[0].Trim().Replace('.', Constants.DecimalSeparator));
                    double   lon = double.Parse(s[1].Trim().Replace('.', Constants.DecimalSeparator));
                    coord = new PointLatLng(lat, lon);
                }
                else
                {
                    coord = PointLatLng.Empty;
                }
                res.Position = coord;
                res.BeginChange();

                var arr = worksheet.Cells;
                for (int i = 5; i <= worksheet.Dimension.Rows; i++)
                {
                    DateTime dt    = getDateTime(arr[i, 1]);
                    double   temp  = getDouble(arr[i, 2]);
                    double   spd   = getDouble(arr[i, 5]);
                    double   press = getDouble(arr[i, 6]);
                    double   wet   = getDouble(arr[i, 3]);
                    double   dirs  = getDouble(arr[i, 4]);

                    try
                    { res.Add(new RawItem()
                        {
                            Date = dt, Direction = dirs, Speed = spd, Temperature = temp, Wetness = wet, Pressure = press
                        }); }
                    catch (Exception)
                    { continue; }
                }

                //поиск информации о МС
                RP5MeteostationInfo meteostation = null;
                int    start = title.IndexOf("ID=") + "ID=".Length;
                string id_s  = title.Substring(start);
                if (id_s.ToLower() != "nasa" && id_s.ToLower() != "undefined")
                {
                    meteostation = Vars.RP5Meteostations.GetByID(id_s);
                }

                res.Meteostation = meteostation;
                res.Height       = rangeHeight;
                res.EndChange();
                return(res);
            }
        }
Пример #20
0
        /// <summary>
        /// загрузить файл данных с сайта и открыть ряд наблюдений
        /// </summary>
        /// <param name="fromDate">с какой даты</param>
        /// <param name="toDate">до какой даты</param>
        /// <param name="info">Метеостанция, с которой загружается ряд</param>
        /// <param name="onPercentChange"></param>
        /// <param name="checkStop"></param>
        /// <returns></returns>
        public RawRange GetRange(DateTime fromDate, DateTime toDate, RP5MeteostationInfo info, Action <double> onPercentChange = null, Func <bool> checkStop = null)
        {
            if (toDate < fromDate)
            {
                throw new WindEnergyException("Даты указаны неверно");
            }

            switch (Vars.Options.RP5SourceEngine)
            {
            case RP5SourceType.LocalDBSearch:
                return(Vars.RP5Database.GetRange(fromDate, toDate, info, onPercentChange, checkStop));

            case RP5SourceType.OnlineAPI:
                if (toDate - fromDate > TimeSpan.FromDays(365 * LOAD_STEP_YEARS))     // если надо скачать больше трёх лет, то скачиваем по частям
                {
                    TimeSpan span = toDate - fromDate;

                    RawRange res1 = new RawRange();
                    DateTime dt;
                    int      i     = 0;
                    int      total = (int)(span.TotalDays / (365 * LOAD_STEP_YEARS)) + 1;
                    for (dt = fromDate; dt <= toDate; dt += TimeSpan.FromDays(365 * LOAD_STEP_YEARS))
                    {
                        if (checkStop != null)
                        {
                            if (checkStop.Invoke())
                            {
                                break;
                            }
                        }

                        if (onPercentChange != null)
                        {
                            double pc = ((i / (double)total) * 100d);
                            onPercentChange.Invoke(pc);
                        }
                        RawRange r = GetRange(dt, dt + TimeSpan.FromDays(365 * LOAD_STEP_YEARS), info, onPercentChange, checkStop);
                        res1.Add(r);
                        res1.Name         = r.Name;
                        res1.Position     = r.Position;
                        res1.Meteostation = r.Meteostation;
                        res1.Height       = 10; //высота всегда 10м
                        i++;
                    }
                    //DateTime fr = dt - TimeSpan.FromDays(365 * LOAD_STEP_YEARS);
                    //RawRange r1 = GetRange(fr, toDate, info);
                    return(res1);
                }

                #region отправка статистики загрузки

                string dataS, linkS;
                switch (info.MeteoSourceType)
                {
                case MeteoSourceType.Airport:
                    dataS = "cc_id={0}&cc_str={1}&stat_p=1&s_date1={2}&s_ed3={4}&s_ed4={4}&s_ed5={5}&s_date2={3}&s_ed9=0&s_ed10=-1&s_pe=1&lng_id=2&s_dtimehi=-Период---";
                    linkS = "https://rp5.ru/responses/reStatistMetar.php";
                    dataS = string.Format(dataS,
                                          info.ID,                              //cc_id
                                          info.CC_Code,                         //cc_str
                                          fromDate.Date.ToString("dd.MM.yyyy"), //from
                                          toDate.Date.ToString("dd.MM.yyyy"),   //to
                                          DateTime.Now.Month,                   //f_ed3 - только месяц
                                          DateTime.Now.Day                      //f_ed5 - только день
                                          );
                    break;

                case MeteoSourceType.Meteostation:
                    dataS = "wmo_id={0}&stat_p=1&s_date1={1}&s_ed3={3}&s_ed4={3}&s_ed5={4}&s_date2={2}&s_ed9=0&s_ed10=-1&s_pe=1&lng_id=2&s_dtimehi=-срок---";
                    linkS = "https://rp5.ru/responses/reStatistSynop.php";
                    dataS = string.Format(dataS,
                                          info.ID,                              //wmo_id
                                          fromDate.Date.ToString("dd.MM.yyyy"), //from
                                          toDate.Date.ToString("dd.MM.yyyy"),   //to
                                          DateTime.Now.Month,                   //f_ed3 - только месяц
                                          DateTime.Now.Day                      //f_ed5 - только день
                                          );
                    break;

                default: throw new Exception("Этот тип метеостанций не реализован");
                }
                string strS = this.SendStringPostRequest(linkS, dataS, referer: "https://rp5.ru/", cookies: this.CookieData, customHeaders: this.Headers);

                #endregion

                #region получение ссылки на файл
                string data, link;
                //получение ссылки на файл
                switch (info.MeteoSourceType)
                {
                case MeteoSourceType.Airport:
                    data = "metar={0}&a_date1={1}&a_date2={2}&f_ed3={3}&f_ed4={4}&f_ed5={5}&f_pe={6}&f_pe1={7}&lng_id=2";
                    link = "https://rp5.ru/responses/reFileMetar.php";
                    break;

                case MeteoSourceType.Meteostation:
                    data = "wmo_id={0}&a_date1={1}&a_date2={2}&f_ed3={3}&f_ed4={4}&f_ed5={5}&f_pe={6}&f_pe1={7}&lng_id=2";
                    link = "https://rp5.ru/responses/reFileSynop.php";
                    break;

                default: throw new Exception("Этот тип метеостанций не реализован");
                }

                data = string.Format(data,
                                     info.ID,                              //id
                                     fromDate.Date.ToString("dd.MM.yyyy"), //from
                                     toDate.Date.ToString("dd.MM.yyyy"),   //to
                                     DateTime.Now.Month,                   //f_ed3 - только месяц
                                     DateTime.Now.Month,                   //f_ed4 - только месяц
                                     DateTime.Now.Day,                     //f_ed5 - только день
                                     1,                                    //f_pe
                                     2                                     //f_pe1- кодировка (1 - ansi, 2 - utf8, 3 - Unicode)
                                     );

                string str = this.SendStringPostRequest(link, data, referer: "https://rp5.ru/", cookies: this.CookieData, customHeaders: this.Headers);


                //ОШИБКИ rp5.ru
                //запросы к reFileSynop.php
                //FS004 несуществующий wmo_id
                //FS002 ошибки в исходных данных (параметрах запроса)
                //FS000 Ошибка авторизации
                //FS001-
                //запросы к reStatistSynop.php
                //S000 Ошибка авторизации
                //FM000 Время жизни статистики истекло для этой сессии
                if (str.Contains("FS004"))
                {
                    throw new WindEnergyException("Для этого id нет архива погоды", ErrorReason.FS004);
                }
                if (str.Contains("FS002"))
                {
                    throw new WindEnergyException("Ошибка в исходных данных", ErrorReason.FS002);
                }
                if (str.Contains("FS000"))
                {
                    throw new WindEnergyException("Ошибка авторизации", ErrorReason.FS000);
                }
                if (str.Contains("FS001-"))
                {
                    throw new WindEnergyException("Неправильный метод запроса. Ожидается POST", ErrorReason.FS001);
                }
                if (str.Contains("FM000"))
                {
                    throw new WindEnergyException("Время жизни статистики истекло для этой сессии", ErrorReason.FM000);
                }
                if (str.Contains("FM004"))
                {
                    throw new WindEnergyException("Внутренняя ошибка. Архив недоступен или не существует", ErrorReason.FM004);
                }

                int start = str.IndexOf("href=") + 5;
                str = str.Substring(start);
                int    end = str.IndexOf(">");
                string lnk = str.Substring(0, end);
                lnk = lnk.Split(' ')[0] ?? "";

                bool checkLink = Uri.TryCreate(lnk, UriKind.Absolute, out Uri uriResult) && (uriResult.Scheme == Uri.UriSchemeHttp || uriResult.Scheme == Uri.UriSchemeHttps);
                if (!checkLink)
                {
                    throw new WindEnergyException("В парсере ответа rp5 произошла ошибка. Скорее всего, парсер устарел, обратитесь к разработчику");
                }

                #endregion

                #region  загрузка файла с сервера

                string    tmp_dl_file = Vars.LocalFileSystem.GetTempFileName();
                WebClient webcl       = new WebClient();
                webcl.DownloadFile(lnk, tmp_dl_file);
                webcl.Dispose();

                //распаковка
                string tmp_unpack_file = tmp_dl_file + ".csv";
                LocalFileSystem.UnGZip(tmp_dl_file, tmp_unpack_file);

                //открытие файла
                RawRange res = LoadCSV(tmp_unpack_file, info);

                res              = new RawRange(res.OrderBy(x => x.Date).ToList());
                res.Name         = info.Name;
                res.Position     = info.Position;
                res.Meteostation = info;
                res.Height       = 10;                                                  //высота всегда 10м
                new Task(() => Vars.RP5Meteostations.TryAddMeteostation(info)).Start(); //если такой метеостанции нет в БД, то добавляем
                return(res);

                #endregion

            default: throw new Exception("Этот тип БД не реализован");
            }
        }