ArcMap中的空间连接空间,会产生新的要素类,使用该工具,工作中,如果一个生产的数据图层需要去多个图层去获取某些属性,则需要多次空间连接,并产生多个中间结果,且空间连接前后,如果存在字段名称一样的情况,被连接的字段会自动改名,并附加到连接的数据集的后面,工作中,往往需要将通过字段计算器将该字段的内容计算到前一个字段中。
空间连接工具功能界面如下,主要实现将连接图层的字段附加至源图层,而不产生中间成果,同时,支持多要素处理,可以选择只保留一个以及综合,对于源图层已经存在的字段,可以通过选择,实现直接写入已有字段,或者是写入一个新的字段。
下面介绍一下上述功能的实现方式。
一、界面
界面按照上述样式绘制,主要实现对ArcMap中图层数据的获取,以及操作参数的配置。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using GISCommonHelper;
namespace DayDreamInGISTool.SpatialJoin
{
public partial class frmSJSet : Form
{
public frmSJSet()
{
InitializeComponent();
pMap = ArcMap.Document.FocusMap;
}
private IMap pMap;
List<GISCommonHelper.Name_AliasName> fdList;
private List<string> fields_list = new List<string>();
/// <summary>
/// 选定的连接字段
/// </summary>
public List<string> Fields_list
{
get { return fields_list; }
set { fields_list = value; }
}
/// <summary>
/// 源图层
/// </summary>
private IFeatureLayer pSourceFtlyr;
public IFeatureLayer PSourceFtlyr
{
get { return pSourceFtlyr; }
set { pSourceFtlyr = value; }
}
/// <summary>
/// 待连接图层
/// </summary>
private IFeatureLayer pJoinedFtLyr;
public IFeatureLayer PJoinedFtLyr
{
get { return pJoinedFtLyr; }
set { pJoinedFtLyr = value; }
}
private bool b_summary;
/// <summary>
/// 是否综合
/// </summary>
public bool B_summary
{
get { return b_summary; }
set { b_summary = value; }
}
/// <summary>
/// 如果连接字段已经存在,值是否写入原字段
/// </summary>
private bool b_old;
public bool B_old
{
get { return b_old; }
set { b_old = value; }
}
private void frmSJSet_Load(object sender, EventArgs e)
{
pMap = ArcMap.Document.FocusMap;
CartoLyrHelper.setFeatureLyrCombox(ref cmbSource, pMap, esriGeometryType.esriGeometryAny, false);
CartoLyrHelper.setFeatureLyrCombox(ref cmbJoinedLyr, pMap, esriGeometryType.esriGeometryAny, false);
}
private void cmbJoinedLyr_SelectedIndexChanged(object sender, EventArgs e)
{
listView1.Items.Clear();
if (cmbJoinedLyr.SelectedIndex != -1)
{
pJoinedFtLyr = cmbJoinedLyr.SelectedValue as IFeatureLayer;
listView1.CheckBoxes = true;
fdList = GISCommonHelper.CartoFieldHelper.getLyrFields(pJoinedFtLyr.FeatureClass.Fields,esriFieldType.esriFieldTypeDate,esriFieldType.esriFieldTypeDouble,esriFieldType.esriFieldTypeInteger,esriFieldType.esriFieldTypeSingle,esriFieldType.esriFieldTypeSmallInteger,esriFieldType.esriFieldTypeString);
for (int i = 0; i < fdList.Count; i++)
{
ListViewItem lvi = new ListViewItem(fdList[i].alias_name);
listView1.Items.Add(lvi);
}
}
}
private void btnAll_Click(object sender, EventArgs e)
{
listView1.BeginUpdate();
//全选
for (int i = 0; i < listView1.Items.Count; i++)
{
ListViewItem lvi = listView1.Items[i];
lvi.Checked = true;
}
listView1.EndUpdate();
}
private void btnClear_Click(object sender, EventArgs e)
{
listView1.BeginUpdate();
//全不选
for (int i = 0; i < listView1.Items.Count; i++)
{
ListViewItem lvi = listView1.Items[i];
lvi.Checked = false;
}
listView1.EndUpdate();
}
private void btnInverse_Click(object sender, EventArgs e)
{
listView1.BeginUpdate();
//反选
for (int i = 0; i < listView1.Items.Count; i++)
{
ListViewItem lvi = listView1.Items[i];
lvi.Checked = !lvi.Checked;
}
listView1.EndUpdate();
}
private void btnOk_Click(object sender, EventArgs e)
{
fields_list = new List<string>();
if (rdbNew.Checked)
b_old = false;
else
b_old = true;
if (rbdOnly.Checked)
{
b_summary = false;
}
else
b_summary = true;
if (cmbJoinedLyr.SelectedIndex != -1)
{
pJoinedFtLyr = cmbJoinedLyr.SelectedValue as IFeatureLayer;
}
else { return; }
if (cmbSource.SelectedIndex != -1)
{
pSourceFtlyr = cmbSource.SelectedValue as IFeatureLayer;
}
else return;
for (int i = 0; i < listView1.Items.Count;i++ )
{
ListViewItem lvi = listView1.Items[i];
if (lvi.Checked)
{
fields_list.Add(fdList[i].name);
}
}
this.DialogResult = DialogResult.OK;
}
private void btnCancel_Click(object sender, EventArgs e)
{
this.DialogResult = DialogResult.Cancel;
}
}
}
上述代码涉及到Name_AliasName类,name_layer类,此二类主要用于Combox等控件DataSource绑定使用。
/// <summary>
/// 字段名与假名
/// </summary>
public class Name_AliasName
{
public string name { get; set; }
public string alias_name { get; set; }
public Name_AliasName(string name,string alias_name)
{
this.name = name;
if (string.IsNullOrEmpty(this.alias_name))
{
this.alias_name = alias_name;
}
else
{
this.alias_name = name;
}
}
}
/// <summary>
/// 图层名与图层
/// </summary>
public class name_Layer{
public string name { get; set; }
public ILayer layer { get; set; }
public Guid id { get; set; }
public name_Layer(string name,ILayer layer){
this.name=name;
this.layer=layer;
this.id = Guid.NewGuid();
}
}
涉及到CartoFieldHelper类,该类主要实现将ArcMap中要素图层绑定至Combox中,以供用户进行点击选择
/// <summary>
/// 图层辅助类
/// </summary>
public class CartoLyrHelper
{
#region 设置要素图层Combox
/// <summary>
/// 设置要素图层Combox
/// </summary>
/// <param name="cmb"></param>
/// <param name="pMap"></param>
/// <param name="tp"></param>
/// <param name="nl">默认选中的图层</param>
/// <param name="useBlank"></param>
/// <returns></returns>
public static List<name_Layer> setFeatureLyrCombox(ref ComboBox cmb, IMap pMap, esriGeometryType tp,name_Layer nl,bool useBlank = false)
{
List<name_Layer> lyrlist = setFeatureLyrCombox(ref cmb, pMap, tp, useBlank);
for (int i = 0; i < cmb.Items.Count; i++)
{
name_Layer nltmp = cmb.Items[i] as name_Layer;
if (nltmp.id == nl.id)
{
cmb.SelectedIndex = i;
break;
}
}
return lyrlist;
}
/// <summary>
/// 设置图要素层Combox
/// </summary>
/// <param name="cmb"></param>
/// <param name="pMap"></param>
/// <param name="tp">几何类型</param>
/// <param name="useBlank">使用默认的空白项</param>
/// <returns></returns>
public static List<name_Layer> setFeatureLyrCombox(ref ComboBox cmb, IMap pMap,esriGeometryType tp,bool useBlank=false)
{
cmb.DisplayMember = "name";
cmb.ValueMember = "layer";
List<name_Layer> lyrlist = new List<name_Layer>();
if (useBlank)
{
name_Layer nl = new name_Layer("", null);
lyrlist.Insert(0, nl);
}
getAllFtlyr(ref lyrlist, pMap,tp);
cmb.DataSource = lyrlist;
cmb.DropDownStyle = ComboBoxStyle.DropDownList;
cmb.SelectedIndex = -1;
return lyrlist;
}
#endregion
#region 设置图层Combox
public static List<name_Layer> setLyrCombox<T>(ref ComboBox cmb, IMap pMap,name_Layer nl, bool useBlank)
{
List<name_Layer> nllist = setLyrCombox<T>(ref cmb, pMap, useBlank);
for (int i = 0; i < cmb.Items.Count; i++)
{
name_Layer nlTmp = cmb.Items[i] as name_Layer;
if (nlTmp.id == nl.id)
{
cmb.SelectedIndex = i;
break;
}
}
return nllist;
}
/// <summary>
/// 设置图层Combox
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="cmb"></param>
/// <param name="pMap"></param>
/// <returns></returns>
public static List<name_Layer> setLyrCombox<T>(ref ComboBox cmb,IMap pMap,bool useBlank=false)
{
cmb.DisplayMember = "name";
cmb.ValueMember = "layer";
List<name_Layer> lyrlist = new List<name_Layer>();
if (useBlank)
{
name_Layer nl = new name_Layer("", null);
lyrlist.Insert(0, nl);
}
getAllLayer<T>(ref lyrlist, pMap);
cmb.DataSource = lyrlist;
cmb.DropDownStyle = ComboBoxStyle.DropDownList;
cmb.SelectedIndex = -1;
return lyrlist;
}
#endregion
#region 获取所有图层
public static List<T> getAllLayer<T>(IMap pMap)
{
List<name_Layer> nllist = new List<name_Layer>();
getAllLayer<T>(ref nllist, pMap);
List<T> lyrlist = new List<T>();
for (int i = 0; i < nllist.Count; i++)
{
lyrlist.Add((T)nllist[i].layer);
}
return lyrlist;
}
#endregion
#region 获取所有图层集合,适用于Combox
/// <summary>
/// 获取图层集合,适用于combox
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="nllist"></param>
/// <param name="pMap"></param>
public static void getAllLayer<T>(ref List<name_Layer> nllist, IMap pMap)
{
for (int i = 0; i < pMap.LayerCount; i++)
{
ILayer plyr = pMap.get_Layer(i);
if (plyr is T)
{
nllist.Add(new name_Layer(plyr.Name, plyr));
}
else if (plyr is IGroupLayer)
{
getGroupLayer<T>(ref nllist, (IGroupLayer)plyr);
}
}
}
#endregion
#region 获取所有要素图层
/// <summary>
/// 获取所有要素图层
/// </summary>
/// <param name="nllist"></param>
/// <param name="pMap"></param>
/// <param name="tp"></param>
public static void getAllFtlyr(ref List<name_Layer> nllist, IMap pMap, ESRI.ArcGIS.Geometry.esriGeometryType tp)
{
for (int i = 0; i < pMap.LayerCount; i++)
{
ILayer plyr = pMap.get_Layer(i);
if (plyr is IFeatureLayer)
{
if (((IFeatureLayer)plyr).FeatureClass != null) //避免图层感叹号时,可能存在的问题
{
if (tp == esriGeometryType.esriGeometryAny)
{
nllist.Add(new name_Layer(plyr.Name, plyr));
}
else
{
if (((IFeatureLayer)plyr).FeatureClass.ShapeType == tp)
nllist.Add(new name_Layer(plyr.Name, plyr));
}
}
}
else if (plyr is IGroupLayer)
{
getGroupLayer(ref nllist, (IGroupLayer)plyr,tp);
}
}
}
#endregion
#region 获取图层组的子图层
/// <summary>
/// 获取图层组的子图层
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="nllist"></param>
/// <param name="pGroupLyr"></param>
private static void getGroupLayer<T>(ref List<name_Layer> nllist, IGroupLayer pGroupLyr)
{
ICompositeLayer pCmsLyr = pGroupLyr as ICompositeLayer;
for (int i = 0; i < pCmsLyr.Count; i++)
{
ILayer plyr = pCmsLyr.get_Layer(i);
if (plyr is T)
{
nllist.Add(new name_Layer(plyr.Name, plyr));
}
if (plyr is IGroupLayer)
{
getGroupLayer<T>(ref nllist, (IGroupLayer)plyr);
}
}
}
/// <summary>
/// 获取图层组的子图层,只针对于FeatureLayer
/// </summary>
/// <param name="nllist"></param>
/// <param name="pGroupLyr"></param>
/// <param name="tp"></param>
private static void getGroupLayer(ref List<name_Layer> nllist, IGroupLayer pGroupLyr,esriGeometryType tp)
{
ICompositeLayer pCmsLyr = pGroupLyr as ICompositeLayer;
for (int i = 0; i < pCmsLyr.Count; i++)
{
ILayer plyr = pCmsLyr.get_Layer(i);
if (plyr is IFeatureLayer)
{
if(((IFeatureLayer)plyr).FeatureClass!=null){
if (((IFeatureLayer)plyr).FeatureClass.ShapeType == tp)
nllist.Add(new name_Layer(plyr.Name, plyr));
}
}
if (plyr is IGroupLayer)
{
getGroupLayer(ref nllist, (IGroupLayer)plyr,tp);
}
}
}
#endregion
#region 图层更改数据源
/// <summary>
/// 根据图层中的数据源的数据集名称设置数据源
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="pLyr"></param>
/// <param name="pWs"></param>
public static void setDataSourceByDsname<T>(ILayer pLyr, IWorkspace pWs,string pnm="")
{
string dsName;
if (string.IsNullOrEmpty(pnm))
{
dsName = (((IDataLayer)pLyr).DataSourceName as IDatasetName).Name;
}
else
{
dsName = pnm;
}
try
{
if (typeof(T) == typeof(IFeatureLayer))
{
IFeatureWorkspace pfws = pWs as IFeatureWorkspace;
IFeatureLayer pftLyr = pLyr as IFeatureLayer;
pftLyr.FeatureClass = pfws.OpenFeatureClass(dsName);
}
else if (typeof(T) == typeof(IRasterLayer))
{
IRasterWorkspace2 prstWorkspace = pWs as IRasterWorkspace2;
IRasterLayer prstLyr = pLyr as IRasterLayer;
IRasterDataset rasterDataset = prstWorkspace.OpenRasterDataset(dsName);
prstLyr.CreateFromDataset(rasterDataset);
}
}
catch (System.Exception ex)
{
//可能会有未知的名称问题导致图层名称更改而无法获取名称的问题
}
}
public static void setDataSourceByDsnameTwice<T>(ILayer pLyr, IWorkspace pWs)
{
IWorkspace2 pws2 = pWs as IWorkspace2;
string dsName;
dsName = (((IDataLayer)pLyr).DataSourceName as IDatasetName).Name;
esriDatasetType edt;
if (typeof(T) == typeof(IFeatureLayer))
{
edt = esriDatasetType.esriDTFeatureClass;
}
else if (typeof(T) == typeof(IRasterLayer))
{
edt = esriDatasetType.esriDTRasterDataset;
}
else
edt = esriDatasetType.esriDTAny;
if(pws2.get_NameExists(edt,dsName))
{
setDataSourceByDsname<T>(pLyr, pWs);
}
else
{
dsName = "_" + dsName;
if (pws2.get_NameExists(edt, dsName))
setDataSourceByDsname<T>(pLyr, pWs,dsName);
else
{
//不存在,不处理
}
}
}
/// <summary>
/// 根据图层的名称设置数据源
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="pLyr"></param>
/// <param name="pWs"></param>
public static void setDataSourceByLayerName<T>(ILayer pLyr, IWorkspace pWs)
{
string dsName = pLyr.Name;
if (typeof(T) == typeof(IFeatureLayer))
{
IFeatureWorkspace pfws = pWs as IFeatureWorkspace;
IFeatureLayer pftLyr = pLyr as IFeatureLayer;
pftLyr.FeatureClass = pfws.OpenFeatureClass(dsName);
}
else if (typeof(T) == typeof(IRasterLayer))
{
if (dsName.Contains("."))
dsName = dsName.Substring(0, dsName.LastIndexOf("."));
IRasterWorkspace2 prstWorkspace = pWs as IRasterWorkspace2;
IRasterLayer prstLyr = pLyr as IRasterLayer;
IRasterDataset rasterDataset = prstWorkspace.OpenRasterDataset(dsName);
prstLyr.CreateFromDataset(rasterDataset);
}
}
#endregion
}
二、核心功能
using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.Display;
using System.Windows.Forms;
using GISCommonHelper;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Editor;
namespace DayDreamInGISTool.SpatialJoin
{
/// <summary>
/// 空间连接 属性附加
/// </summary>
public class SpatialJoin_AppendBtn : ESRI.ArcGIS.Desktop.AddIns.Button
{
public SpatialJoin_AppendBtn()
{
}
private IMap pMap;
private IFeatureLayer pSourceFtLyr, pJoinedFtlyr;
/// <summary>
/// 待附加的字段集合
/// </summary>
private List<string> append_fdlist;
/// <summary>
/// 多要素是否综合
/// </summary>
private bool b_summary;
/// <summary>
/// 同名字段时,是否使用已有字段
/// </summary>
private bool b_old;
/// <summary>
/// 连接要素个数字段名
/// </summary>
private string sj_count = "J_Count";
/// <summary>
/// 连接要素的Id字段
/// </summary>
private string s_Oid = "S_OId";
private event ProgressDialogHelper.ProgressUpdateHandler ProgressUpdateEvent; //下一步事件
private event ProgressDialogHelper.EndHandler EndEvent; //结束事件
Guid toolid = Guid.Parse("{D21C8C59-6658-4228-A9D0-12D0A8D22217}");
protected override void OnClick()
{
//if (false)
//{
// ArcMap.Application.CurrentTool = null;
// return;
//}
//添加字段时,需要关闭编辑模式,否则无法添加字段
IEditor3 meditor = GISCommonHelper.AddInHelper.geteditor(ArcMap.Application);
if (meditor.EditState == esriEditState.esriStateEditing)
{
MessageBox.Show("请关闭编辑模式");
return;
}
pMap = ArcMap.Document.FocusMap;
try
{
frmSJSet fsjs = new frmSJSet();
if (fsjs.ShowDialog() == DialogResult.OK)
{
//通过窗体获取空间链接相关参数
append_fdlist = fsjs.Fields_list;
pSourceFtLyr = fsjs.PSourceFtlyr;
pJoinedFtlyr = fsjs.PJoinedFtLyr;
b_summary = fsjs.B_summary;
b_old = fsjs.B_old;
//添加待附加的字段至源图层中.
addTFields();
//下述代码构建空间缓存,以提高空间检索的效率
IWorkspace pSourceWs = (pSourceFtLyr.FeatureClass as IDataset).Workspace;
ISpatialCacheManager spatialCacheManager = pSourceWs as ISpatialCacheManager;
IEnvelope cacheExtent = (pSourceFtLyr.FeatureClass as IGeoDataset).Extent;
if(spatialCacheManager!=null)
{
//检测是否存在缓存
if (!spatialCacheManager.CacheIsFull)
{
//不过不存在,则创建缓存
spatialCacheManager.FillCache(cacheExtent);
}
}
IWorkspace pJoinWS= (pJoinedFtlyr.FeatureClass as IDataset).Workspace;
ISpatialCacheManager spatialCacheManager2 = pJoinWS as ISpatialCacheManager;
IEnvelope cacheExtent2 = (pJoinedFtlyr.FeatureClass as IGeoDataset).Extent;
if (spatialCacheManager2 != null)
{
//检测是否存在缓存
if (!spatialCacheManager2.CacheIsFull)
{
//不过不存在,则创建缓存
spatialCacheManager2.FillCache(cacheExtent2);
}
}
//打开要素工作空间的编辑模式
IWorkspaceEdit pwsEdit = pSourceWs as IWorkspaceEdit;
pwsEdit.StartEditing(false);
pwsEdit.StartEditOperation();
int feature_count = pSourceFtLyr.FeatureClass.FeatureCount(null);
int count = 0;
//配置进度更新对话框
ProgressDialogHelper pdh = new ProgressDialogHelper();
pdh.Min = 0;
pdh.Max = feature_count;
pdh.Msg = "正在检索...";
pdh.Title = "处理中...";
pdh._Application = ArcMap.Application;
pdh.InitisalProgressDialog();
this.EndEvent += pdh.End;
this.ProgressUpdateEvent += pdh.progressNext;
//对源图层中所有要素进行遍历
IFeatureCursor pSFtcursor = pSourceFtLyr.FeatureClass.Update(null, false);
IFeature pSourceFeature = pSFtcursor.NextFeature();
while (pSourceFeature != null)
{
//if (pSourceFeature.OID != 48)
//{
// pSourceFeature = pSFtcursor.NextFeature();
// continue;
//}
search(ref pSourceFeature);
pSFtcursor.UpdateFeature(pSourceFeature);
pSourceFeature = pSFtcursor.NextFeature();
count++;
if (ProgressUpdateEvent != null)
{
ProgressUpdateEvent(count);
}
//System.Diagnostics.Debug.WriteLine(count);
}
if (EndEvent != null)
EndEvent();
//pSFtcursor.Flush();
//保存编辑
pwsEdit.StopEditOperation();
pwsEdit.StopEditing(true);
MessageBox.Show("处理完成");
//清除缓存
if(spatialCacheManager!=null)
spatialCacheManager.EmptyCache();
if(spatialCacheManager2!=null)
spatialCacheManager2.EmptyCache();
}
}
catch (System.Exception ex)
{
MessageBox.Show("发生未知异常,ErrorCode:{B74639EE-B057-4CCF-B9DA-3D0155F7EC28},消息:" + ex.Message);
}
//finally
//{
//}
}
/// <summary>
/// 检索并设置要素的附加字段的值.
/// </summary>
/// <param name="pSourceFeature"></param>
private void search(ref IFeature pSourceFeature)
{
//以源图层中的要素进行空间检索
ISpatialFilter psf = new SpatialFilterClass();
IGeometry pGeo = pSourceFeature.Shape;
ITopologicalOperator ptop = pGeo as ITopologicalOperator;
ptop.Simplify(); //简化
psf.Geometry = ptop as IGeometry;
psf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
IFeatureCursor pftcursor = pJoinedFtlyr.FeatureClass.Search(psf, false);
IFeature pJFeature = pftcursor.NextFeature();
//检索到的要素集合
List<IFeature> search_list = new List<IFeature>();
while (pJFeature != null)
{
search_list.Add(pJFeature);
if (b_summary)
{
}
else
{
break;
}
pJFeature = pftcursor.NextFeature();
}
//字段内容处理
int source_fdIndex, join_fdIndex;
IField psourefd;
object val=0;
for (int i = 0; i < append_fdlist.Count; i++)
{
source_fdIndex = pSourceFeature.Fields.FindField(append_fdlist[i]);
//此处存在Bug,如果存在源图层字段与连接图层字段重复,并选择了保留两个字段时,会存在Bug
join_fdIndex = pJoinedFtlyr.FeatureClass.Fields.FindField(append_fdlist[i]);
psourefd = pSourceFeature.Fields.get_Field(source_fdIndex);
switch (psourefd.Type)
{
case esriFieldType.esriFieldTypeString:
case esriFieldType.esriFieldTypeDate:
//连接
string str = "";
if (search_list.Count == 0)
{
}
else
{
//字符类型进行连接
val = "";
for (int j = 0; j < search_list.Count; j++)
{
string Vl = search_list[j].get_Value(join_fdIndex).ToString();
if (!string.IsNullOrWhiteSpace(Vl))
{
str += Vl + ",";
}
}
if (str.Length != 0)
{
if (str[str.Length - 1] == ',')
{
val = str.Remove(str.Length - 1);
}
}
if (pSourceFeature.Fields.get_Field(source_fdIndex).Name == "FNUMBER")
{
System.Diagnostics.Debug.WriteLine("开始调试");
}
//此时需要判断是否可能超限
if (psourefd.Length < str.Length)
{
val = str.Substring(0, psourefd.Length - 1); //防止超过长度
}
}
break;
case esriFieldType.esriFieldTypeSmallInteger:
val = summary<int>(search_list, join_fdIndex);
break;
case esriFieldType.esriFieldTypeSingle:
val = summary<Single>(search_list, join_fdIndex);
break;
case esriFieldType.esriFieldTypeInteger:
val = summary<long>(search_list, join_fdIndex);
break;
case esriFieldType.esriFieldTypeDouble:
val = summary<double>(search_list, join_fdIndex);
break;
}
pSourceFeature.set_Value(source_fdIndex, val);
}
//设置写入个数,源OId
if (search_list.Count == 0)
{
}
else
{
string strt = "";
for (int i = 0; i < search_list.Count; i++)
{
strt += search_list[i].OID.ToString() + ",";
}
strt = strt.Remove(strt.Length - 1);
//判断长度是否超限
int s_oid_length = pSourceFeature.Fields.get_Field(pSourceFeature.Fields.FindField(s_Oid)).Length;
if (s_oid_length < strt.Length)
{
strt = strt.Substring(0, s_oid_length - 5) + ">>";
}
pSourceFeature.set_Value(pSourceFeature.Fields.FindField(s_Oid), strt);
}
pSourceFeature.set_Value(pSourceFeature.Fields.FindField(sj_count), search_list.Count);
System.Runtime.InteropServices.Marshal.ReleaseComObject(pftcursor);
System.Runtime.InteropServices.Marshal.ReleaseComObject(psf);
System.GC.Collect();
System.GC.WaitForPendingFinalizers();//挂起当前线程,直到处理终结器队列的线程清空该队列为止。
}
private object summary<T>(List<IFeature> ftlist,int fdIndex)
{
if (typeof(T) == typeof(System.Double))
{
double tmp = 0;
for (int j = 0; j < ftlist.Count; j++)
{
double t = 0;
string st = ftlist[j].get_Value(fdIndex).ToString();
if (double.TryParse(st, out t))
{
tmp += t;
}
}
return tmp;
}
if (typeof(T) == typeof(System.Int32))
{
int tmp = 0;
for (int j = 0; j < ftlist.Count; j++)
{
int t = 0;
string st = ftlist[j].get_Value(fdIndex).ToString();
if (int.TryParse(st, out t))
{
tmp += t;
}
}
return tmp;
}
if (typeof(T) == typeof(System.Single))
{
Single tmp = 0;
for (int j = 0; j < ftlist.Count; j++)
{
string stt = ftlist[j].get_Value(fdIndex).ToString();
Single t = 0;
if (Single.TryParse(stt, out t))
{
tmp += t;
}
}
return tmp;
}
if (typeof(T) == typeof(System.Int64))
{
long tmp = 0;
for (int j = 0; j < ftlist.Count; j++)
{
long t = 0;
string st=ftlist[j].get_Value(fdIndex).ToString();
if(long.TryParse(st,out t)){
tmp+=t;
}
}
return tmp;
}
else
return null;
}
/// <summary>
/// 添加附加字段
/// </summary>
private void addTFields()
{
//添加附加字段 添加字段通过IClass接口实现
IClass pClass = pSourceFtLyr.FeatureClass as IClass;
for (int i = 0; i < append_fdlist.Count; i++)
{
string fdnm = append_fdlist[i];
if (addHasFd(pClass, ref fdnm))
{
append_fdlist[i] = fdnm; //字段名称发生变化时,更新待附加字段集合中的名称
}
}
//添加Join_Count,源Oid字段
if (pClass.Fields.FindField(sj_count) == -1)
{
IField pfd = new FieldClass();
IFieldEdit pfdEdit = pfd as IFieldEdit;
pfdEdit.Name_2 = sj_count;
pfdEdit.Type_2 = esriFieldType.esriFieldTypeSmallInteger;
pClass.AddField(pfd);
}
if (pClass.Fields.FindField(s_Oid) == -1)
{
IField pfd = new FieldClass();
IFieldEdit pfdEdit = pfd as IFieldEdit;
pfdEdit.Name_2 = s_Oid;
pfdEdit.Type_2 = esriFieldType.esriFieldTypeString;
pfdEdit.Length_2 = 200;
pClass.AddField(pfd);
}
}
/// <summary>
/// 添加字段名称,如果字段名称没有变化,返回false,字段名称变化了,返回true
/// </summary>
/// <param name="pClass"></param>
/// <param name="fdnm"></param>
/// <returns></returns>
private bool addHasFd(IClass pClass,ref string fdnm)
{
IField pSFd = pJoinedFtlyr.FeatureClass.Fields.get_Field(pJoinedFtlyr.FeatureClass.FindField(fdnm));
if (pClass.FindField(fdnm) == -1)
{
//在源图层中检索待附加字段,不存在该字段,则添加.
IClone pClone = pSFd as IClone; //通过AE提供的IClone接口,直接从待连接图层的字段中复制一个对象
IFieldEdit pNFD = pClone.Clone() as IFieldEdit;
pNFD.IsNullable_2 = true;
pClass.AddField(pNFD);
return false;
}
else
{
//如果源图层存在该字段
if (!b_old)
{
//配置不使用原字段,则创建新字段
fdnm = fdnm.Remove(fdnm.Length - 1, 1);
fdnm = fdnm + "T"; //移除字段名的最后一个字符,并替换为"T",特殊情况下,可能存在还是与原字段名一致的问题
IFieldEdit psfdEdit = pSFd as IFieldEdit;
psfdEdit.Name_2 = fdnm;
pClass.AddField(psfdEdit as IField);
return true;
}
else
{
//配置使用原字段
return false;
}
}
}
protected override void OnUpdate()
{
}
}
}