// ■色地図と等高線の表示 // @以下のusingを追加 // using System.Drawing.Drawing2D; // using System.IO; // AopenFileDialog1を配置してFileOkイベントをopenFileDialog1_FileOkに指定 // Btextbox1を配置してTextプロパティを200にして、TextChangedイベントを // textbox1_TextChangedに指定 // (TextAlignをRightにするほうがよい) // Cbutton1のTextを"数値地図読込"にしてClickイベントをbutton1_Clickに指定 // Dbutton2のTextを"再表示"にしてClickイベントをbutton1_Clickに指定 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Windows.Forms; using System.Drawing.Drawing2D; // これを追加すること using System.IO; // これを追加すること namespace contour { public partial class Form1 : Form { private int numX = 201, numY = 201; // メッシュ数 private double dx = 1.0, dy = 1.0; // 刻み幅 private double Hstep; // 等高線間隔 private double[,] Z = new double[201, 201]; // 標高値 private Matrix matrix = new Matrix(); // 表示用変換Matrix private Image image; // 表示画像 public Form1() { InitializeComponent(); } public double 補間(double H, double Z1, double Z2)// 標高値の比率 { return ((H - Z1) / (Z2 - Z1)); } public void Contour(Graphics g, int j, int k, double H) { double Z0 = Z[j, k] ; double Z1 = Z[j + 1, k]; //メッシュ周囲の4点の標高 double Z2 = Z[j + 1, k + 1]; double Z3 = Z[j, k + 1]; bool P01 = (Z0 > H) ^ (Z1 > H); // メッシュ周囲の辺に該当標高値の有無の判定 bool P12 = (Z1 > H) ^ (Z2 > H); bool P23 = (Z2 > H) ^ (Z3 > H); bool P30 = (Z3 > H) ^ (Z0 > H); if (P01 || P12 || P23 || P30) // メッシュ内に該当標高値があるときのみ表示 { float x0 = 0; float y1 = 0; float x2 = 0; float y3 = 0; Pen pen = new Pen(Color.Black, 0.01F); if (P01) x0 = (float)(dx * (((double)j) + 補間(H, Z0, Z1)));//補間 if (P12) y1 = (float)(dy * (((double)k) + 補間(H, Z1, Z2))); if (P23) x2 = (float)(dx * (((double)j) + 補間(H, Z3, Z2))); if (P30) y3 = (float)(dy * (((double)k) + 補間(H, Z0, Z3))); float yk = (float)(dy * (double)(k)); // メッシュ上辺のY座標 float yk1 = (float)(dy * (double)(k + 1)); // メッシュ上辺のY座標 float xj = (float)(dx * (double)(j)); // メッシュ左辺のX座標 float xj1 = (float)(dx * (double)(j + 1)); // メッシュ右辺のX座標 if (P01 && P12) g.DrawLine(pen, x0, yk, xj1, y1);// 等高線表示 if (P12 && P23) g.DrawLine(pen, xj1, y1, x2, yk1); if (P23 && P30) g.DrawLine(pen, x2, yk1, xj, y3); if (P30 && P01) g.DrawLine(pen, xj, y3, x0, yk); if (P01 && P23) g.DrawLine(pen, x0, yk, x2, yk1); if (P12 && P30) g.DrawLine(pen, xj1, y1, xj, y3); } } public void Contours(Graphics g, double v1, double v2, double dv)// コンタ表示 { for (int j = 0; j < numX - 1; j++) for (int k = 0; k < numY - 1; k++) for (double v = v1; v <= v2; v += dv) Contour(g, j, k, v); } public void ColorMap(Graphics g, double v1, double v2, double dv)//色地図表示 { Color color; float w = (float)dx, h = (float)dy; double DD = (v2 - v1) / 768; for (int j = 0; j < numX - 1; j++) for (int k = 0; k < numY - 1; k++) { float x1 = (float)(dx * j), y1 = (float)(dy * k); int ID = (int)((Z[j, k] - v1) / DD); if (ID < 256) color = Color.FromArgb(0, ID, 0); else if (ID < 512) color = Color.FromArgb(ID - 256, 255, 0); else if (ID < 768) color = Color.FromArgb(255, 767 - ID, 0); else color = Color.FromArgb(255, 0, 0); Brush brush = new SolidBrush(color); g.FillRectangle(brush, x1, y1, w, h); } } public double minZ()// 最低標高値を求める { double R = Z[0, 0]; for (int j = 0; j < numX - 1; j++) for (int k = 0; k < numY - 1; k++) if (Z[j, k] < R) R = Z[j, k]; return R; } public double maxZ()// 最高標高値を求める { double R = Z[0, 0]; for (int j = 0; j < numX - 1; j++) for (int k = 0; k < numY - 1; k++) if (Z[j, k] > R) R = Z[j, k]; return R; } private void 描画() { image = new Bitmap(1000, 1000); Graphics g = Graphics.FromImage(image); g.Clear(this.BackColor); g.Transform = matrix; double V1 = minZ(), V2 = maxZ(); if (Math.Abs(V2 - V1) < 0.0000001) V2 = V1 + 1; ColorMap(g, V1, V2, 0.1); Contours(g, V1, V2, Hstep); } protected override void OnPaint(PaintEventArgs e) { base.OnPaint(e); e.Graphics.DrawImage(image, 0, 0); } private void window(double X1, double Y1, double X2, double Y2) { double W = this.ClientSize.Width, H = this.ClientSize.Height; float SX = (float)(W / (X2 - X1)); float SY = (float)(H / (Y2 - Y1)); matrix.Scale(SX, SY); matrix.Translate(-(float)X1, -(float)Y1); } private void Form1_Load(object sender, System.EventArgs e) { double XX = ((double)numX) * 0.5, YY = ((double)numY) * 0.5; double C = 0.02; Hstep = double.Parse(textBox1.Text); for (int i = 0; i < numX; i++) for (int j = 0; j < numY; j++) { double x = C * ((double)i - XX), y = C * ((double)j - YY); Z[i, j] = (x - y) * Math.Exp(-(x * x + y * y)) * 5000; } window(-20, 240, 220, -50); 描画(); } private void button1_Click(object sender, System.EventArgs e) { openFileDialog1.ShowDialog(); } private string midStr(string DT, int ist, int N) { string S = ""; for (int i = 1, k = ist - 1; i <= N; i++, k++) S += DT[k]; return S; } private void openFileDialog1_FileOk(object sender, System.ComponentModel.CancelEventArgs e) { StreamReader DTS; int ii; string FName = openFileDialog1.FileName;if (FName == "") return; DTS = new StreamReader(FName, System.Text.Encoding.Default); string DT = DTS.ReadLine(); //1行目読み飛ばし DT = DTS.ReadLine(); for (int k = 0; DT != null; k++) { ii = 5; for (int j = 0; j < 200; j++){ii += 5; Z[k, j] = int.Parse(midStr(DT, ii, 5));} DT = DTS.ReadLine(); } DTS.Close(); 描画(); this.Invalidate(); } private void textBox1_TextChanged(object sender, System.EventArgs e) { Hstep = double.Parse(textBox1.Text); } private void button2_Click(object sender, System.EventArgs e) { 描画(); this.Invalidate(); } } }