Esempio n. 1
0
        /// <summary>
        /// приведение ряда к условиям плоской местности
        /// </summary>
        /// <param name="ms_range">ряд</param>
        /// <param name="expectancy">повторяемости направлений ветра</param>
        /// <param name="ms_classes">классы открытости МС</param>
        /// <param name="water_type">расстояние до водной поверхности</param>
        /// <returns></returns>
        public static RawRange ToFlatTerrain(RawRange ms_range, StatisticalRange <WindDirections8> expectancy, Dictionary <WindDirections8, double> ms_classes, WaterDistanceType water_type)
        {
            //1. найти Кмс
            //2. пересчитать ряд

            RawRange result = new RawRange();
            double   K0     = (int)water_type;

            //средневзвешенный коэффициент открытости метеостанции
            double Kms = 0;

            foreach (WindDirections8 dir in WindDirections8.N.GetEnumItems())
            {
                if (dir != WindDirections8.Calm && dir != WindDirections8.Undefined && dir != WindDirections8.Variable)
                {
                    Kms += expectancy[dir] * ms_classes[dir];
                }
            }

            double k0 = K0 / Kms;

            result.BeginChange();
            foreach (RawItem item in ms_range)
            {
                RawItem ni = item.Clone();
                ni.Speed = item.Speed * k0;
                result.Add(ni);
            }
            result.EndChange();
            return(result);
        }
Esempio n. 2
0
        /// <summary>
        /// поднять ряд на высоту с заданными настройками
        /// </summary>
        /// <param name="Range">поднимаемый ряд</param>
        /// <param name="param">настройки</param>
        /// <param name="actionPercent">действие при изменении процента выполнения</param>
        /// <param name="actionAfter">действие по окончании выполнения</param>
        public async static Task <RawRange> ProcessRange(RawRange Range, ElevatorParameters param, Action <int> actionPercent = null, Action <RawRange, SuitAMSResultItem> actionAfter = null)
        {
            //найти подходящую АМС
            //получить из неё параметры m по месяцам
            //поднять ряд Range на высоту


            //выбор варианта расчета m: через БД АМС или введенный вручную
            Dictionary <Months, double> coeffs = null;

            switch (param.HellmanCoefficientSource)
            {
            case HellmanCoefficientSource.AMSAnalog:
                coeffs = getAMSAnalogCoefficients(param.SelectedAMS.AMS, Range);
                break;

            case HellmanCoefficientSource.CustomMonths:
                coeffs = param.CustomMCoefficientMonths;
                break;

            case HellmanCoefficientSource.CustomOne:
                coeffs = new Dictionary <Months, double>();
                for (int i = 1; i <= 12; i++)
                {
                    coeffs.Add((Months)i, param.CustomMCoefficient);
                }
                break;

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

            coeffs = coeffs ?? throw new ArgumentException("Недопустимые настройки, коэффициенты пересчета на высоту не получены");

            //поднять ряд  с учетом m по месяцам
            RawRange res = new RawRange();

            res.Position = Range.Position;
            res.Height   = param.ToHeight;
            res.BeginChange();
            return(await Task.Run(() =>
            {
                double c = 0;
                foreach (RawItem item in Range)
                {
                    c++;
                    if (Math.IEEERemainder(c, 100) == 0 && actionPercent != null)
                    {
                        actionPercent.Invoke((int)((c / Range.Count) * 100));
                    }
                    Months month = (Months)item.Date.Month;
                    double m = coeffs[month];
                    double oldV = item.Speed;
                    double newV = oldV *Math.Pow(param.ToHeight / param.FromHeight, m);
                    RawItem ni = item.Clone();
                    ni.Speed = newV;
                    res.Add(ni);
                }
                res.EndChange();
                if (actionAfter != null)
                {
                    actionAfter.Invoke(res, param.SelectedAMS);
                }
                return res;
            }));
        }
Esempio n. 3
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);
            }
        }
Esempio n. 4
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);
        }
Esempio n. 5
0
        /// <summary>
        /// поднять ряд на высоту с заданными настройками
        /// </summary>
        /// <param name="Range">поднимаемый ряд</param>
        /// <param name="param">настройки</param>
        /// <param name="actionPercent">действие при изменении процента выполнения</param>
        /// <param name="actionAfter">действие по окончании выполнения</param>
        public static void ProcessRange(RawRange Range, TerrainParameters param, Action <int> actionPercent, Action <RawRange, FlugerMeteostationInfo> actionAfter)
        {
            RawRange result = new RawRange();

            result.Position = param.PointCoordinates;
            result.Name     = $"Ряд в точке {param.PointCoordinates.ToString(3)}";
            result.BeginChange();
            switch (param.TerrainType)
            {
            case TerrainType.Macro:
                Dictionary <WindDirections8, double> k0 = getTerrainMacroK0(param.MSClasses, param.PointClasses);    //получаем коэффициенты для плоского рельефа

                //пересчет всех скоростей ряда
                double c = 0;
                foreach (var item in Range)
                {
                    WindDirections8 wd8 = item.DirectionRhumb8;
                    if (wd8 == WindDirections8.Calm || wd8 == WindDirections8.Undefined || wd8 == WindDirections8.Variable)
                    {
                        continue;
                    }
                    double  nspeed = item.Speed * k0[wd8];    //для направления в этой точке пересчитываем скорости
                    RawItem nitem  = item.Clone();
                    nitem.Speed = nspeed;
                    result.Add(nitem);

                    c++;
                    if (Math.IEEERemainder(c, 100) == 0 && actionPercent != null)
                    {
                        actionPercent((int)((c / Range.Count) * 100));
                    }
                }
                break;

            case TerrainType.Meso:
                //мезоклиматический коэффициент
                double Km = (param.MesoclimateCoefficient.Value.From + param.MesoclimateCoefficient.Value.To) / 2d;     //среднее внутри диапазона

                //выбор преобладающих направлений ветра
                List <WindDirections8> dominants = GetRhumbsDominants(Range);

                //пересчет ряда только для преобладающих направлений
                foreach (RawItem item in Range)
                {
                    RawItem ni = item.Clone();
                    ni.Speed = dominants.Contains(ni.DirectionRhumb8) ? ni.Speed * Km : ni.Speed;
                    result.Add(ni);
                }
                break;

            case TerrainType.Micro:
                //выбор преобладающих направлений ветра
                List <WindDirections8> directs = GetRhumbsDominants(Range);

                //пересчет ряда только для преобладающих направлений
                foreach (RawItem item in Range)
                {
                    double  Kmk = selectMicroclimateCoefficient(item.Speed, param.MicroclimateCoefficient, param.AtmosphereStratification);
                    RawItem ni  = item.Clone();
                    ni.Speed = directs.Contains(ni.DirectionRhumb8) ? ni.Speed * Kmk : ni.Speed;
                    result.Add(ni);
                }
                break;

            default: throw new Exception("Этот тип рельефа не реализован");
            }
            result.Height = Range.Height;
            result.EndChange();
            actionAfter(result, param.FlugerMeteostation);
            return;
        }
Esempio n. 6
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);
        }
Esempio n. 7
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);
            }
        }