using DevExpress.XtraEditors; using System.ComponentModel.DataAnnotations; using Yw.Geometry; namespace Yw.WinFrmUI.Phart { public partial class PumpCharImageImportCtrl : XtraUserControl { public PumpCharImageImportCtrl() { InitializeComponent(); Initial(); } private enum eCurveGetWay { [Display(Name = "全部")] All, [Display(Name = "流量扬程/功率,分析效率")] QhQpAnaQe, [Display(Name = "流量扬程/效率,分析功率")] QhQeAnaQp, [Display(Name = "仅流量扬程线")] OnlyQh } private eCurveGetWay _curve_get_way = eCurveGetWay.All; private Yw.Ahart.eCurveType _curve_type = Yw.Ahart.eCurveType.QH; private double? _min_head, _max_head; private double? _min_eff, _max_eff; private double? _min_power, _max_power; private List _pic_qh_pt_list = null; private List _pic_qp_pt_list = null; private List _pic_qe_pt_list = null; private Rectangle? _rect_qh, _rect_qp, _rect_qe; //初始化 private void Initial() { this.repImgCmbSizeModel.Items.Add("常规", PictureBoxSizeMode.Normal, -1); this.repImgCmbSizeModel.Items.Add("拉伸", PictureBoxSizeMode.StretchImage, -1); this.repImgCmbSizeModel.Items.Add("缩放", PictureBoxSizeMode.Zoom, -1); this.repImgCmbSizeModel.Items.Add("居中", PictureBoxSizeMode.CenterImage, -1); this.reImgCmbGetWay.AddEnum(typeof(eCurveGetWay), false); this.barImgCmbGetWay.EditValue = _curve_get_way; this.repImgCmbUnitX.AddEnum(typeof(Unit.eUnitQ), false); this.barImgCmbUnitX.EditValue = this.pumpImageBoxCtrl1.UnitQ; this.barcekCaputueEffPt.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; this.repImgCmbCurveType.EditValueChanging += RepImgCmbCurveType_EditValueChanging; this.barImgCmbCurveType.EditValueChanged += BarImgCmbCurveType_EditValueChanged; ; this.pumpImageBoxCtrl1.ReloadPickPointsEvent += CurvePictureBoxCtrl1_ReloadPickPointsEvent; this.pumpImageBoxCtrl1.ReloadBoundaryEvent += CurvePictureBoxCtrl1_ReloadBoundaryEvent; this.barImgCmbCurveType.EditValue = _curve_type; this.barImgCmbSizeModel.EditValue = PictureBoxSizeMode.StretchImage; } /// /// 初始化数据 /// public void SetBindingData(string file_path) { this.pumpImageBoxCtrl1.SetBindingData(file_path); this.pumpImageBoxCtrl1.Enabled = true; } //曲线获取方法 private void repimgCmbGetWay_SelectedValueChanged(object sender, EventArgs e) { _curve_get_way = (eCurveGetWay)this.barImgCmbGetWay.EditValue; switch (_curve_get_way) { case eCurveGetWay.QhQpAnaQe: { _rect_qe = null; _pic_qe_pt_list = null; this.repImgCmbCurveType.Items.Clear(); this.repImgCmbCurveType.Items.Add("流量扬程线", Yw.Ahart.eCurveType.QH, -1); this.repImgCmbCurveType.Items.Add("流量功率线", Yw.Ahart.eCurveType.QP, -1); } break; case eCurveGetWay.QhQeAnaQp: { _rect_qp = null; _pic_qp_pt_list = null; this.repImgCmbCurveType.Items.Clear(); this.repImgCmbCurveType.Items.Add("流量扬程线", Yw.Ahart.eCurveType.QH, -1); this.repImgCmbCurveType.Items.Add("流量效率线", Yw.Ahart.eCurveType.QE, -1); } break; case eCurveGetWay.OnlyQh: { _rect_qe = null; _rect_qp = null; _pic_qp_pt_list = null; _pic_qe_pt_list = null; this.repImgCmbCurveType.Items.Clear(); this.repImgCmbCurveType.Items.Add("流量扬程线", Yw.Ahart.eCurveType.QH, -1); } break; case eCurveGetWay.All: { this.repImgCmbCurveType.Items.Clear(); this.repImgCmbCurveType.Items.Add("流量扬程线", Yw.Ahart.eCurveType.QH, -1); this.repImgCmbCurveType.Items.Add("流量功率线", Yw.Ahart.eCurveType.QP, -1); this.repImgCmbCurveType.Items.Add("流量效率线", Yw.Ahart.eCurveType.QE, -1); } break; } } //流量单位变换 private void repImgCmbUnitX_SelectedValueChanged(object sender, EventArgs e) { this.pumpImageBoxCtrl1.UnitQ = (Unit.eUnitQ)this.barImgCmbUnitX.EditValue; } //图片显示模式 private void barImgCmbSizeModel_EditValueChanged(object sender, EventArgs e) { var size_model = (PictureBoxSizeMode)this.barImgCmbSizeModel.EditValue; this.pumpImageBoxCtrl1.SetPictureSizeMode(size_model); } //框选坐标 private void barBtnSetCoordinates_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { this.pumpImageBoxCtrl1.StartSelectionRange(); this.barCekPickPt.Checked = false; } //坐标框选完成 private void CurvePictureBoxCtrl1_ReloadBoundaryEvent(System.Drawing.Rectangle? obj) { switch (_curve_type) { case Yw.Ahart.eCurveType.QH: _rect_qh = obj; break; case Yw.Ahart.eCurveType.QE: _rect_qe = obj; break; case Yw.Ahart.eCurveType.QP: _rect_qp = obj; break; } } //抓取点 private void barCekPickPt_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { if (this.barCekPickPt.Checked) { if (!ReloadChartCoordinate()) { this.barCekPickPt.Checked = false; XtraMessageBox.Show("请输入坐标!"); return; } this.pumpImageBoxCtrl1.StartPickPoint(); } else { this.pumpImageBoxCtrl1.EndPickPoint(); } } //刷新图表坐标 private bool ReloadChartCoordinate() { if (this.barTxtMinX.EditValue == null || this.barTxtMaxX.EditValue == null) return false; this.pumpImageBoxCtrl1.ChartMinX = Convert.ToDouble(this.barTxtMinX.EditValue); this.pumpImageBoxCtrl1.ChartMaxX = Convert.ToDouble(this.barTxtMaxX.EditValue); double? min_y = this.barTxtMinY.EditValue == null ? null : Convert.ToDouble(this.barTxtMinY.EditValue); double? max_y = this.barTxtMaxY.EditValue == null ? null : Convert.ToDouble(this.barTxtMaxY.EditValue); if (min_y == null || max_y == null) return false; switch (_curve_type) { case Yw.Ahart.eCurveType.QH: { _max_head = max_y; _min_head = min_y; } break; case Yw.Ahart.eCurveType.QE: { _max_eff = max_y; _min_eff = min_y; } break; case Yw.Ahart.eCurveType.QP: { _max_power = max_y; _min_power = min_y; } break; } this.pumpImageBoxCtrl1.ChartMaxY = max_y.Value; this.pumpImageBoxCtrl1.ChartMinY = min_y.Value; return true; } //清空点 private void barClearPt_ItemClick(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { this.pumpImageBoxCtrl1.ClearPickPoint(); } //选择曲线变换时 private void RepImgCmbCurveType_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e) { if (e.OldValue == null) return; var old_curve_type = (Yw.Ahart.eCurveType)e.OldValue; var new_curve_type = e.NewValue; this.pumpImageBoxCtrl1.GetPicPoints(out List clickPoints); double? min_y = this.barTxtMinY.EditValue == null ? null : Convert.ToDouble(this.barTxtMinY.EditValue); double? max_y = this.barTxtMaxY.EditValue == null ? null : Convert.ToDouble(this.barTxtMaxY.EditValue); switch (old_curve_type) { case Ahart.eCurveType.QH: { _min_head = min_y; _max_head = max_y; _pic_qh_pt_list = clickPoints; } break; case Ahart.eCurveType.QE: { _min_eff = min_y; _max_eff = max_y; _pic_qe_pt_list = clickPoints; } break; case Ahart.eCurveType.QP: { _min_power = min_y; _max_power = max_y; _pic_qp_pt_list = clickPoints; } break; } } //选择曲线变换 private void BarImgCmbCurveType_EditValueChanged(object sender, EventArgs e) { this.barCekPickPt.Checked = false; _curve_type = (Yw.Ahart.eCurveType)this.barImgCmbCurveType.EditValue; this.pumpImageBoxCtrl1.CurrentCaptureCruve = _curve_type; switch (_curve_type) { case Yw.Ahart.eCurveType.QH: { this.barTxtMinY.Caption = "扬程最小值:"; this.barTxtMaxY.Caption = "扬程最大值:"; this.barTxtMinY.EditValue = _min_head; this.barTxtMaxY.EditValue = _max_head; if (_min_head == null || _max_head == null) { return; } this.pumpImageBoxCtrl1.ChartMinY = _min_head.Value; this.pumpImageBoxCtrl1.ChartMaxY = _max_head.Value; this.pumpImageBoxCtrl1.RefreshPictureShape(_pic_qh_pt_list, _rect_qh); this.barcekCaputueEffPt.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } break; case Yw.Ahart.eCurveType.QE: { this.barTxtMinY.Caption = "效率最小值:"; this.barTxtMaxY.Caption = "效率最大值:"; this.barTxtMinY.EditValue = _min_eff; this.barTxtMaxY.EditValue = _max_eff; if (_min_eff == null || _max_eff == null) { return; } this.pumpImageBoxCtrl1.ChartMinY = _min_eff.Value; this.pumpImageBoxCtrl1.ChartMaxY = _max_eff.Value; this.pumpImageBoxCtrl1.RefreshPictureShape(_pic_qe_pt_list, _rect_qe); this.barcekCaputueEffPt.Visibility = DevExpress.XtraBars.BarItemVisibility.Always; } break; case Yw.Ahart.eCurveType.QP: { this.barTxtMinY.Caption = "功率最小值:"; this.barTxtMaxY.Caption = "功率最大值:"; this.barTxtMinY.EditValue = _min_power; this.barTxtMaxY.EditValue = _max_power; if (_min_power == null || _max_power == null) { return; } this.pumpImageBoxCtrl1.ChartMinY = _min_power.Value; this.pumpImageBoxCtrl1.ChartMaxY = _max_power.Value; this.pumpImageBoxCtrl1.RefreshPictureShape(_pic_qp_pt_list, _rect_qp); this.barcekCaputueEffPt.Visibility = DevExpress.XtraBars.BarItemVisibility.Never; } break; } ReloadChartCoordinate(); } //打点等效线 private void barcekCaputueEffPt_CheckedChanged(object sender, DevExpress.XtraBars.ItemClickEventArgs e) { this.pumpImageBoxCtrl1.IsCaputueEtaPtInEqupCurve = this.barcekCaputueEffPt.Checked; } //打点更新数据 private void CurvePictureBoxCtrl1_ReloadPickPointsEvent(List list) { switch (_curve_type) { case Yw.Ahart.eCurveType.QH: _pic_qh_pt_list = list; break; case Yw.Ahart.eCurveType.QE: _pic_qe_pt_list = list; break; case Yw.Ahart.eCurveType.QP: _pic_qp_pt_list = list; break; } } #region 方法 /// /// 获取数据 /// public bool Get( out List def_qh_pt_list, out List def_qe_pt_list, out List def_qp_pt_list, out Yw.Ahart.eFeatType feat_type_qh, out Yw.Ahart.eFeatType feat_type_qe, out Yw.Ahart.eFeatType feat_type_qp) { def_qh_pt_list = null; def_qe_pt_list = null; def_qp_pt_list = null; feat_type_qh = Ahart.eFeatType.Cubic; feat_type_qe = Ahart.eFeatType.Cubic; feat_type_qp = Ahart.eFeatType.Cubic; switch (_curve_get_way) { case eCurveGetWay.All: { if (_pic_qh_pt_list == null || _pic_qh_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量扬程点!"); return false; } if (_pic_qp_pt_list == null || _pic_qp_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量功率点!"); return false; } if (_pic_qe_pt_list == null || _pic_qe_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量效率点!"); return false; } } break; case eCurveGetWay.QhQpAnaQe: { if (_pic_qh_pt_list == null || _pic_qh_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量扬程点!"); return false; } if (_pic_qp_pt_list == null || _pic_qp_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量功率点!"); return false; } } break; case eCurveGetWay.QhQeAnaQp: { if (_pic_qh_pt_list == null || _pic_qh_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量扬程点!"); return false; } if (_pic_qe_pt_list == null || _pic_qe_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量效率点!"); return false; } } break; case eCurveGetWay.OnlyQh: { if (_pic_qh_pt_list == null || _pic_qh_pt_list.Count < 4) { XtraMessageBox.Show("请录入流量扬程点!"); return false; } } break; default: break; } var qh_pt_list = new List(); var qe_pt_list = new List(); var qp_pt_list = new List(); var pic_qh_pt_list = new List(); var pic_qe_pt_list = new List(); var pic_qp_pt_list = new List(); var unitQ = this.pumpImageBoxCtrl1.UnitQ; double MinQ = 0; double MaxQ = 0; if (this.pumpImageBoxCtrl1.ChartMinX == 0) MinQ = 0; else MinQ = _pic_qh_pt_list.Min(x => x.X); MaxQ = _pic_qh_pt_list.Max(x => x.X); //换算单位 MinQ = Unit.UnitQHelper.Convert(unitQ, Unit.eUnitQ.M3H, MinQ); MaxQ = Unit.UnitQHelper.Convert(unitQ, Unit.eUnitQ.M3H, MaxQ); pic_qh_pt_list = ToM3H(unitQ, _pic_qh_pt_list); pic_qe_pt_list = ToM3H(unitQ, _pic_qe_pt_list); pic_qp_pt_list = ToM3H(unitQ, _pic_qp_pt_list); int insert_num = 15; double space = (MaxQ - MinQ) / (insert_num - 1); int i = 0; double Q = MinQ; double H, E = 0, P = 0; for (i = 1; i < insert_num - 1; i++) { Q = Q + space; H = pic_qh_pt_list.GetPointList(feat_type_qh).GetInterPointsY(Q).Last(); qh_pt_list.Add(new Yw.Geometry.Point2d(Q, H)); if (_curve_get_way != eCurveGetWay.OnlyQh) { switch (_curve_get_way) { case eCurveGetWay.All: { P = pic_qp_pt_list.GetPointList(feat_type_qp).GetInterPointsY(Q)?.LastOrDefault() ?? 0; E = pic_qe_pt_list.GetPointList(feat_type_qe).GetInterPointsY(Q)?.LastOrDefault() ?? 0; } break; case eCurveGetWay.QhQpAnaQe: { P = pic_qp_pt_list.GetPointList(feat_type_qp).GetInterPointsY(Q)?.LastOrDefault() ?? 0; E = Yw.Pump.CalculationHelper.CalcuE(Q, H, P); } break; case eCurveGetWay.QhQeAnaQp: { E = pic_qe_pt_list.GetPointList(feat_type_qe).GetInterPointsY(Q)?.LastOrDefault() ?? 0; P = Yw.Pump.CalculationHelper.CalcuP(Q, H, E); } break; } qp_pt_list.Add(new Yw.Geometry.Point2d(Q, P)); qe_pt_list.Add(new Yw.Geometry.Point2d(Q, E)); } } if (_curve_get_way == eCurveGetWay.OnlyQh) { if (qh_pt_list.Count < 3) { XtraMessageBox.Show("未导入足够多的性能曲线点"); return false; } } else { if (qh_pt_list.Count < 3 || qe_pt_list.Count < 3 || qp_pt_list.Count < 3) { qh_pt_list = null; qe_pt_list = null; qp_pt_list = null; XtraMessageBox.Show("未导入足够多的性能曲线点"); return false; } } #region 首尾两点的处理:因为首尾2点按流量扬程获取范围,而点击不一定正好首尾2点流量一样 //流量扬程首尾两点 double startH = LineHelper.GetYbyX(qh_pt_list[0].X, qh_pt_list[0].Y, qh_pt_list[1].X, qh_pt_list[1].Y, MinQ); qh_pt_list.Insert(0, new Yw.Geometry.Point2d(MinQ, startH)); int point_num = qh_pt_list.Count;//不一定和insert_num一样 double endH = LineHelper.GetYbyX(qh_pt_list[point_num - 2].X, qh_pt_list[point_num - 2].Y, qh_pt_list[point_num - 1].X, qh_pt_list[point_num - 1].Y, MaxQ); qh_pt_list.Add(new Yw.Geometry.Point2d(MaxQ, endH)); if (qe_pt_list != null && qe_pt_list.Count > 0) { //流量效率首尾两点 double startE = 0;//起始点 if (MinQ > 0.2) startE = LineHelper.GetYbyX(qe_pt_list[0].X, qe_pt_list[0].Y, qe_pt_list[1].X, qe_pt_list[1].Y, MinQ); else startE = 0; qe_pt_list.Insert(0, new Yw.Geometry.Point2d(MinQ, startE)); point_num = qe_pt_list.Count;//末尾点 double endE = LineHelper.GetYbyX(qe_pt_list[point_num - 2].X, qe_pt_list[point_num - 2].Y, qe_pt_list[point_num - 1].X, qe_pt_list[point_num - 1].Y, MaxQ); qe_pt_list.Add(new Yw.Geometry.Point2d(MaxQ, endE)); } if (qp_pt_list != null && qp_pt_list.Count > 0) { //流量功率首尾两点 double startP = LineHelper.GetYbyX(qp_pt_list[0].X, qp_pt_list[0].Y, qp_pt_list[1].X, qp_pt_list[1].Y, MinQ); qp_pt_list.Insert(0, new Yw.Geometry.Point2d(MinQ, startP)); point_num = qp_pt_list.Count; double endP = LineHelper.GetYbyX(qp_pt_list[point_num - 2].X, qp_pt_list[point_num - 2].Y, qp_pt_list[point_num - 1].X, qp_pt_list[point_num - 1].Y, MaxQ); qp_pt_list.Add(new Yw.Geometry.Point2d(MaxQ, endP)); } #endregion //圆整 def_qh_pt_list = Regulate(qh_pt_list, 2); def_qe_pt_list = Regulate(qe_pt_list, 2); def_qp_pt_list = Regulate(qp_pt_list, 2); return true; } //单位换算 private List ToM3H(Unit.eUnitQ unit, List points) { if (unit == Unit.eUnitQ.M3H) { return points; } if (points == null) { return null; } var list = new List(); for (int i = 0; i < points.Count; i++) { var point = new Yw.Geometry.Point2d(points[i]); point.X = Unit.UnitQHelper.Convert(unit, Unit.eUnitQ.M3H, point.X); list.Add(point); } return list; } //四舍五入圆整,如 0.44 -> 0.4 , 0.46 -> 0.5//flag--小数点后位数 public static List Regulate(List inPoints, int flag) { if (inPoints == null) return null; List outPoints = new List(); for (int i = 0; i < inPoints.Count(); i++) { outPoints.Add(new Yw.Geometry.Point2d(Regulate(inPoints[i].X, flag), Regulate(inPoints[i].Y, flag))); } return outPoints; } //四舍五入圆整,如 0.44 -> 0.4 , 0.46 -> 0.5//flag--小数点后位数 public static double Regulate(double v, int flag) { bool isNegative = false; //如果是负数 if (v < 0) { isNegative = true; v = Math.Abs(v); } else { isNegative = false; } double value = Math.Round(v, flag); if (isNegative) { value = -value; } return value; } #endregion } }