/// <summary> /// получить строку по направлению ветра /// </summary> /// <param name="direction"></param> /// <returns></returns> public static string GetStringFromWindDirection(WindDirections16 direction) { switch (direction) { case WindDirections16.N: return("ветер, дующий с севера"); case WindDirections16.NNE: return("ветер, дующий с северо-северо-востока"); case WindDirections16.NE: return("ветер, дующий с северо-востока"); case WindDirections16.NEE: return("ветер, дующий с востоко-северо-востока"); case WindDirections16.E: return("ветер, дующий с востока"); case WindDirections16.SEE: return("ветер, дующий с востоко-юго-востока"); case WindDirections16.SE: return("ветер, дующий с юго-востока"); case WindDirections16.SSE: return("ветер, дующий с юго-юго-востока"); case WindDirections16.S: return("ветер, дующий с юга"); case WindDirections16.SSW: return("ветер, дующий с юго-юго-запада"); case WindDirections16.SW: return("ветер, дующий с юго-запада"); case WindDirections16.SWW: return("ветер, дующий с западо-юго-запада"); case WindDirections16.W: return("ветер, дующий с запада"); case WindDirections16.NWW: return("ветер, дующий с западо-северо-запада"); case WindDirections16.NW: return("ветер, дующий с северо-запада"); case WindDirections16.NNW: return("ветер, дующий с северо-северо-запада"); case WindDirections16.Variable: return("переменное направление"); default: throw new Exception("Это направление ветра не реализовано"); } }
/// <summary> /// сохранить энергетические характеристики в файл csv /// </summary> /// <param name="fileName">имя файла</param> /// <param name="range_info">характеристики по ряду наблюдений</param> /// <param name="ext_info">характеристики по градациям</param> /// <param name="stat_directions">повторяемость направлений</param> /// <param name="stat_speeds">повторяемость скоростей</param> /// <param name="append">если истина, то файл будет дописан</param> /// <param name="caption">заголовок, который будет записан в начале</param> /// <param name="month">значение графы месяц</param> /// <param name="year">значение графы год</param> /// <param name="amount">количество измерений в ряде</param> private void saveEnergyInfoLine( string fileName, EnergyInfo range_info, EnergyInfo ext_info, StatisticalRange <WindDirections16> stat_directions, StatisticalRange <GradationItem> stat_speeds, string caption, string year, string month, int amount, bool append ) { StreamWriter sw = new StreamWriter(fileName, append, Encoding.UTF8); //запись заголовка if (!string.IsNullOrEmpty(caption)) { sw.WriteLine(caption); } if (range_info == null || ext_info == null || stat_directions == null || stat_speeds == null) { sw.Close(); return; } // "Год;Месяц;кол-во изм;0.75;2.5;4.5;6.5;8.5;10.5;12.5;14.5;16.5;19;22.5;26.5;31.5;37.5;43.5;Vmin;Vmax;Vср.год;Vэкст50,м/с;δ(P);Cv(V);Nвал уд.;Эвал уд.;С;СВ;В;ЮВ;Ю;ЮЗ;З;СЗ;штиль"; string line = $"{year};{month};{amount}"; //повторяемости скоростей ветра for (int j = 0; j < stat_speeds.Keys.Count; j++) { line += ";" + (stat_speeds.Values[j] * 100).ToString("0.00"); } //по ряду наблюдений line += string.Format(";{0:f2};{1:f2};{2:f2};{3:f2};{4:f2};{5:f2};{6:f2};{7:f2};{8:f2};{9:f2};{10:f2}", range_info.Vmin, range_info.Vmax, range_info.V0, range_info.ExtremalSpeed, range_info.ExpectancyDeviation, range_info.Cv, range_info.StandardDeviationSpeed, range_info.VeybullGamma, range_info.VeybullBeta, range_info.PowerDensity, range_info.EnergyDensity); //повторяемости направлений ветра List <Enum> rs = WindDirections16.Calm.GetEnumItems().GetRange(0, 17); for (int j = 0; j < rs.Count; j++) { WindDirections16 rhumb = (WindDirections16)rs[j]; int index = stat_directions.Keys.IndexOf(rhumb); if (index == -1) { continue; } line += ";" + (stat_directions.Values[index] * 100).ToString("0.00"); } sw.WriteLine(line); sw.Close(); }
/// <summary> /// запись одной строки в лист ВЭК. Возвращет число элементов в этой строке /// </summary> /// <param name="worksheet">страница для записи</param> /// <param name="line">строка</param> /// <param name="range_info">характеристики по ряду наблюдений</param> /// <param name="ext_info">характеристики по градациям</param> /// <param name="stat_directions">повторяемость направлений</param> /// <param name="stat_speeds">повторяемость скоростей</param> /// <param name="year">год</param> /// <param name="month">месяц</param> /// <param name="amount">число измерений</param> /// <returns>количество добавленных ячеек</returns> private int saveEnergyInfoLine(ExcelWorksheet worksheet, int line, EnergyInfo range_info, EnergyInfo ext_info, StatisticalRange <WindDirections16> stat_directions, StatisticalRange <GradationItem> stat_speeds, string year, string month, int amount) { if (range_info == null || ext_info == null || stat_directions == null || stat_speeds == null) { return(0); } // "Год;Месяц;кол-во изм;0.75;2.5;4.5;6.5;8.5;10.5;12.5;14.5;16.5;19;22.5;26.5;31.5;37.5;43.5;Vmin;Vmax;Vср.год;Vэкстр.50, м/с;δ(P);Cv(V);Nвал уд.;Эвал уд.;С;СВ;В;ЮВ;Ю;ЮЗ;З;СЗ;штиль"; List <object> values = new List <object>() { year, month, amount }; //повторяемости скоростей ветра for (int j = 0; j < stat_speeds.Keys.Count; j++) { values.Add(Math.Round((stat_speeds.Values[j] * 100), 2)); } //по ряду наблюдений values.AddRange(new List <object>() { Math.Round(range_info.Vmin, 2), Math.Round(range_info.Vmax, 2), Math.Round(range_info.V0, 2), Math.Round(range_info.ExtremalSpeed, 2), Math.Round(range_info.ExpectancyDeviation, 2), Math.Round(range_info.Cv, 2), Math.Round(range_info.StandardDeviationSpeed, 2), Math.Round(range_info.VeybullGamma, 2), Math.Round(range_info.VeybullBeta, 2), Math.Round(range_info.PowerDensity, 2), Math.Round(range_info.EnergyDensity, 2) }); //повторяемости направлений ветра List <Enum> rs = WindDirections16.Calm.GetEnumItems().GetRange(0, 17); for (int j = 0; j < rs.Count; j++) { WindDirections16 rhumb = (WindDirections16)rs[j]; int index = stat_directions.Keys.IndexOf(rhumb); if (index == -1) { continue; } values.Add(Math.Round((stat_directions.Values[index] * 100), 2)); } //запись всех значений for (int j = 1; j <= values.Count; j++) { worksheet.Cells[line, j].Value = values[j - 1]; } return(values.Count); }
/// <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); } }