ArcGIS开发&基于Apose.Cells的分类统计表格属性值

这几天,有小伙伴有这么样的需求。首先为了便于说明,将数据展示出来,能够直观了解要描述的问题。来看一下下面的数据。他有很多条记录数据,其中字段INPUT_FID按照一大类进行标记,比如0为一类,1为一类,依次类推。然后现在要求出,每一类中对应字段DISTANCE的最小值的记录,不知道我的描述够清楚了没。就好像,我们现在有很多个班级,在一次考试中,我们要找出每一班中,语文成绩最低的那位同学。

那么我们现在要怎么解决这个问题呢。一开始,给我是准备使用arcpy去操作这些数据的,但是发现,这个小伙伴给我的数据并不是完整的shapefile格式,因为给我的数据只有一个.dbf格式文件,于是后面转用了C#来实现了。首先得将数据转为excel,然后使用apose.cells来操作excel了。具体的算法是,利用C#的dictionary来保存我们INPUT_FID值,对每一条记录进行判断,如果我们的Dictionary中已经存在了某个INPUT_FID值,那么我们只需要取保存的最小值来与当前的记录最小值来比对,如果当然记录最小值比Dictionary中的值小,那么将已经存在的Dictionary的最小值给删掉,重新将当然的最小值给放入到Dictionary中,如果当前记录的最小值大于保存在Dictionary中那么就不做存入操作。依次同时使用另外一个Dictionary来保存当然的记录,因为我们需要记录的其他字段信息,所以这里特意设计一个Datainfo类来对应每一个字段。

好了,我们来看一下。设计的Dtainfo类,对应了每一字段。

using System;
using System.Collections.Generic;
using System.Text;

namespace GetCollect
{
    class DataInfo
    {
        private string oid;/*OID*/

        public string Oid
        {
            get { return oid; }
            set { oid = value; }
        }
        private string objectid;/*OBJECTID*/

        public string Objectid
        {
            get { return objectid; }
            set { objectid = value; }
        }


        private string input_fid;/*INPUT_FID*/

        public string Input_fid
        {
            get { return input_fid; }
            set { input_fid = value; }
        }
        private string near_fid; /*NEAR_FID*/

        public string Near_fid
        {
            get { return near_fid; }
            set { near_fid = value; }
        }
        private string distace; /*DISTANCE*/

        public string Distace
        {
            get { return distace; }
            set { distace = value; }
        }

        public DataInfo() { }
        public DataInfo(string oid, string objectid, string input_fid, string near_fid, string distace)
        {
            Oid = oid;
            Objectid = objectid;
            Input_fid = input_fid;
            Near_fid = near_fid;
            Distace = distace;

        }



    }
}

再来看一下处理的代码实现,这里设计一简单的winform框。有两个按钮,一个是读入excel数据,另外一个是出来设计的,而一个TextBox则是显示我们读入的excel路径。做出来的程序如下图所示。

最后的实现代码如下所示:

using System;
using System.Collections.Generic;

using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Aspose.Cells;
using System.IO;

namespace GetCollect
{
    public partial class Form1 : Form
    {
        private String fileName = "";
        List<DataInfo> listExcelInfos = new List<DataInfo>();
        public Form1()
        {
            InitializeComponent();
        }

        private void BTN_OPEN_Click(object sender, EventArgs e)
        {
            OpenFileDialog file = new OpenFileDialog();
            file.Filter = "Excel(*.xlsx)|*.xlsx|Excel(*.xls)|*.xls";
            file.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
            file.Multiselect = false;
 
            if (file.ShowDialog() == DialogResult.Cancel)
            {
                return;
            }
 
            String path = file.FileName;
            string fileSuffix = System.IO.Path.GetExtension(path);
 
            if (string.IsNullOrEmpty(fileSuffix))
            {
                System.Windows.Forms.MessageBox.Show("文件没有后缀");
                return;
            }
 
            fileName = path;
            this.TB_PATH.Text = fileName;


        }

        private void BTN_RUN_Click(object sender, EventArgs e)
        {
            Workbook workbook = new Workbook();
            workbook.Open(fileName);
            
            Cells cells = workbook.Worksheets[0].Cells;

            int maxColum = cells.MaxColumn;
            int maxRow = cells.MaxRow;
            listExcelInfos.Clear();

            for (int row = 0; row <= maxRow; row++)
            {
                DataInfo dataInfo = new DataInfo();
                for (int colum = 0; colum <= maxColum; colum++)
                {

                    Cell cell = cells[row, colum];
                    string StrValue = cell.StringValue.Trim();
                    if (colum == 0)
                    {
                        dataInfo.Objectid = StrValue;
                    }else if(colum == 1){
                        dataInfo.Input_fid = StrValue;
                    }else if(colum == 2){
                        dataInfo.Near_fid = StrValue;
                    }
                    else if (colum == 3)
                    {
                        dataInfo.Distace = StrValue;
                    }
                }
                listExcelInfos.Add(dataInfo);
            }

           Dictionary<string, DataInfo> res=  dealProcess(listExcelInfos);

           if (ExtInfosToTable(res))
            {
                System.Windows.Forms.MessageBox.Show("处理成功");
            }
            else {
                System.Windows.Forms.MessageBox.Show("处理失败");
            }




        }

