/// <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); }
/// <summary> /// загрузка данных с сайта и закрытие диалогового окна /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void buttonDownload_Click(object sender, EventArgs e) { if (selectedMeteostation == null) { _ = MessageBox.Show(this, "Не выбрана метеостанция или координаты метеостанции недоступны", "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Warning); return; } Action <double> pcChange = new Action <double>((pc) => { if (this.InvokeRequired) { _ = Invoke(new Action(() => { progressBarProgress.Value = (int)pc; progressBarProgress.Refresh(); })); } else { progressBarProgress.Value = (int)pc; progressBarProgress.Refresh(); } }); Action <RawRange> success = new Action <RawRange>((res) => { Result = res; DialogResult = DialogResult.OK; Close(); }); Action <Exception> error1 = new Action <Exception>((ex) => { buttonDownload.Enabled = true; _ = MessageBox.Show(this, ex.Message + "\r\n" + (ex.InnerException != null ? ex.InnerException.Message : ""), "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }); Action <Exception> error2 = new Action <Exception>((ae) => { buttonDownload.Enabled = true; _ = MessageBox.Show(this, ae.Message + "\r\n" + (ae.InnerException != null ? ae.InnerException.Message : "\r\n") + "\r\nПопробуйте выбрать меньший интервал времени", "Загрузка ряда", MessageBoxButtons.OK, MessageBoxIcon.Error); return; }); Action <string> setStatus = new Action <string>((text) => { labelStatus.Text = text; }); buttonDownload.Enabled = false; new Task(() => { try { this.Invoke(setStatus, "Загрузка ряда..."); RawRange res = engine.GetRange(dateTimePickerFromDate.Value, dateTimePickerToDate.Value, selectedMeteostation, pcChange); if (checkBoxClearRange.Checked) { pcChange.Invoke(0); this.Invoke(setStatus, "Очистка ряда..."); res = new Checker().ProcessRange(res, new CheckerParameters(LimitsProviders.StaticLimits, res.Position), out CheckerInfo stats, pcChange); } if (this.InvokeRequired) { _ = Invoke(success, res); } else { success.Invoke(res); } } catch (WebException ex) { if (this.InvokeRequired) { _ = Invoke(error1, ex); } else { error1.Invoke(ex); } } catch (ApplicationException ae) { if (this.InvokeRequired) { _ = Invoke(error2, ae); } else { error2.Invoke(ae); } } catch (Exception ee) { if (this.InvokeRequired) { _ = Invoke(error1, ee); } else { error1.Invoke(ee); } } }).Start(); }
/// <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); }