Example #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);
        }
Example #2
0
        /// <summary>
        /// загрузка файла CSV поддерживаемых форматов
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>
        public override RawRange LoadRange(string fileName)
        {
            StreamReader sr = new StreamReader(fileName, Encoding.UTF8, true);

            //определение формата файла csv
            string title = null, title2 = null, title3 = null;

            title = sr.ReadLine();
            if (!sr.EndOfStream)
            {
                title2 = sr.ReadLine();
            }
            if (!sr.EndOfStream)
            {
                title3 = sr.ReadLine();
            }
            sr.Close();

            if (title == null)
            {
                throw new WindEnergyException("Файл пуст!");
            }

            string regex = @"^\d+[\.\,].\d*\s+\d+[\.\,].\d*$";

            //этот файл - один из типов файлов rp5.ru (в заголовке есть тип источника, во второй строке указана кодировка, в третьей есть ссылка на источник)
            if ((title.Contains("WMO_ID") || title.Contains("METAR")) &&
                title2 != null && title2.Contains("UTF-8") &&
                title3 != null && title3.Contains("rp5.ru"))
            {
                return(RP5ru.LoadCSV(fileName));
            }

            //этот файл - просто файл CSV (в заголовке есть тип источника, во второй строке есть координаты точки)
            else if ((title.Contains("ID")) &&
                     title2 != null && new Regex(regex).IsMatch(title2))
            {
                return(loadCSVFile(fileName));
            }

            //этот файл другого формата
            else
            {
                throw new Exception("Файл повреждён или имеет неподдерживаемый формат");
            }
        }
Example #3
0
        /// <summary>
        /// Пытается импортировать файл на основе заданных настроек. При ошибке выбрасывает исключение WindEnergyException с информацией или ArgumentException при недопустимых настройках
        /// </summary>
        /// <returns></returns>
        /// <param name="count">количество считываемых строк, начиная со StartLine</param>
        public RawRange Import(long count = long.MaxValue)
        {
            CheckParameters(); //проверка параметров

            //Импорт данных
            string data = GetText(count);

            RawRange res = new RawRange();

            res.BeginChange();

            string[] lines  = data.Split('\r');
            int      line_i = 0;

            foreach (string line in lines)
            {
                line_i++;
                string[] arr = new Regex("w*" + Delimeter + "w*").Split(line.Replace("\n", ""));
                if (arr.Length <= 1)
                {
                    continue;
                }

                List <ImportFields> fields = this.Columns.Keys.ToList();
                RawItem             item   = new RawItem();
                foreach (ImportFields field in fields)
                {
                    int    index = Columns[field] - 1;
                    string value = arr[index];
                    if (Trimmers != null && Trimmers.Length > 0)
                    {
                        value = value.Trim(Trimmers);
                    }
                    try
                    {
                        switch (field)
                        {
                        case ImportFields.Date:
                            item.Date = DateTime.Parse(value);
                            break;

                        case ImportFields.Direction:
                            switch (DirectionUnit)
                            {
                            case DirectionUnits.Degrees:
                                item.Direction = double.Parse(value.Replace('.', Constants.DecimalSeparator));
                                break;

                            case DirectionUnits.TextRP5:
                                item.DirectionRhumb = RP5ru.GetWindDirectionFromString(value);
                                break;

                            case DirectionUnits.None:
                                throw new ArgumentException("Не заданы единицы измерения для направления");

                            default:
                                throw new WindEnergyException("Эта единица измерений не реализована");
                            }
                            break;

                        case ImportFields.Pressure:
                            switch (PressureUnit)
                            {
                            case PressureUnits.KPa:
                                item.Pressure = double.Parse(value.Replace('.', Constants.DecimalSeparator)) * Constants.MMHGART_IN_1KPA;         //перевод в мм рт. ст.
                                break;

                            case PressureUnits.mmHgArt:
                                item.Pressure = double.Parse(value.Replace('.', Constants.DecimalSeparator));
                                break;

                            case PressureUnits.None:
                                throw new ArgumentException("Не заданы единицы измерения для давления");

                            default:
                                throw new WindEnergyException("Эта единица измерений не реализована");
                            }
                            break;

                        case ImportFields.Wetness:
                            switch (WetnessUnit)
                            {
                            case WetnessUnits.Percents:
                                item.Wetness = double.Parse(value.Replace('.', Constants.DecimalSeparator));
                                break;

                            case WetnessUnits.Parts:
                                item.Wetness = double.Parse(value.Replace('.', Constants.DecimalSeparator)) * 100d;        //перевод в %
                                break;

                            case WetnessUnits.None:
                                throw new ArgumentException("Не заданы единицы измерения для влажности");

                            default:
                                throw new WindEnergyException("Эта единица измерений не реализована");
                            }
                            break;

                        case ImportFields.Temperature:
                            item.Temperature = double.Parse(value.Replace('.', Constants.DecimalSeparator));
                            break;

                        case ImportFields.Speed:
                            item.Speed = double.Parse(value.Replace('.', Constants.DecimalSeparator));
                            break;

                        default: throw new WindEnergyException("Этот параметр не реализован");
                        }
                    }
                    catch (Exception ex)
                    {
                        throw new WindEnergyException($"Не удалось распознать строку \"{value}\" как значение поля {field.Description()} в строке {line_i}", ex.Message);
                    }
                }
                res.Add(item);
            }

            if ((bool)BindNearestMS)
            {
                res.Meteostation = Vars.RP5Meteostations.GetNearestMS(this.Coordinates);
            }
            res.Position = this.Coordinates;
            res.Name     = Path.GetFileNameWithoutExtension(this.FilePath);
            res.EndChange();
            res.PerformRefreshQuality();
            return(res);
        }
Example #4
0
 public FormLoadFromRP5()
 {
     InitializeComponent();
     engine       = new RP5ru(Vars.Options.CacheFolder + "\\rp5.ru");
     DialogResult = DialogResult.None;
 }
Example #5
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);
        }