由坐标数据生成点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

You may also like...