数据处理中,经常需要将Excel中的相关属性关联到空间数据中。而Excel中的数据格式较自由,有时候Excel表中的数据包含换行符等特殊符号,而这种包含换行符的数据关联到ArcGIS的属性表中时,在属性表界面中,该界面是不支持换行符的。
比如下述两条示例数据,显示责任单位为太平街道办事处
当打开编辑模式时,并双击进该属性时,则显示为
此时,在Attributes窗口中,显示为
而平时数据处理时,有时候只是为了查看一下数据的属性,并不会打开编辑模式,也并不一定会点击到该属性。因此,往往会将这种属性只按“太平街道办事处”来处理。
工作中,有时候需要将其他业务数据库中用户填报的信息关联到空间数据中,当用户填报的数据中包含备注等字数比较多的字段时,用户往往是将其他文档整段的内容复制过来,也会产生这种问题。
上述问题解决比较麻烦,首先,数据中这种换行符问题比较难以发现,其次,即使发现了,这种换行符由于在ArcGIS 里是不显示的,也很难删除,直接在ArcGIS的属性窗口中,往往是看似删除了,实际没有删除,为了解决这个问题,往往需要在记事本中把上述内容抄写一遍,再复制到该字段中。
为了解决这个问题,制作了一个ArcGIS插件,通过对图层中的所有的字符类型的字段进行遍历,并将常见的这种特殊类型的字符,替换成其他字符。
插件下载地址:
链接:https://pan.baidu.com/s/1yUOVQ8ZoWngyEO0aRa6dhg
提取码:ssr9
注意:请下载v1.0.9版本,工具条最后一个按钮。工具名称:DayDreamInGIS工具
主要界面:
代码如下
界面部分:
<Window x:Class="WaterAssisterToolbar.AttrSpecialStrRemove.RemoveAttrSpecialStrFrm"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Title="设置-移除特殊字符"
ResizeMode="NoResize"
Height="300" Width="300" MaxWidth="300" MaxHeight="300">
<Grid Name="RootGrid">
<Label Content="图层" HorizontalAlignment="Left" Margin="12,8,0,0" VerticalAlignment="Top"/>
<ComboBox Name="cmbLayer" HorizontalAlignment="Left" Margin="51,10,0,0" VerticalAlignment="Top" Width="229" SelectionChanged="cmbLayer_SelectionChanged"/>
<GroupBox Header="待移除特殊字符" HorizontalAlignment="Left" Margin="12,41,0,0" VerticalAlignment="Top" Height="101" Width="268" Name="ToBeRemovedGroup">
<Grid Height="90" Margin="0,0,0.2,-0.4" VerticalAlignment="Top">
<CheckBox Name="chkEnter" IsChecked="True" Content="换行符 \r\n" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top"/>
<CheckBox Name="chkA" Content="响铃 \a" IsChecked="True" HorizontalAlignment="Left" Margin="142,10,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.313,0.526"/>
<CheckBox Name="chkF" IsChecked="True" Content="换页 \f" HorizontalAlignment="Left" Margin="10,34,0,0" VerticalAlignment="Top"/>
<CheckBox Name="chkT" IsChecked="True" Content="水平制表 \t" HorizontalAlignment="Left" Margin="142,34,0,0" VerticalAlignment="Top"/>
<CheckBox Name="chkV" IsChecked="True" Content="垂直制表 \v" HorizontalAlignment="Left" Margin="142,58,0,0" VerticalAlignment="Top" Checked="chkV_Checked"/>
</Grid>
</GroupBox>
<Label Content="替换为" HorizontalAlignment="Left" Margin="12,151,0,0" VerticalAlignment="Top" RenderTransformOrigin="-0.155,0.477"/>
<TextBox HorizontalAlignment="Left" Name="txtReplace" Height="23" Margin="64,151,0,0" TextWrapping="Wrap" Text="、" VerticalAlignment="Top" Width="216"/>
<Button Content="确定" Name="btnOK" HorizontalAlignment="Left" Margin="49,220,0,0" VerticalAlignment="Top" Width="83" Height="30" Click="btnOK_Click"/>
<Button Content="取消" Name="btnCancel" HorizontalAlignment="Left" Margin="174,220,0,0" VerticalAlignment="Top" Width="83" RenderTransformOrigin="-0.557,1.094" Height="30" Click="btnCancel_Click"/>
<CheckBox Content="处理TOC中所有图层" Name="chkAll" HorizontalAlignment="Left" Margin="51,193,0,0" VerticalAlignment="Top"/>
</Grid>
</Window>
界面部分代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
namespace Toolbar.AttrSpecialStrRemove
{
/// <summary>
/// RemoveAttrSpecialStrFrm.xaml 的交互逻辑
/// </summary>
public partial class RemoveAttrSpecialStrFrm : Window
{
private IMap pMap = null;
private IFeatureLayer pftlyr = null;
public IFeatureLayer Pftlyr
{
get { return pftlyr; }
set { pftlyr = value; }
}
private char[] specialCharArray;
private bool isAll = false;
public bool IsAll
{
get { return isAll; }
set { isAll = value; }
}
private List<char> special_char;
public List<char> Special_char
{
get { return special_char; }
set { special_char = value; }
}
private string replace_str;
public string Replace_str
{
get { return replace_str; }
set { replace_str = value; }
}
public RemoveAttrSpecialStrFrm()
{
InitializeComponent();
special_char = new List<char>();
pMap = ArcMap.Document.FocusMap;
GISCommonHelper.CartoLyrHelper.setFeatureLyrCombox(ref cmbLayer, pMap, esriGeometryType.esriGeometryAny);
}
private void chkV_Checked(object sender, RoutedEventArgs e)
{
}
private void btnOK_Click(object sender, RoutedEventArgs e)
{
replace_str = txtReplace.Text;
isAll = chkAll.IsChecked.Value;
if (chkA.IsChecked.Value)
{
special_char.Add('\a');
}
if (chkEnter.IsChecked.Value)
{
special_char.Add('\r');
special_char.Add('\n');
}
if (chkF.IsChecked.Value)
{
special_char.Add('\f');
}
if (chkT.IsChecked.Value)
{
special_char.Add('\t');
}
if (chkV.IsChecked.Value)
{
special_char.Add('\v');
}
this.DialogResult = true;
}
private void btnCancel_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = false;
}
private void cmbLayer_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (cmbLayer.SelectedIndex > -1)
{
pftlyr = cmbLayer.SelectedValue as IFeatureLayer;
}
}
}
}
核心代码:
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 System.Windows.Forms;
namespace Toolbar.AttrSpecialStrRemove
{
/// <summary>
/// 移除换行符等特殊字符
/// </summary>
public class btnRemoveAttrSpecialStr : ESRI.ArcGIS.Desktop.AddIns.Button
{
public btnRemoveAttrSpecialStr()
{
}
private List<char> special_char_list;
private string replacestr=";";
int cnt = 0;
protected override void OnClick()
{
try
{
RemoveAttrSpecialStrFrm ras = new RemoveAttrSpecialStrFrm();
if (ras.ShowDialog() == true)
{
cnt = 0;
special_char_list = ras.Special_char;
replacestr = ras.Replace_str;
if (ras.IsAll)
{
List<IFeatureLayer> ftlyrlist=GISCommonHelper.CartoLyrHelper.getAllLayer<IFeatureLayer>(ArcMap.Document.FocusMap);
ftlyrlist.ForEach(p => {
Execute_specialStr_Remove(p);
});
}
else
{
Execute_specialStr_Remove(ras.Pftlyr);
}
MessageBox.Show("处理完成");
}
}
catch (Exception ex)
{
MessageBox.Show("发生未知异常:"+ex.Message);
}
}
/// <summary>
/// 遍历要素,替换要素各字段中的特殊字符
/// </summary>
/// <param name="pftlyr"></param>
/// <returns></returns>
private int Execute_specialStr_Remove(IFeatureLayer pftlyr)
{
int cnt = 0;
IWorkspaceEdit pwsEdit = (pftlyr.FeatureClass as IDataset).Workspace as IWorkspaceEdit;
pwsEdit.StartEditing(false);
pwsEdit.StartEditOperation();
IFeatureCursor pftcursor = pftlyr.FeatureClass.Update(null, true);
IFeature pFeature = pftcursor.NextFeature();
while (pFeature != null)
{
System.Diagnostics.Debug.WriteLine(pFeature.OID);
remove_feature_attr_specialStr(ref pFeature);
pftcursor.UpdateFeature(pFeature);
pFeature = pftcursor.NextFeature();
}
pwsEdit.StopEditOperation();
pwsEdit.StopEditing(true);
return cnt;
}
/// <summary>
/// 替换要素所有字段中的特殊字符
/// </summary>
/// <param name="pFeature"></param>
private void remove_feature_attr_specialStr(ref IFeature pFeature)
{
for (int i = 0; i < pFeature.Fields.FieldCount; i++)
{
IField pfd = pFeature.Fields.get_Field(i);
if (pfd.Type == esriFieldType.esriFieldTypeString)
{
//只处理字符类型的值
string val = pFeature.get_Value(i).ToString();
string val_r = remove_specialStrInString(val);
if (!string.Equals(val, val_r))
{
pFeature.set_Value(i, val_r);
}
}
}
}
/// <summary>
/// 替换字符串中的特殊字符
/// </summary>
/// <param name="str"></param>
/// <returns></returns>
private string remove_specialStrInString(string str)
{
special_char_list.ForEach(p => {
str=str.Replace(p.ToString(), replacestr);
});
return str;
}
protected override void OnUpdate()
{
}
}
}