2024年测绘程序设计比赛--空间探索性分析(数据为2025年第三次模拟数据)

发布于:2025-08-08 ⋅ 阅读:(15) ⋅ 点赞:(0)

想要在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


网站公告

今日签到

点亮在社区的每一天
去签到