这是一个基于字段计算的工具。
有时候我们会遇到一些混杂着各种中文、英文、数字、特殊符号的文字,这个工具的目的是从这些复杂文字中提取出想要的特定文字。
比如说从CAD测绘图中可以读取到类似【混3】、【砖2】的文字,如果想要从中提取出层数或结构,就可以用这个工具实现。
一、要实现的功能
如上图所示,点击【提取特定文字】工具,选择地图内的要素图层或独立表,再选择要处理的包含复杂文字的字段和要输出结果的字段,再选择提取模式,点击执行即可。
执行结果如下:
有点像字段计算器计算的结果,实际上用字段计算器也能实现上面的效果,有兴趣的可以看一下这一篇文章:Arcgis小技巧【10】——字段计算器的简单用法和示例
二、实现流程
首先要从当前选择的图层或独立表中获取【Table】,作为后续字段计算的载体。
因为选择的可能是要素图层或者独立表,写了一个通用方法,考虑的比以前要多一些。
// 从图层获取Tablepublic static Table GetTableFromLayer(string fcPath){// 判断是否选择了图层if (fcPath == ""){MessageBox.Show("请选择一个要素图层或表");return null;}// 根据图层名找到当前图层var map = MapView.Active.Map;var init_featurelayer = map.FindLayers(fcPath);var init_table = map.FindStandaloneTables(fcPath);// 判断当前选择的是要素图层还是独立表if (init_featurelayer.Count == 0){// 是独立表的情况StandaloneTable init_layer = map.FindStandaloneTables(fcPath)[0];return init_layer.GetTable();}if (init_table.Count == 0){// 是要素图层的情况FeatureLayer init_layer = map.FindLayers(fcPath)[0] as FeatureLayer;return init_layer.GetTable();}return null;}
获取到【Table】之后,就可以通过游标进行字段计算了:
await QueuedTask.Run(() =>{// 获取所选图层的所有字段var tb = ToolManager.GetTableFromLayer(layer_path);// 字段计算using (ArcGIS.Core.Data.Table table = tb){using (RowCursor rowCursor = table.Search(null, false)){TableDefinition tableDefinition = table.GetDefinition();while (rowCursor.MoveNext()){using (Row row = rowCursor.Current){// 获取输入字段的值var value_in = row[field_in].ToString();// 提取特定文字row[field_out] = ToolManager.GetWord(value_in, model);// 保存row.Store();}}}}});
这里的ToolManager.GetWord(value_in, model)方法就是最核心的代码了,主要是通过正则表达式来实现:
// 提取特定文字【model包括:中文、英文、数字、特殊符号】public static string GetWord(string txt_in, string model = "中文"){string chinesePattern = "[\u4e00-\u9fa5]"; // 匹配中文字符的正则表达式string englishPattern = "[a-zA-Z]"; // 匹配英文字符的正则表达式string digitPattern = @"\d"; // 匹配数字的正则表达式string specialCharPattern = @"[^a-zA-Z0-9\u4e00-\u9fa5\s]"; // 匹配特殊符号的正则表达式string txt = "";if (model == "中文"){Regex chineseRegex = new Regex(chinesePattern);txt = ExtractMatches(txt_in, chineseRegex);}else if (model == "英文"){Regex englishRegex = new Regex(englishPattern);txt = ExtractMatches(txt_in, englishRegex);}else if (model == "数字"){Regex digitRegex = new Regex(digitPattern);txt = ExtractMatches(txt_in, digitRegex);}else if (model == "特殊符号"){Regex specialCharRegex = new Regex(specialCharPattern);txt = ExtractMatches(txt_in, specialCharRegex);}return txt;}// 正则匹配public static string ExtractMatches(string input, Regex regex){string result = "";MatchCollection matches = regex.Matches(input);foreach (Match match in matches){result += match.Value;}return result;}
核心代码并不长,正则表达式之前在python中用过,这次在c#中实现,基本差不多,还是很好用的。
三、工程文件分享
最后,放上工程文件的链接:
GetWordhttps://pan.baidu.com/s/1IJ6qDrMKcZqWCsPceAy5bA?pwd=y1vyPS:可以直接点击...bin\Debug\net6.0-windows\下的.esriAddinX文件直接安装。