这几天,有小伙伴有这么样的需求。首先为了便于说明,将数据展示出来,能够直观了解要描述的问题。来看一下下面的数据。他有很多条记录数据,其中字段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