        private bool ExtInfosToTable(Dictionary<string, DataInfo> tmpDic)
        {
            bool isSuc = false;
            try
            {
                /*创建工作薄*/
                Workbook wb = new Workbook();
                /*创建样式*/
                Style style = wb.Styles[wb.Styles.Add()];
                /*设置单元格水平居中对齐和垂直居中对齐*/
                style.HorizontalAlignment = Aspose.Cells.TextAlignmentType.Center;
                /*新建工作表*/
                Worksheet ws = wb.Worksheets[0];
                /*第一条用来标记表头*/
                int row = 1;

               
                ws.Cells[0, 0].PutValue("Objectid");
                ws.Cells[0, 1].PutValue("Input_fid");
                ws.Cells[0, 2].PutValue("Near_fid");
                ws.Cells[0, 3].PutValue("Distace");

                foreach (KeyValuePair<string, DataInfo> kv in tmpDic)
                {
                    string key = kv.Key;
                    DataInfo tmpList = tmpDic[key];
                    ws.Cells[row, 0].PutValue(tmpList.Objectid);
                    ws.Cells[row, 1].PutValue(tmpList.Input_fid);
                    ws.Cells[row, 2].PutValue(tmpList.Near_fid);
                    ws.Cells[row, 3].PutValue(tmpList.Distace);
                   
                    row++;

                }
                    
                /*设置所有列为自适应列宽*/
                ws.AutoFitColumns();
                string path = GetAssemblyPath();
                string filePath = System.IO.Path.Combine(path, "result.xls");
                if (System.IO.File.Exists(filePath))
                {
                    System.IO.File.Delete(filePath);
                }
                FileStream fs = System.IO.File.Create(filePath);
                fs.Close();
                wb.Save(filePath);
                isSuc = true;
 
            }
            catch (Exception e)
            {
 
                isSuc = false;
            }
            return isSuc;
        
        }




        /// <summary>
        /// 返回处理后的数据
        /// </summary>
        /// <param name="listExcelInfos"></param>
        /// <returns></returns>
        private Dictionary<string, DataInfo> dealProcess(List<DataInfo> listExcelInfos)
        {
            Dictionary<string, DataInfo> dic = new Dictionary<string, DataInfo>();

            Dictionary<string, double> tmpDIC = new Dictionary<string, double>();
            for (int i = 0; i < listExcelInfos.Count; i++)
            {
                double minValue = 0;
                DataInfo tDataInfo=listExcelInfos[i];
                if (!tmpDIC.ContainsKey(tDataInfo.Input_fid))
                {
                    minValue = getNUM(tDataInfo.Distace);
                    tmpDIC.Add(tDataInfo.Input_fid, minValue);
                    dic.Add(tDataInfo.Input_fid, tDataInfo);
                }
                else if (tmpDIC.ContainsKey(tDataInfo.Input_fid))
                {
                    minValue = getNUM(tDataInfo.Distace);
                    double tminValue = tmpDIC[tDataInfo.Input_fid];
                    if (minValue < tminValue)
                    {
                        tmpDIC.Remove(tDataInfo.Input_fid);
                        dic.Remove(tDataInfo.Input_fid);

                        tmpDIC.Add(tDataInfo.Input_fid, minValue);
                        dic.Add(tDataInfo.Input_fid, tDataInfo);

                    }
                }

            }
            return dic;
        }

         private double getNUM(string str_num) {
 
            double res = 0;
            try
            {
               res= double.Parse(str_num);
               return res;
            }
            catch (Exception e)
            {
                System.Console.WriteLine(e.ToString());
                
            }
            return res;
        }

         private string GetAssemblyPath()
        {
            string CodeBasePath = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
            CodeBasePath = CodeBasePath.Substring(8, CodeBasePath.Length - 8);
            string[] arrSection = CodeBasePath.Split(new char[] { '/' });
            string FolderPath = "";
            for (int i = 0; i < arrSection.Length - 1; i++)
            {
                FolderPath += arrSection[i] + "\\";
            }
 
            return FolderPath;
        }

    }
}

结尾,我们来看一下、我们的统计结果。



                            更多内容,请微信扫二维码关注公众号,或者加入arcpy开发qq学习群:487352121

                                                                       

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yGIS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值