AnalystResultPouDuanMian.cs 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369
  1. using SuperMap.Data;
  2. using System;
  3. using System.Collections.Generic;
  4. using System.ComponentModel;
  5. using System.Data;
  6. using System.Drawing;
  7. using System.Drawing.Drawing2D;
  8. using System.Linq;
  9. using System.Text;
  10. using System.Threading.Tasks;
  11. using System.Windows.Forms;
  12. using WWPipeLine.MapBasic;
  13. namespace WWPipeLine.MapTools.Conditions.AnalystToolBar
  14. {
  15. public partial class AnalystResultPouDuanMian : Sunny.UI.UIForm
  16. {
  17. private DataTable m_dt;
  18. private string m_dType = string.Empty;
  19. public AnalystResultPouDuanMian(DataTable dt, string dtType)
  20. {
  21. InitializeComponent();
  22. this.StartPosition = FormStartPosition.Manual;
  23. this.Location = new System.Drawing.Point(10, 10);
  24. m_dt = dt; m_dType = dtType;
  25. if (dtType == "poumian")
  26. {
  27. uitxtTitle.Text = "城市供水管网纵剖面图";
  28. this.Text = "剖面分析结果";
  29. }
  30. if (dtType == "duanmian")
  31. {
  32. uitxtTitle.Text = "城市供水管网横断面图";
  33. this.Text = "断面分析结果";
  34. }
  35. }
  36. private void AnalystResultForm_Load(object sender, EventArgs e)
  37. {
  38. int width = 800;// pictureBox.Width;
  39. int height = 600;// pictureBox.Height;
  40. Bitmap image = new Bitmap(width, height);
  41. //创建Graphics类对象
  42. Graphics g = Graphics.FromImage(image);
  43. g.SmoothingMode = SmoothingMode.AntiAlias;
  44. g.InterpolationMode = InterpolationMode.HighQualityBicubic;
  45. g.CompositingQuality = CompositingQuality.HighQuality;
  46. g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
  47. g.Clear(Color.White);
  48. Pen PenXYLine = Pens.Blue;
  49. Pen PenBlack = Pens.Black;
  50. Brush defaultBrush = Brushes.Black;
  51. Font fontNormal = new Font("Arial", 9, FontStyle.Regular);
  52. Font fontTitle = new Font("Arial", 16, FontStyle.Bold);
  53. //顶部标题
  54. g.DrawString(uitxtTitle.Text, fontTitle, defaultBrush, new PointF(width / 3, 10));
  55. //画图片的边框线
  56. g.DrawRectangle(PenXYLine, 0, 50, width - 2, height - 52);
  57. //绘制 Y轴线,直接从顶到底
  58. g.DrawLine(PenXYLine, 100, 50, 100, height);
  59. int yHeight = 450;// height - 50 - TableLineHeight * 5;
  60. int gxgcFenDuanHeight = 75;// (int)450 / 6; //(int)((height - 55 - TableLineHeight * 6) / 6
  61. int xWidth = 700;
  62. double UnitX = 0;
  63. double UnitY = 0;
  64. DataView m_dt_dv = m_dt.DefaultView;
  65. if (m_dType == "poumian")
  66. {
  67. #region 计算 Y轴 最大值与最小值 Y轴设置横线5根,数据值5个,分为6段,7个节点
  68. //高程最大值 取地面高程的最大值
  69. m_dt_dv.Sort = "dmgc DESC"; double gcMax = Math.Round(double.Parse(m_dt_dv[0]["dmgc"].ToString()), 2);
  70. //高程最小值 =管顶高程最小值-管点埋深最大值
  71. m_dt_dv.Sort = "gdgc ASC"; double gdgcMin = Math.Round(double.Parse(m_dt_dv[0]["gdgc"].ToString()), 2);
  72. m_dt_dv.Sort = "gdms DESC"; double gdmsMin = Math.Round(double.Parse(m_dt_dv[0]["gdms"].ToString()), 2);
  73. double gcMin = gdgcMin - gdmsMin;
  74. //Y轴共计6段,计算每一段的差值
  75. double gdgcChaZhi = Math.Round(gcMax - (gcMax + gcMin) / 2, 2);
  76. if (gdgcChaZhi == 0 || gdgcChaZhi == double.PositiveInfinity || gdgcChaZhi == double.NegativeInfinity)
  77. {
  78. gdgcChaZhi = 1;
  79. }
  80. double gdgcTop = gcMax + gdgcChaZhi * 2;
  81. for (int i = 0; i <= 6; i++)//Y轴分为6段,除了顶部和底部,需要绘制5个 短横线和坐标值
  82. {
  83. if (i == 0 || i == 6) continue;
  84. g.DrawLine(PenXYLine, 95, 50 + i * gxgcFenDuanHeight, 100, 50 + i * gxgcFenDuanHeight);
  85. g.DrawString(GetGxgcY(i).ToString(), fontNormal, defaultBrush, 50, 50 + i * gxgcFenDuanHeight - 5);
  86. }
  87. double GetGxgcY(int i)
  88. {
  89. switch (i)
  90. {
  91. case 0: return gdgcTop;
  92. case 1: return gdgcTop - gdgcChaZhi;
  93. case 2: return gcMax;
  94. case 3: return gcMax - gdgcChaZhi;
  95. case 4: return gcMax - gdgcChaZhi * 2;
  96. case 5: return gcMax - gdgcChaZhi * 3;
  97. case 6: return gcMax - gdgcChaZhi * 4;
  98. default: return 0.0;
  99. }
  100. }
  101. UnitY = yHeight / (gdgcChaZhi * 6);
  102. #endregion
  103. #region X轴 计算UnitX 并配置断面的X坐标
  104. double tbJuLiSum = 0.0D;
  105. foreach (DataRow dr in m_dt.Rows)
  106. {
  107. if (m_dt.Rows.IndexOf(dr) == m_dt.Rows.Count - 1) continue;
  108. tbJuLiSum += double.Parse(dr["gxcd"].ToString());
  109. }
  110. if (tbJuLiSum == 0 || tbJuLiSum == double.PositiveInfinity || tbJuLiSum == double.NegativeInfinity)
  111. {
  112. tbJuLiSum = 1;
  113. }
  114. UnitX = (xWidth - 120) / tbJuLiSum;
  115. double tbJuLiX = 120.0D;
  116. foreach (DataRow dr in m_dt.Rows)
  117. {
  118. double newJuli = UnitX * double.Parse(dr["gxcd"].ToString());
  119. dr["xLeft"] = newJuli * 0.6;
  120. if (m_dt.Rows.IndexOf(dr) == 0) { dr["x"] = tbJuLiX; continue; }
  121. tbJuLiX += newJuli;
  122. dr["x"] = tbJuLiX;
  123. }
  124. #endregion
  125. #region 绘制 底部的表格横线 表格数据展示
  126. g.DrawString("地面高程(M)", fontNormal, defaultBrush, 40, 60);
  127. int TableLineHeight = 20;
  128. string tbTitle = "";
  129. string tbZiDuan = "";
  130. for (int i = 1; i <= 5; i++)
  131. {
  132. g.DrawLine(PenXYLine, 0, height - i * TableLineHeight, width, height - i * TableLineHeight);
  133. GetTableColumsCaption(i);
  134. float StringY = height - i * TableLineHeight + 5;
  135. g.DrawString(tbTitle, fontNormal, defaultBrush, 20, StringY);
  136. for (int j = 0; j < m_dt.Rows.Count; j++)
  137. {
  138. if (tbZiDuan == "gxgj" || tbZiDuan == "gxcd")
  139. {
  140. if (j == m_dt.Rows.Count - 1) continue;
  141. g.DrawString(m_dt.Rows[j][tbZiDuan].ToString(), fontNormal, defaultBrush, float.Parse(m_dt.Rows[j]["x"].ToString()) + float.Parse(m_dt.Rows[j]["xLeft"].ToString()), StringY);
  142. continue;
  143. }
  144. g.DrawString(m_dt.Rows[j][tbZiDuan].ToString(), fontNormal, defaultBrush, float.Parse(m_dt.Rows[j]["x"].ToString()), StringY);
  145. if (tbZiDuan == "dmgc")//计算Y坐标,只需要计算一次
  146. {
  147. m_dt.Rows[j]["y"] = 50 + UnitY * (gdgcTop - Double.Parse(m_dt.Rows[j]["dmgc"].ToString()));
  148. m_dt.Rows[j]["ygd"] = double.Parse(m_dt.Rows[j]["y"].ToString()) + UnitY * Double.Parse(m_dt.Rows[j]["gdms"].ToString());
  149. }
  150. }
  151. }
  152. void GetTableColumsCaption(int i)
  153. {
  154. switch (i)
  155. {
  156. case 1: tbTitle = "管线长度(M)"; tbZiDuan = "gxcd"; break;
  157. case 2: tbTitle = "管线管径(MM)"; tbZiDuan = "gxgj"; break;
  158. case 3: tbTitle = "管点埋深(M)"; tbZiDuan = "gdms"; break;
  159. case 4: tbTitle = "管顶高程(M)"; tbZiDuan = "gdgc"; break;
  160. case 5: tbTitle = "地面高程(M)"; tbZiDuan = "dmgc"; break;
  161. default: tbTitle = "未知"; tbZiDuan = ""; break;
  162. }
  163. }
  164. #endregion
  165. #region 绘制 断面管线
  166. float gxgj = 0;
  167. float Ydmgc = 0.0F;
  168. float Xdmgc = 0.0F;
  169. float Ygdgc = 0.0F;
  170. for (int j = 0; j < m_dt.Rows.Count; j++)
  171. {
  172. float.TryParse(m_dt.Rows[j]["gxgj"].ToString(), out gxgj);
  173. gxgj = (float)(gxgj / 1000 * UnitY);
  174. Xdmgc = float.Parse(m_dt.Rows[j]["x"].ToString());
  175. Ydmgc = float.Parse(m_dt.Rows[j]["y"].ToString());
  176. Ygdgc = float.Parse(m_dt.Rows[j]["ygd"].ToString());
  177. //绘制 地面高程 到 管顶高程的 竖线 该管点为管线的起始管点
  178. //g.DrawLine(PenXYLine, Xdmgc, Ydmgc, Xdmgc, Ygdgc);
  179. if (j == 0)//第一行 只需要绘制地面高程到管顶高程的竖线
  180. {
  181. g.DrawLine(PenBlack, Xdmgc, Ygdgc, Xdmgc, Ygdgc + gxgj);
  182. continue;
  183. }
  184. //绘制地面高程线 管线的 起始管点 到 终点管点
  185. g.DrawLine(PenBlack, float.Parse(m_dt.Rows[j - 1]["x"].ToString()), float.Parse(m_dt.Rows[j - 1]["y"].ToString()), Xdmgc, Ydmgc);
  186. //绘制管顶高程线 管线的 起始管点 到 终点管点的 管顶
  187. g.DrawLine(PenBlack, float.Parse(m_dt.Rows[j - 1]["x"].ToString()), float.Parse(m_dt.Rows[j - 1]["ygd"].ToString()), Xdmgc, Ygdgc);
  188. //绘制管底高程线
  189. g.DrawLine(PenBlack, float.Parse(m_dt.Rows[j - 1]["x"].ToString()), float.Parse(m_dt.Rows[j - 1]["ygd"].ToString()) + gxgj, Xdmgc, Ygdgc + gxgj);
  190. //绘制管头的竖线
  191. g.DrawLine(PenBlack, Xdmgc, Ygdgc, Xdmgc, Ygdgc + gxgj);
  192. }
  193. #endregion
  194. }
  195. if (m_dType == "duanmian")
  196. {
  197. #region 计算 Y轴 最大值与最小值 Y轴设置横线5根,数据值5个,分为6段,7个节点
  198. m_dt_dv.Sort = "gxgc DESC";
  199. double gxgcMax = 0.0; double.TryParse(m_dt_dv[0]["gxgc"].ToString(), out gxgcMax); gxgcMax = Math.Round(gxgcMax, 2);
  200. double gxgcMin = 0.0; double.TryParse(m_dt_dv[m_dt_dv.Count - 1]["gxgc"].ToString(), out gxgcMin); gxgcMin = Math.Round(gxgcMin, 2);
  201. double gxgcChaZhi = Math.Round(gxgcMax - (gxgcMax + gxgcMin) / 2, 2);
  202. if (gxgcChaZhi == 0 || gxgcChaZhi == double.PositiveInfinity || gxgcChaZhi == double.NegativeInfinity)
  203. {
  204. gxgcChaZhi = 1;
  205. }
  206. double gxgcTop = gxgcMax + gxgcChaZhi * 2;
  207. for (int i = 0; i <= 6; i++)//Y轴分为6段,除了顶部和底部,需要绘制5个 短横线和坐标值
  208. {
  209. if (i == 0 || i == 6) continue;
  210. g.DrawLine(PenXYLine, 95, 50 + i * gxgcFenDuanHeight, 100, 50 + i * gxgcFenDuanHeight);
  211. g.DrawString(GetGxgcY(i).ToString(), fontNormal, defaultBrush, 50, 50 + i * gxgcFenDuanHeight - 5);
  212. }
  213. double GetGxgcY(int i)
  214. {
  215. switch (i)
  216. {
  217. case 0: return gxgcTop;
  218. case 1: return gxgcMax + gxgcChaZhi;
  219. case 2: return gxgcMax;
  220. case 3: return gxgcMax - gxgcChaZhi;
  221. case 4: return gxgcMin;
  222. case 5: return gxgcMin - gxgcChaZhi;
  223. case 6: return gxgcMin - gxgcChaZhi * 2;
  224. default: return 0.0;
  225. }
  226. }
  227. UnitY = yHeight / (gxgcChaZhi * 6);
  228. #endregion
  229. #region X轴 计算UnitX 并配置断面的X坐标
  230. double tbJuLiSum = Convert.ToDouble(m_dt.Compute("SUM(jl)", ""));
  231. if (tbJuLiSum == 0 || tbJuLiSum == double.PositiveInfinity || tbJuLiSum == double.NegativeInfinity)
  232. {
  233. tbJuLiSum = 1;
  234. }
  235. UnitX = (xWidth - 150) / tbJuLiSum;
  236. double tbJuLiX = 150.0D;
  237. foreach (DataRow dr in m_dt.Rows)
  238. {
  239. if (m_dt.Rows.IndexOf(dr) == 0) { dr["x"] = tbJuLiX; continue; }
  240. double newJuli = UnitX * ComsStatic.StringToDouble(dr["jl"]);
  241. dr["xLeft"] = newJuli * 0.6;
  242. tbJuLiX += newJuli;
  243. dr["x"] = tbJuLiX;
  244. }
  245. #endregion
  246. #region 绘制 底部的表格横线 表格数据展示
  247. g.DrawString("管线高程(M)", fontNormal, defaultBrush, 40, 60);
  248. int TableLineHeight = 20;
  249. string tbTitle = "";
  250. string tbZiDuan = "";
  251. for (int i = 1; i <= 5; i++)
  252. {
  253. g.DrawLine(PenXYLine, 0, height - i * TableLineHeight, width, height - i * TableLineHeight);
  254. GetTableColumsCaption(i);
  255. float StringY = height - i * TableLineHeight + 5;
  256. g.DrawString(tbTitle, fontNormal, defaultBrush, 20, StringY);
  257. for (int j = 0; j < m_dt.Rows.Count; j++)
  258. {
  259. if (tbZiDuan == "jl")//距离直接显示,这个地方可以 设置 距离在2个断面的中间
  260. {
  261. if (j == 0) continue;
  262. g.DrawString(m_dt.Rows[j]["jl"].ToString(), fontNormal, defaultBrush, float.Parse(m_dt.Rows[j]["x"].ToString()) - float.Parse(m_dt.Rows[j]["xLeft"].ToString()), StringY);
  263. continue;
  264. }
  265. g.DrawString(m_dt.Rows[j][tbZiDuan].ToString(), fontNormal, defaultBrush, float.Parse(m_dt.Rows[j]["x"].ToString()), StringY);
  266. if (tbZiDuan == "gxgc")//计算Y坐标,只需要计算一次
  267. {
  268. m_dt.Rows[j]["Y"] = (50 + UnitY * (gxgcTop - Double.Parse(m_dt.Rows[j]["gxgc"].ToString())));
  269. }
  270. }
  271. }
  272. void GetTableColumsCaption(int i)
  273. {
  274. switch (i)
  275. {
  276. case 1: tbTitle = "距 离(M)"; tbZiDuan = "jl"; break;
  277. case 2: tbTitle = "管 径(MM)"; tbZiDuan = "gxgj"; break;
  278. case 3: tbTitle = "管线埋深(M)"; tbZiDuan = "gxms"; break;
  279. case 4: tbTitle = "管线高程(M)"; tbZiDuan = "gxgc"; break;
  280. case 5: tbTitle = "地面高程(M)"; tbZiDuan = "dmgc"; break;
  281. default: tbTitle = "未知"; tbZiDuan = ""; break;
  282. }
  283. }
  284. #endregion
  285. #region 绘制 断面管线
  286. double gxgj = 0;
  287. double zhijing = 0;
  288. Pen PenXuxian = new Pen(Color.Blue, 2); PenXuxian.DashStyle = DashStyle.Dash;
  289. for (int j = 0; j < m_dt.Rows.Count; j++)
  290. {
  291. double.TryParse(m_dt.Rows[j]["gxgj"].ToString(), out gxgj);
  292. zhijing = gxgj / 1000 * UnitY;
  293. g.DrawEllipse(PenXYLine, (float)(float.Parse(m_dt.Rows[j]["x"].ToString()) - zhijing * 0.5), (float)(float.Parse(m_dt.Rows[j]["y"].ToString()) - zhijing * 0.5), (float)(zhijing), (float)(zhijing));
  294. g.DrawLine(PenXuxian, float.Parse(m_dt.Rows[j]["x"].ToString()), (float)(float.Parse(m_dt.Rows[j]["y"].ToString()) + zhijing * 0.5), float.Parse(m_dt.Rows[j]["x"].ToString()), 596);
  295. }
  296. #endregion
  297. }
  298. //显示 比例尺
  299. string bilichi = string.Format("水平比例尺 1:{0} 垂直比例尺 1:{1} ", Math.Round(UnitX, 0), Math.Round(UnitY, 0));
  300. g.DrawString(bilichi, fontNormal, defaultBrush, width / 3, 60);
  301. pictureBox.Image = image;
  302. }
  303. private void uibtnSave_Click(object sender, EventArgs e)
  304. {
  305. SaveFileDialog save = new SaveFileDialog();
  306. save.FileName = uitxtTitle.Text;
  307. save.Filter = "Jpg 图片|*.jpg|Bmp 图片|*.bmp|Png 图片|*.png";
  308. if (save.ShowDialog() == DialogResult.OK)
  309. {
  310. pictureBox.Image.Save(save.FileName);
  311. }
  312. }
  313. private void uibtnQuantu_Click(object sender, EventArgs e)
  314. {
  315. pictureBox.Width = 800;
  316. pictureBox.Height = 600;
  317. pictureBox.SizeMode = PictureBoxSizeMode.AutoSize;
  318. pictureBox.Refresh();
  319. }
  320. private void uiIbtnFangda_Click(object sender, EventArgs e)
  321. {
  322. pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
  323. pictureBox.Width = (int)(pictureBox.Width * 1.2);
  324. pictureBox.Height = (int)(pictureBox.Height * 1.2);
  325. pictureBox.Refresh();
  326. }
  327. private void uibtnSuoxiao_Click(object sender, EventArgs e)
  328. {
  329. pictureBox.SizeMode = PictureBoxSizeMode.StretchImage;
  330. pictureBox.Width = (int)(pictureBox.Width * 0.8);
  331. pictureBox.Height = (int)(pictureBox.Height * 0.8);
  332. pictureBox.Refresh();
  333. }
  334. }
  335. }