由坐标数据生成点SHP文件,并由多组点生成线SHP文件(上)
目录
由坐标数据生成点SHP文件,并由多组点生成线SHP文件(上)
在最近的公司项目中,老板要求将外业采集的管线连接点坐标表格数据生成线状的shp文件,上网查了下都是生成点状shp文件的例子,作为一个小白根据例子苦逼摸索了半个星期终于搞定了,放上来和大家分享一下。
实现思路
- 连接Excel表格,将表格中需要的数据生成DataTable
- 获取DataTable中的坐标数据,根据要求获取坐标对
- 创建空的点shp文件,设置属性信息,加载空的点layer
- 编辑点layer的属性信息,添加点要素
- 获取DataTable中的坐标数据,根据要求获取点对
- 创建空的线shp文件,设置属性信息,加载空的线layer
- 编辑线layer的属性信息,添加线要素
实现步骤
1.连接Excel表格,将表格中需要的数据生成DataTable
本项目是基于.NET平台的AE开发,使用的语言为C#。C#读取Excel表格有三种经典的方法,具体大家可以自行百度,这里不再详细介绍,我采用的是通过OleDB读取Excel文件的方法。实例方法如下:
public DataTable ExcelToDataTable(string strExcelFileName, string strSheetName)
{
string strConn="Provider=Microsoft.ACE.OLEDB.12.0;"+"Data Source="+strExcelFileName+";"+"Extended Properties='Excel 8.0;HDR=NO;IMEX=1';";
String strExcel="select * from ["+strSheetName+"$]";
DataSet ds=new DataSet();
OleDbConnection conn=new OleDbConnection(strConn);
conn.Open();
OleDbDataAdapter adapter=new OleDbDataAdapter(strExcel,strConn);
adapter.Fill(ds,strSheetName);
conn.Close();
return ds.Tables[strSheetName];
}
这里有个小地方需要注意一下,Excel的版本不同,源语句的定义也不同,我用的是07以后的版本,如果是97-03的版本应该将部分代码换成
Provider=Microsoft.Jet.OLEDB.4.0;
2.获取DataTable中的坐标数据,根据要求获取坐标对
步骤1中得到的DataTable实质上就是一张二维表,它的格式和Excel表是一样的,我这里的表格数据中一共包含了七项数据,分别是管线起始点的ID,管线起始点代号,管线连接点代号,管线起始点X坐标,管线起始点Y坐标,管线起始点高程,管线起始点埋深,如图:
空格项代表与上一个相同。读取核心代码如下:
Dictionary<string,IPoint> pdic=new Dictionary<string,IPoint>();//建立点与代号的键值对,方便生成线shp时对点的提取
List<int> pCol=new List<int>();//存储点ID的列表
string temp=null;//用于在空格项表示上一管线起始点代号
int idSet=0;//用于设置点的ID
for(int i=1;i<mDataTable.Rows.Count;i++)
{
if(mDataTable.Rows[i][1].ToString()!=temp&&mDataTable.Rows[i][1]!=string.Empty)
{
//提取点的属性信息
string name=mDataTable.Rows[i][1].ToString();
double x=Convert.ToDouble(mDataTable.Rows[i][3]);
double y = Convert.ToDouble(mDataTable.Rows[i][4]);
double ele = Convert.ToDouble(mDataTable.Rows[i][5]);
double d = 0;
if (mDataTable.Rows[i][6].ToString() !=string.Empty)
{
d = Convert.ToDouble(mDataTable.Rows[i][6]);
}
if (Tool.addPoint(pLyrPoint,x,y,name,ele,d,axMapControl1,idSet,pdic))
{
temp = name;
idSet = idSet + 1;
}
}
}
3.创建空的点shp文件,设置属性信息,加载空的点layer
设置属性信息,返回ILayer对象。核心代码如下:
private string defaultPath; //定义默认保存路径
private string fileFullPath; //定义文件全路径
private string fileName; //定义不带后缀的文件名称
private string filePath; //定义文件目录
private IWorkspaceFactory pWsF; //定义工作空间工厂
private IFeatureWorkspace pFeatWs; //定义要素工作空间
private IFeatureClass pFeatCls; //定义要素类
private IDataset pDataset; //定义数据集
private IField pField; //定义字段
private IFields pFields; //定义字段集
private IFieldEdit pFieldEdit; //定义字段编辑
private IFieldsEdit pFieldsEdit; //定义字段集编辑
public ILayer CreatePointShapeFile(string excelPath,AxMapControl axMapControl)
{
SaveFileDialog saveFDlg = new SaveFileDialog();
saveFDlg.Title = "生成点图层";
saveFDlg.Filter = "Shape文件(*.shp)|*.shp";
saveFDlg.CheckFileExists = false;
saveFDlg.FileName = System.IO.Path.GetFileNameWithoutExtension(excelPath);
defaultPath = excelPath.Replace("xls", "shp");
saveFDlg.InitialDirectory = defaultPath;
if (saveFDlg.ShowDialog() == DialogResult.OK)
{
fileFullPath = saveFDlg.FileName;
fileName = System.IO.Path.GetFileNameWithoutExtension(fileFullPath);
filePath = System.IO.Path.GetDirectoryName(fileFullPath);
pWsF = new ShapefileWorkspaceFactory();
if (System.IO.File.Exists(fileFullPath))
{
//如果选择替换同名文件,即先删掉同名文件;否则返回空
if (MessageBox.Show("该文件夹下已经有同名文件,是否替换?", "信息提示", MessageBoxButtons.OKCancel, MessageBoxIcon.Question) == DialogResult.OK)
{
pFeatWs = pWsF.OpenFromFile(filePath, 0) as IFeatureWorkspace;
pFeatCls = pFeatWs.OpenFeatureClass(fileName);
pDataset = pFeatCls as IDataset;
pDataset.Delete();
}
else
return null;
}
}
else
return null;
//Shape字段
pFields=new FieldsClass();
pFieldsEdit=pFields as IFieldsEdit;
pField=new FieldClass();
pFieldEdit=pField as iFieldEdit;
//定义字段信息
pFieldEdit.Name_2="Shape";
pFieldEdit.Type_2=esriFieldType.esriFieldTypeGeometry;
//定义要素形状特征
IGeometryDef pGeoDef=new GeometryDefClass();
IGeometryDefEdit pGeoDefEdit=pGeoDef as IGeometryDefEdit;
pGeoDefEdit.GeometryType_2=esriGeometryType.esriGeometryPoint;
//空间参考设置(这里没有设置空间参考)
//pGeoDefEdit.SpatialReference_2=axMapControl.SpatialReference;
pFieldEdit.GeometryDef_2=pGeoDef;
pFieldsEdit.AddField(pField);//注意这个方法是隐藏的,并不会给出拼写提示
//点号字段
pField=new FieldClass();
pFieldEdit=pField as IFieldEdit;
pFieldEdit.Name_2="点号";
pFieldEdit.Type_2=esriFieldType.esriFieldTypeString;
pFieldEdit.Length_2=50;//length参数是string类型特有的
pFieldsEdit.AddField(pField);
...
pWsF=new ShapefileWorkspaceFactory();
IFeatureWorkspace pFeatWs1=pWsF.OpenFromFile(filePath,0) as IFeatureWorkspace;
int i = fileName.IndexOf(".shp");
if (i == -1)
{
pFeatWs1.CreateFeatureClass(fileName + ".shp", pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
}
else
pFeatWs1.CreateFeatureClass(fileName, pFields, null, null, esriFeatureType.esriFTSimple, "Shape", "");
axMapControl.AddShapeFile(filePath, fileName);
return axMapControl.get_Layer(0);
}
其余字段的编码以此类推,此处省去。
4.编辑点layer的属性信息,添加点要素
核心代码如下:
public static bool addPoint(ILayer pLayer, double x, double y, string name, double elevation, double deep,AxMapControl axMapControl,int id,Dictionary<string,IPoint> pDictionary)
{
if (pLayer==null)
return false;
IFeatureLayer pFeatLyr=pLayer as IFeatureLayer;
IFeatureClass pFeatCls=pFeatLyr.FeatureClass;
IFeatureClassWrite pFeatClsWrite=pFeatCls as IFeatureClassWrite;
IWorkspaceEdit pWorkspaceEdit=(pFeatCls as IDataset).Workspace as IWorkspaceEdit;
pWorkspaceEdit.StartEditing(true);
pWorkspaceEdit.StartEditOperation();
IFeature pFeaure;
IPoint pPoint;
pFeature=pFeatCls.CreateFeature();
IFields pFields=pFeature.Fields;
pFeature.set_Value(pFields.FindField("点号"),name);
pFeature.set_Value(pFields.FindField("地面高程"),elevation);
pFeature.set_Value(pFields.FindField("埋深"),deep);
pPoint = new PointClass();
pPoint.X=x;
pPoint.Y=y;
pFeature.Shape=pPoint;
pFeatClsWrite.WriteFeature(pFeature);
pWorkspaceEdit.StopEditOperation();
pWorkspaceEdit.StopEditing(true);
axMapControl.ActiveView.Refresh();
pPoint.ID = id;
pDictionary.Add(name, pPoint);
return true;
}
转载自:https://blog.csdn.net/u014380270/article/details/54981716