zoukankan      html  css  js  c++  java
  • 通过ArcEngine接口建立凸包(一)

    准备步骤:

    1.先要能实现选择点的功能,可以利用矩形选点要素的方法axMapControl1.TrackRectangle()。

    2.要建立凸包,必须有存凸包(线要素)的文件,然后通过下拉框选择这个图层,再在构建凸包的时候把凸包线存进去。

    3.前面的接口声明如下:

            public IPoint qian = new PointClass();
            public IPoint zhong = new PointClass();
            public IPoint hou = new PointClass();
    
            public IPointArray Ymin = new PointArrayClass();
            public IPointArray FirstCos = new PointArrayClass();
            public IPointArray First2Pt = new PointArrayClass();
            public IPointArray LoopPt = new PointArrayClass();
            public IPointArray NextPts = new PointArrayClass();
            public IPointArray NewPts = new PointArrayClass();
            public IPolyline pPolyLine = new PolylineClass();  //这个后来没用到了
            //这个方法是将所选择的点存进IPointArray
    public IPointArray LoadPoint(IArray pIDArray, IGeometry pGeo, IPoint pt, IFeature pFeature, IIdentifyObj pIdObj, IEnumFeature enumFeature) { if (pIDArray != null) { for (int i = 0; i < pIDArray.Count; i++) { pGeo = pFeature.Shape as IGeometry; pt = pFeature.Shape as IPoint; pFeature = enumFeature.Next(); pIdObj = pIDArray.get_Element(i) as IIdentifyObj; LoadPt.Add(pt); } } return LoadPt; }
    //先计算最开始的两个点
                public IPointArray First2Point(IPointArray LoadPt)
                {
                    Ymin.RemoveAll();
                    int p = 0;
                    for (int j = 0; j < LoadPt.Count; j++)
                    {
                        if (LoadPt.Element[p].Y > LoadPt.Element[j].Y)//找出y最小的极限点
                            p = j;
                    }
                    Ymin.Add(LoadPt.Element[p]);//先把第一个点存进来
                    for (int j = 0; j < LoadPt.Count; j++)//再把LoadPt的所有点存进来
                    {
                        IPoint Pt = new PointClass();
                        Pt = LoadPt.get_Element(j);
                        Ymin.Add(Pt);
                    }
                    DeleteRepeatPoint(Ymin);//删除掉重复存的那个点(留9个点)
                    //MessageBox.Show("最下方点是" + Ymin.Element[0].X.ToString("#0.00") + " , " + Ymin.Element[0].Y.ToString("#0.00"));
    
                    FirstCos.RemoveAll();
                    for (int i = 0; i < Ymin.Count; i++)
                    {
                        IPoint Pt = new PointClass();
                        Pt.PutCoords(30000000, Ymin.Element[0].Y);
                        hou = Pt;
                        zhong = Ymin.Element[0];
                        qian = Ymin.Element[i];//下一个点
    
                        //计算余弦值,取最大的余弦值的点就是下一个点(黄石)
                        double c = System.Math.Sqrt((hou.X - zhong.X) * (hou.X - zhong.X) + (hou.Y - zhong.Y) * (hou.Y - zhong.Y));
                        double a = System.Math.Sqrt((qian.X - zhong.X) * (qian.X - zhong.X) + (qian.Y - zhong.Y) * (qian.Y - zhong.Y));
                        double b = System.Math.Sqrt((hou.X - qian.X) * (hou.X - qian.X) + (hou.Y - qian.Y) * (hou.Y - qian.Y));
                        double Cosine = (a * a + c * c - b * b) / (2 * a * c);
                        FirstCos.Add(Ymin.Element[i]);
                        FirstCos.Element[i].M = Cosine;
                    }
                    //下面这个循环是为了删除FirstCos里面的最下方点,因为它的值是NaN
                    for (int j = 0; j < FirstCos.Count; j++)
                    {
                        if (double.IsNaN(FirstCos.Element[j].M))
                            FirstCos.Remove(j);//将最下方点去掉
                    }
    
                    First2Pt.RemoveAll();
                    int m = 0;
                    for (int k = 1; k < FirstCos.Count; k++)
                    {
                        if (FirstCos.Element[m].M < FirstCos.Element[k].M)//找出cos最小的点(黄冈)
                            m = k;
                    }
                    First2Pt.Add(FirstCos.Element[m]);//将这个cos最小的点最先存储进数组中
                    First2Pt.Add(Ymin.Element[0]);//将第一个点存储进数组中
                    for (int j = 0; j < FirstCos.Count; j++)//再把FirstCos的所有点存进来
                    {
                        IPoint Pt = new PointClass();
                        Pt = FirstCos.get_Element(j);
                        First2Pt.Add(Pt);
                    }
                    DeleteRepeatPoint(First2Pt);//删除掉重复存的那个点
                    return First2Pt;
                }

    之后再开始计算第一圈余下的点

    public IPointArray Next(IPointArray First2Pt)
                {
                    LoopPt.RemoveAll();
                    IPointArray NextCos = new PointArrayClass();
                    for (int j = 2; j - 2 < First2Pt.Count; j++)
                    {
                        for (int i = 2; i < First2Pt.Count; i++)
                        {
                            hou = First2Pt.Element[1];
                            zhong = First2Pt.Element[0];
                            qian = First2Pt.Element[i];//下一个点
    
                            //计算余弦值,取最大的余弦值的点就是下一个点(黄石)
                            double c = System.Math.Sqrt((hou.X - zhong.X) * (hou.X - zhong.X) + (hou.Y - zhong.Y) * (hou.Y - zhong.Y));
                            double a = System.Math.Sqrt((qian.X - zhong.X) * (qian.X - zhong.X) + (qian.Y - zhong.Y) * (qian.Y - zhong.Y));
                            double b = System.Math.Sqrt((hou.X - qian.X) * (hou.X - qian.X) + (hou.Y - qian.Y) * (hou.Y - qian.Y));
                            double Cosine = (a * a + c * c - b * b) / (2 * a * c);
                            First2Pt.Element[i].M = Cosine;
                            NextCos.Add(First2Pt.Element[i]);
                        }
    
                        int m = 0;
                        for (int k = 1; k < NextCos.Count; k++)
                        {
                            if (NextCos.Element[m].M > NextCos.Element[k].M)//找出cos最小的点
                                m = k;
                        }
                        NextPts.Add(NextCos.Element[m]);
                        for (int k = 0; k < First2Pt.Count; k++)//再把First2Pt的所有点存进来
                        {
                            IPoint Pt = new PointClass();
                            Pt = First2Pt.get_Element(k);
                            NextPts.Add(Pt);
                        }
                        DeleteRepeatPoint(NextPts);
    
                        LoopPt.Add(NextCos.Element[m]);
                        First2Pt.RemoveAll();//重新装下一次循环要用的First2Pt
                        for (int k = 0; k < NextPts.Count; k++)//再把NextPts的所有点给First2Pt(此时点顺序已经变了)
                        {
                            IPoint Pt = new PointClass();
                            Pt = NextPts.get_Element(k);
                            First2Pt.Add(Pt);
                        }
                        NextCos.RemoveAll();
                        NextPts.RemoveAll();
                    }
                    DeleteRepeatPoint(LoopPt);//删除掉重复存的那个点
                    LoopPt.Add(LoopPt.Element[0]);
                    //下面代码是测试这一步的结果
                    //ArrayList mesPt = new ArrayList();
                    //for (int i = 0; i < LoopPt.Count; i++)
                    //{
                    //    mesPt.Add(LoopPt.Element[i].X.ToString("#0.00") + " , " + LoopPt.Element[i].Y.ToString("#0.00"));
                    //}
                    //string str = string.Join(";\n", (string[])mesPt.ToArray(typeof(string)));
                    //MessageBox.Show("凸包点包括:\n" + str);
    
                    return LoopPt;
                }
  • 相关阅读:
    HERO 3
    office的一些应用,
    网页之间的参数传弟
    一个好的数码网站
    C++遍历中删除std::hash_map元素问题
    【转】Asio与shared_ptr的一些注意事项
    delphi的字节对齐
    paypal的即时付款通知参数列表(PDT)
    vs2010下libevent的使用
    mysql 数据库 left join,right join, inner join 知识
  • 原文地址:https://www.cnblogs.com/huangyanjia/p/7635604.html
Copyright © 2011-2022 走看看