2024年测绘程序设计比赛--空间探索性分析(数据为2025年第三次模拟数据)
想要在2026年参加这个比赛的,可以加入小编和其它大佬所建的群242845175一起来备赛,为2026年的比赛打基础,也可以私信小编,为你答疑解惑
一、读写文件
internal class Read
{public static List<Point> pts = new List<Point>();public static List<Point> Readfile(string filename){string str;StreamReader sr = new StreamReader(filename);sr.ReadLine();while(!sr.EndOfStream){str=sr.ReadLine();string[]Buf=str.Split(new char[]{','},StringSplitOptions.RemoveEmptyEntries);Point pt = new Point(Buf[0], double.Parse(Buf[1]), double.Parse(Buf[2]), double.Parse(Buf[3]));pts.Add(pt);}return pts;}public static void Savefile(string report){SaveFileDialog sf= new SaveFileDialog();sf.Filter = "文本数据|*.txt";sf.Title = "选择保存路径";sf.FileName = "result";if(sf.ShowDialog() == DialogResult.OK){StreamWriter sw=new StreamWriter(sf.FileName);sw.Write(report);sw.Flush();}}
}
二、数据预处理(分组,数据统计)
public static List<List<Point>> ptcode = new List<List<Point>>();
public static List<Point> ptt = Read.pts.OrderBy(p => p.area).ToList();//将每个不同区域的点进行分组public static void Classify()
{double n = 0;List<Point> points = new List<Point>();foreach(Point p in ptt){if (p.area != n){n = p.area;points=new List<Point>();ptcode.Add(points);}points.Add(p);}
}//计算平均中心
public static void Averge(out double avx,out double avy)
{double sumx = Read.pts.Sum(p => p.x);double sumy = Read.pts.Sum(p => p.y);avx = sumx / Read.pts.Count;avy = sumy / Read.pts.Count;
}
三、标准差椭圆计算
//计算每个点的标准差
public static void Allcha()
{Averge(out double avx, out double avy);foreach(Point p in Read.pts){p.a = p.x - avx;p.b = p.y - avy;}
}//计算辅助量
public static void Helpword(out double A,out double B,out double C)
{A = 0;B = 0;C = 0;double sumab = 0;double sumA = 0;double sumB = 0;foreach(Point p in Read.pts){sumA += p.a * p.a;sumB += p.b * p.b;sumab += p.a * p.b;}A=sumA-sumB;B=Math.Sqrt(A*A+4*sumab*sumab);C=2*sumab;
}//计算椭圆量
public static void Sdsigema(out double sigema,out double SDEx,out double SDEy)
{sigema = 0;SDEx = 0;SDEy = 0;Helpword(out double A, out double B, out double C);sigema = Math.Atan((A + B) / C);double sumn = 0;double summ = 0;foreach(Point p in Read.pts){sumn += (p.a * Math.Cos(sigema) + p.b * Math.Sin(sigema))* (p.a * Math.Cos(sigema) + p.b * Math.Sin(sigema));summ+= (p.a * Math.Sin(sigema) - p.b * Math.Cos(sigema)) * (p.a * Math.Sin(sigema) - p.b * Math.Cos(sigema));}SDEx=Math.Sqrt(2*sumn/Read.pts.Count);SDEy= Math.Sqrt(2 * summ / Read.pts.Count);
}
四、空间矩阵计算
注意公式(5)中的公式有些问题,其分子应为1而非1000,否则与下面答案无法对应
//计算各区的平均中心
public static void Avcenter(List<Point> pts,out double X,out double Y)
{double sumx=pts.Sum(p => p.x);double sumy = pts.Sum(p => p.y);X=sumx/pts.Count;Y=sumy/pts.Count;
}//计算各区之间的空间权重矩阵
public static void Weight(int a,int b,out double weight)
{Avcenter(ptcode[a-1], out double Xa, out double Ya);Avcenter(ptcode[b - 1], out double Xb, out double Yb);if (a == b){weight = 0;}else { weight = 1 / Math.Sqrt((Xa - Xb) * (Xa - Xb) + (Ya - Yb) * (Ya - Yb)); }}
五、莫兰指数计算
//计算各区之间的空间权重矩阵
public static void Weight(int a,int b,out double weight)
{Avcenter(ptcode[a-1], out double Xa, out double Ya);Avcenter(ptcode[b - 1], out double Xb, out double Yb);if (a == b){weight = 0;}else { weight = 1 / Math.Sqrt((Xa - Xb) * (Xa - Xb) + (Ya - Yb) * (Ya - Yb)); }}//计算全局莫兰指数
public static void Allmoulan(out double avX, out double I, out double S)
{S = 0;I = 0;avX = (double)Read.pts.Count / (double)ptcode.Count;for (int i = 1; i <= ptcode.Count; i++){for (int j = 1; j <= ptcode.Count; j++){Weight(i, j, out double weight);S += weight;}}double suma = 0;for (int i = 0; i < ptcode.Count; i++){suma += (ptcode[i].Count - avX) * (ptcode[i].Count - avX);}double sumb = 0;for (int i = 0; i < ptcode.Count; i++){for(int j=0; j < ptcode.Count; j++){Weight(i+1, j+1, out double weight);sumb += weight * (ptcode[i].Count-avX)* (ptcode[j].Count - avX);}}I = (7.0 / S) * (sumb / suma);}
//计算局部莫兰指数
public static void Portmolan(int i,out double Ii,out double Si)
{Allmoulan(out double avX, out double I, out double S);double suma = 0;double sumb = 0;for(int j = 0; j < 7; j++){if ((j+1) == i){continue;}Weight(i, j + 1, out double weight);suma += weight * (ptcode[j ].Count - avX);sumb += (ptcode[j].Count - avX) * (ptcode[j ].Count - avX);}Si = sumb / 6.0;Ii = ((ptcode[i - 1].Count - avX) / Si) * suma;
}
//计算局部莫兰指数Z得分
public static void Portpoint(out double miu,out double sigema)
{double sumi = 0;for(int i=1; i <= 7; i++){Portmolan(i, out double Ii, out double Si);sumi += Ii;}miu = sumi / 7;double sums = 0;for (int i = 1; i <= 7; i++){Portmolan(i, out double Ii, out double Si);sums += (Ii - miu) * (Ii - miu);}sigema=Math.Sqrt(sums/6.0);}//计算莫兰指数得分
public static void Molan(int i,out double Zi)
{Portmolan( i, out double Ii, out double Si);Portpoint(out double miu, out double sigema);Zi = (Ii - miu) / sigema;
}
六、点的属性
public class Point
{public string name;public double x;public double y;public double area;public double a;public double b;public Point(string name, double x, double y, double area){this.name = name;this.x = x;this.y = y;this.area = area;}public override string ToString(){StringBuilder sb = new StringBuilder();sb.Append(name+" "+x.ToString()+" "+y.ToString()+" "+area.ToString());return sb.ToString();}
}
七、页面交互
public Form1()
{InitializeComponent();openFile.FileOk += openFile_FileOk;
}
public static List<Point> before=new List<Point>();
public string report = null;private void toolStripLabel1_Click(object sender, EventArgs e)
{if (openFile.ShowDialog() == DialogResult.OK){string name=openFile.FileName;before=Read.Readfile(name);dataGridView1.RowCount = before.Count;for(int i = 0; i < before.Count; i++){dataGridView1[0, i].Value = before[i].name;dataGridView1[1, i].Value = before[i].x;dataGridView1[2, i].Value = before[i].y;dataGridView1[3, i].Value = before[i].area;}}
}private void openFile_FileOk(object sender, CancelEventArgs e)
{}private void toolStripLabel2_Click(object sender, EventArgs e)
{report += "1 P6 的坐标 x" + before[5].x.ToString("F3") + "\n";report += "2 P6 的坐标 y " + before[5].y.ToString("F3") + "\n";report += "3 P6 的区号" + before[5].area + "\n";Alspace.Classify();report += "4 1 区(区号为 1)的事件数量 n1 " + Alspace.ptcode[0].Count+"\n";report += "5 4 区(区号为 4)的事件数量 n4 " + Alspace.ptcode[3].Count + "\n";report += "6 6 区(区号为 6)的事件数量 n6 " + Alspace.ptcode[5].Count + "\n";report += "7 事件总数 n" + before.Count+"\n";Alspace.Averge(out double avx, out double avy);report += "8 坐标分量 x 的平均值 X" + avx.ToString("F3") + "\n";report += "9 坐标分量 y 的平均值Y " + avy.ToString("F3") + "\n";Alspace.Allcha();report += "10 P6 坐标分量与平均中心之间的偏移量 a6 " + Read.pts[5].a.ToString("F3") + "\n";report += "11 P6 坐标分量与平均中心之间的偏移量 b6 " + Read.pts[5].b.ToString("F3") + "\n";Alspace.Helpword(out double A, out double B, out double C);report += "12 辅助量 A " + A.ToString("F3") + "\n";report += "13 辅助量 B " + B.ToString("F3") + "\n";report += "14 辅助量 C " + C.ToString("F3") + "\n";Alspace.Sdsigema(out double sigema, out double SDEx, out double SDEy);report += "15 标准差椭圆长轴与竖直方向的夹角�" + sigema.ToString("F3") + "\n";report += "16 标准差椭圆的长半轴" + SDEx.ToString("F3") + "\n";report += "17 标准差椭圆的短半轴" + SDEy.ToString("F3") + "\n";Alspace.Avcenter(Alspace.ptcode[0], out double x1, out double y1);Alspace.Avcenter(Alspace.ptcode[3], out double x4, out double y4);report += "18 1 区平均中心的坐标分量 X" + x1.ToString("F3") + "\n";report += "19 1 区平均中心的坐标分量 Y" + y1.ToString("F3") + "\n";report += "20 4 区平均中心的坐标分量 X" + x4.ToString("F3") + "\n";report += "21 4 区平均中心的坐标分量 Y" + y4.ToString("F3") + "\n";Alspace.Weight(1, 4, out double w14);Alspace.Weight(6, 7, out double w67);report += "22 1 区和 4 区的空间权重w1,4 " + w14.ToString("F6") + "\n";report += "23 6 区和 7 区的空间权重w6,7 " + w67.ToString("F6") + "\n";Alspace.Allmoulan(out double avX, out double I, out double S);report += "24 研究区域犯罪事件的平均值�" + avX.ToString("F6") + "\n";report += "25 全局莫兰指数辅助量" + S.ToString("F6") + "\n";report += "26 全局莫兰指数" + I.ToString("F6") + "\n";Alspace.Portmolan(1,out double I1,out double S1);Alspace.Portmolan(3, out double I3, out double S3);Alspace.Portmolan(5, out double I5, out double S5);Alspace.Portmolan(7, out double I7, out double S7);report += "27 1 区的局部莫兰指数" + I1.ToString("F6") + "\n";report += "28 3 区的局部莫兰指数" + I3.ToString("F6") + "\n";report += "29 5 区的局部莫兰指数" + I5.ToString("F6") + "\n";report += "30 7 区的局部莫兰指数" + I7.ToString("F6") + "\n";Alspace.Portpoint(out double miu, out double sigemaa);report += "31 局部莫兰指数的平均数" + miu.ToString("F6") + "\n";report += "32 局部莫兰指数的标准差" + sigema.ToString("F6") + "\n";Alspace.Molan(1, out double Z1);Alspace.Molan(3, out double Z3);Alspace.Molan(5, out double Z5);Alspace.Molan(7, out double Z7);report += "33 1 区局部莫兰指数的 Z 得分" + Z1.ToString("F6") + "\n";report += "34 3 区局部莫兰指数的 Z 得分" + Z3.ToString("F6") + "\n";report += "35 5 区局部莫兰指数的 Z 得分" + Z5.ToString("F6") + "\n";report += "36 7 区局部莫兰指数的 Z 得分" + Z7.ToString("F6") + "\n";richTextBox1.Text = report;}private void toolStripLabel3_Click(object sender, EventArgs e)
{Read.Savefile(report);
}
八、页面布局
九、结果
1 P6 的坐标 x92295.323
2 P6 的坐标 y 100520.233
3 P6 的区号4
4 1 区(区号为 1)的事件数量 n1 1408
5 4 区(区号为 4)的事件数量 n4 288
6 6 区(区号为 6)的事件数量 n6 744
7 事件总数 n7754
8 坐标分量 x 的平均值 X95635.466
9 坐标分量 y 的平均值Y 97175.589
10 P6 坐标分量与平均中心之间的偏移量 a6 -3340.143
11 P6 坐标分量与平均中心之间的偏移量 b6 3344.644
12 辅助量 A -501728394.420
13 辅助量 B 60614732934.584
14 辅助量 C -60612656412.248
15 标准差椭圆长轴与竖直方向的夹角 -0.781
16 标准差椭圆的长半轴3954.899
17 标准差椭圆的短半轴94.495
18 1 区平均中心的坐标分量 X95577.112
19 1 区平均中心的坐标分量 Y97233.212
20 4 区平均中心的坐标分量 X95554.001
21 4 区平均中心的坐标分量 Y97263.180
22 1 区和 4 区的空间权重w1,4 0.026424
23 6 区和 7 区的空间权重w6,7 0.003706
24 研究区域犯罪事件的平均值 1107.714286
25 全局莫兰指数辅助量1.019281
26 全局莫兰指数-0.031250
27 1 区的局部莫兰指数-0.046333
28 3 区的局部莫兰指数0.016573
29 5 区的局部莫兰指数0.025204
30 7 区的局部莫兰指数0.026354
31 局部莫兰指数的平均数-0.002412
32 局部莫兰指数的标准差-0.781259
33 1 区局部莫兰指数的 Z 得分-1.360401
34 3 区局部莫兰指数的 Z 得分0.588010
35 5 区局部莫兰指数的 Z 得分0.855335
36 7 区局部莫兰指数的 Z 得分0.890957