插件地址,相关细节已更新
利用AddIn开发,实现类似PS中仿制图章的工具。即通过鼠标点选的方式,选择一个要素作为源,然后将属性赋值给其他要素。
Tool代码:
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.esriSystem;
using ESRI.ArcGIS.Framework;
using System.Windows.Forms;
using ESRI.ArcGIS.Display;
using ESRI.ArcGIS.Editor;
using System.Drawing;
namespace Brush_Attributes
{
public class Brush_Attributes : ESRI.ArcGIS.Desktop.AddIns.Tool
{
private static AttributeBrushTool_SetPanel m_pbp = null;
IMap pMap = null;
//IFeatureLayer pFtlyr = null; //待操作的图层
IEditor _Editor;
public Brush_Attributes()
{
UID eUID = new UIDClass();
eUID.Value = "esriEditor.Editor";
_Editor = ArcMap.Application.FindExtensionByCLSID(eUID) as IEditor;
if (_Editor.EditState != esriEditState.esriStateEditing)
{
Enabled = false;
return;
}
else
{
Enabled = true;
}
}
protected override void OnUpdate()
{
if (ArcMap.Application != null)
{
UID eUID = new UIDClass();
eUID.Value = "esriEditor.Editor";
_Editor = ArcMap.Application.FindExtensionByCLSID(eUID) as IEditor;
if (_Editor.EditState != esriEditState.esriStateEditing)
{
Enabled = false;
return;
}
else
{
Enabled = true;
}
}
}
protected override void OnActivate()
{
if (Brush_Attributes.m_pbp == null)
{
UID windID = new UIDClass();
windID.Value = ThisAddIn.IDs.AttributeBrushTool_SetPanel;
IDockableWindow pdw = ArcMap.DockableWindowManager.GetDockableWindow(windID);
if (!pdw.IsVisible())
{
pdw.Show(true);
}
}
}
protected override void OnKeyUp(KeyEventArgs arg)
{
if (arg.KeyCode == System.Windows.Forms.Keys.Escape)
ArcMap.Application.CurrentTool = null;
}
protected override void OnMouseDown(MouseEventArgs arg)
{
if (AttributeBrushTool_SetPanel.cpidLyrId == -1)
return;
pMap = ArcMap.Document.FocusMap;
IActiveView pAv = pMap as IActiveView;
try
{
IPoint tmppnt = new PointClass();
tmppnt = pAv.ScreenDisplay.DisplayTransformation.ToMapPoint(arg.X, arg.Y);
ITopologicalOperator ptop = tmppnt as ITopologicalOperator;
IPolygon tmpPln = ptop.Buffer(0.5) as IPolygon;
if (AttributeBrushTool_SetPanel.cpidLyrId == -1)
return;
IFeatureClass copiedFtCls = ((IFeatureLayer)pMap.get_Layer(AttributeBrushTool_SetPanel.cpidLyrId)).FeatureClass;
if (arg.Control && arg.Button == MouseButtons.Left)
{
//设置鼠标样式
this.Cursor = System.Windows.Forms.Cursors.Cross;
//选择源
ISpatialFilter psf = new SpatialFilterClass();
psf.Geometry = tmpPln;
psf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
IFeatureCursor pFtCursor = copiedFtCls.Search(psf, false); ;
IFeature pTmpFt = pFtCursor.NextFeature();
if (pTmpFt != null)
{
//将选择到的要素添加至前端
List<string> ss = new List<string>();
for (int i = 0; i < pTmpFt.Fields.FieldCount; i++)
{
switch (pTmpFt.Fields.get_Field(i).Type)
{
case esriFieldType.esriFieldTypeBlob:
case esriFieldType.esriFieldTypeGeometry:
case esriFieldType.esriFieldTypeGlobalID:
case esriFieldType.esriFieldTypeGUID:
case esriFieldType.esriFieldTypeOID:
case esriFieldType.esriFieldTypeRaster:
ss.Add("");
break;
default:
ss.Add(pTmpFt.get_Value(i).ToString());
break;
}
}
//m_pbp.fillDataGridView3(ss);
AttributeBrushTool_SetPanel.fillDataGridView3(ss);
}
}
else if (arg.Button == MouseButtons.Left)
{
//刷属性
//设置鼠标样式
Stream sm = this.GetType().Assembly.GetManifestResourceStream("Brush_Attributes.Images.AttributeBrushTool.cur");
this.Cursor = new System.Windows.Forms.Cursor(sm);
//获取DataGridView中的属性
List<string> str = AttributeBrushTool_SetPanel.getDataGridViewValue3();
if (str.Count == 0)
return;
//获取所选择的要素
ISpatialFilter psf = new SpatialFilterClass();
psf.Geometry = tmpPln;
psf.SpatialRel = esriSpatialRelEnum.esriSpatialRelIntersects;
IFeatureCursor pFtCursor = copiedFtCls.Update(psf, true); ;
IFeature pTmpFt = pFtCursor.NextFeature();
if (pTmpFt != null)
{
for (int i = 0; i < pTmpFt.Fields.FieldCount; i++)
{
if (str[i] != "")
{
//字段类型转换试试
bool goon = true;
double d;
int ii;
switch (pTmpFt.Fields.get_Field(i).Type)
{
case esriFieldType.esriFieldTypeDouble:
goon = double.TryParse(str[i], out d);
break;
case esriFieldType.esriFieldTypeInteger:
goon = int.TryParse(str[i], out ii);
break;
default:
break;
}
if (goon)
{
pTmpFt.set_Value(i, str[i]);
pFtCursor.UpdateFeature(pTmpFt);
pFtCursor.Flush();
}
else
{
MessageBox.Show(pTmpFt.Fields.get_Field(i).Name + "字段所输入的值 类型不正确");
return;
}
}
}
//刷完属性闪烁要素
//FlashShape(pTmpFt);
//保存交由编辑器执行
//pTmpFt.Store();
IFeatureSelection pFtSelection = (IFeatureSelection)((IFeatureLayer)pMap.get_Layer(AttributeBrushTool_SetPanel.cpidLyrId));
pFtSelection.Clear();
pFtSelection.Add(pTmpFt);
pAv.PartialRefresh(esriViewDrawPhase.esriViewGeoSelection, null, null);
System.Threading.Thread.Sleep(100);
pFtSelection.Clear();
System.Threading.Thread.Sleep(100);
pAv.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
System.Threading.Thread.Sleep(100);
pFtSelection.Add(pTmpFt);
pAv.PartialRefresh(esriViewDrawPhase.esriViewGeography, null, null);
}
}
else
{
return;
}
}
catch (System.Exception ex)
{
MessageBox.Show("发生未知异常_"+ex.Message);
return;
}
}
/// <summary>
/// 要素闪烁
/// </summary>
/// <param name="pTmpFt"></param>
private void FlashShape(IFeature pTmpFt)
{
switch (pTmpFt.Shape.GeometryType)
{
case esriGeometryType.esriGeometryPoint:
case esriGeometryType.esriGeometryPolygon:
case esriGeometryType.esriGeometryPolyline:
break;
default:
break;
}
}
protected override void OnMouseMove(MouseEventArgs arg)
{
try
{
if (arg.Control)
{
//设置鼠标样式
this.Cursor = System.Windows.Forms.Cursors.Cross;
}
else
{
Stream sm = this.GetType().Assembly.GetManifestResourceStream("Brush_Attributes.Images.AttributeBrushTool.cur");
this.Cursor = new System.Windows.Forms.Cursor(sm);
}
}
catch (System.Exception ex)
{
MessageBox.Show("发生未知异常_"+ex.Message);
}
}
protected override void OnKeyDown(KeyEventArgs arg)
{
if (arg.Control)
{
//设置鼠标样式
this.Cursor = System.Windows.Forms.Cursors.Cross;
}
}
}
}
其中,上述代码也实现了在AddIn中自定义鼠标样式。
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geometry;
using ESRI.ArcGIS.Geodatabase;
namespace Brush_Attributes
{
/// <summary>
/// Designer class of the dockable window add-in. It contains user interfaces that
/// make up the dockable window.
/// </summary>
public partial class AttributeBrushTool_SetPanel : UserControl
{
IMap pMap = null;
public static int cpidLyrId=-1;
internal static AttributeBrushTool_SetPanel _Bsp;
public AttributeBrushTool_SetPanel(object hook)
{
InitializeComponent();
this.Hook = hook;
_Bsp = this;
}
/// <summary>
/// Host object of the dockable window
/// </summary>
private object Hook
{
get;
set;
}
/// <summary>
/// Implementation class of the dockable window add-in. It is responsible for
/// creating and disposing the user interface class of the dockable window.
/// </summary>
public class AddinImpl : ESRI.ArcGIS.Desktop.AddIns.DockableWindow
{
private AttributeBrushTool_SetPanel m_windowUI;
public AddinImpl()
{
}
protected override IntPtr OnCreateChild()
{
m_windowUI = new AttributeBrushTool_SetPanel(this.Hook);
return m_windowUI.Handle;
}
protected override void Dispose(bool disposing)
{
if (m_windowUI != null)
m_windowUI.Dispose(disposing);
base.Dispose(disposing);
}
}
private void cmbLayer_SelectedIndexChanged(object sender, EventArgs e)
{
dataGridView1.Rows.Clear();
pMap = ArcMap.Document.FocusMap;
//根据选择图层的不同,DataGridView中显示不同的字段名
if (cmbLayer.SelectedIndex != -1)
{
string tmplyrname = cmbLayer.SelectedItem.ToString();
int tmplyrIndex = getlyridByName(tmplyrname,pMap);
IFeatureLayer tmpLyr = pMap.get_Layer(tmplyrIndex) as IFeatureLayer;
cpidLyrId = tmplyrIndex;
dataGridView1.Rows.Add(tmpLyr.FeatureClass.Fields.FieldCount);
for (int i = 0; i < tmpLyr.FeatureClass.Fields.FieldCount; i++)
{
dataGridView1[0, i].Value = tmpLyr.FeatureClass.Fields.get_Field(i).Name;
switch (tmpLyr.FeatureClass.Fields.get_Field(i).Type)
{
case esriFieldType.esriFieldTypeGeometry:
case esriFieldType.esriFieldTypeRaster:
case esriFieldType.esriFieldTypeOID:
case esriFieldType.esriFieldTypeGUID:
case esriFieldType.esriFieldTypeGlobalID:
case esriFieldType.esriFieldTypeBlob:
dataGridView1[1, i].ReadOnly = true;
dataGridView1[2, i].ReadOnly = true;
break;
default:
DataGridViewCheckBoxCell dgc = ((DataGridViewCheckBoxCell)dataGridView1[1, i]);
dgc.Value = true;
break;
}
}
}
}
private int getlyridByName(string nm, IMap pMap)
{
int id = -1;
for (int i = 0; i < pMap.LayerCount; i++)
{
if (nm == pMap.get_Layer(i).Name)
{
id = i;
break;
}
}
return id;
}
/// <summary>
/// 填充第三列,没有则为空
/// </summary>
/// <param name="vls"></param>
public static void fillDataGridView3(List<string> vls)
{
try
{
for (int i = 0; i < _Bsp.dataGridView1.Rows.Count; i++)
{
DataGridViewCheckBoxCell dgc = (DataGridViewCheckBoxCell)_Bsp.dataGridView1[1, i];
if (dgc.Value == null)
continue;
if ((bool)dgc.Value) //可修改的则赋值
_Bsp.dataGridView1[2, i].Value = vls[i];
}
}
catch (System.Exception ex)
{
throw new Exception(ex.Message);
}
}
/// <summary>
/// 获取第三列的值
/// </summary>
/// <returns></returns>
public static List<string> getDataGridViewValue3()
{
List<string> sre = new List<string>();
try
{
for (int i = 0; i < _Bsp.dataGridView1.Rows.Count; i++)
{
DataGridViewCheckBoxCell dgc = (DataGridViewCheckBoxCell)_Bsp.dataGridView1[1, i];
if (dgc.Value == null)
{
sre.Add("");
continue;
}
if ((bool)dgc.Value) //可修改的则赋值
{
if (_Bsp.dataGridView1[2, i].Value != null)
sre.Add(_Bsp.dataGridView1[2, i].Value.ToString());
else
sre.Add("");
}
}
return sre;
}
catch (System.Exception ex)
{
throw new Exception(ex.Message);
}
}
private void cmbLayer_DropDown(object sender, EventArgs e)
{
try
{
cmbLayer.Items.Clear();
IMap tmpMap = ArcMap.Document.FocusMap;
for (int i = 0; i < tmpMap.LayerCount; i++)
{
IFeatureLayer tmpFtLyr = tmpMap.get_Layer(i) as IFeatureLayer;
if (tmpFtLyr != null)
{
cmbLayer.Items.Add(tmpFtLyr.Name);
}
}
}
catch (System.Exception ex)
{
MessageBox.Show("发生未知异常_"+ex.Message);
}
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
this.dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
}
}
工具界面如下。选择待操作图层之后,通过Ctrl+单击,实现属性源的选择。刷否checkebox可以设置属性是否写入目标要素。然后通过单击实现对目标要素属性的写入。