笔者最近在做一个地籍的项目。单位叫开发一个基于cad二次开发的地籍软件,方便工作人员绘图入库使用。绘图人员前期作业主要是采用cass软件(cad二次开发的)进行作业。所以一些开发工作要兼顾到cass软件的图形属性的存储方式。笔者主要是对绘图人员绘制的地籍图批量导出shp格式的数据,方便后期入库使用。cass对图形的属性数据存储方式主要以扩展数据为主,例如cass编码。在导入cad数据时,要分要素导出,就是将相同cass编码的数据导出到同一个shp文件中。所以就要使用选择集过滤具有相同cass编码的要素。当过滤1001组码的扩展数据时都可以成功的过滤,在过滤1000组码的时候始终过滤不成功,个数为0,最关键的是cass编码都存储在1000组码当中。
TypedValue[] acTypValAr = new TypedValue[2];
acTypValAr.SetValue(new TypedValue(1001, "SOUTH"), 0);
acTypValAr.SetValue(new TypedValue(1000, casscode), 1);
SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
PromptSelectionResult acSSPrompt;
acSSPrompt = acDocEd.SelectAll(acSelFtr);
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
Application.ShowAlertDialog("Number of objects selected: " + acSSet.Count.ToString());
}
else
{
Application.ShowAlertDialog("Number of objects selected: 0");
}
这段代码始终跳到else里。后来经过查证确实autocad不能直接对1000组码进行选择集过滤。
经过在QQ群里的一番询问,发现有些人也遇到过类似的问题,但却都没有解决,绕过了这个问题,用了比较简单而粗暴的方式去做,就是通过遍历图中的每个图元的所有扩展数据去判断该图元是否有指定的cass编码。因为笔者这次做的不是针对个别图元进行判断,而是针对整个已经绘制好的地籍图批量导出,如果按照群友的说法,显然运行效率会大大降低。于是继续寻找,查了百度,google。最后在autodesk官网的论坛下终于找到了个较好的解决方案。这个问题是个老外提出的,也是个老外解决的。代码如下:
private string curCasscode;
private void FeatureFilter()
{
// Get the current document editor获取当前文档编辑器
Editor acDocEd = Application.DocumentManager.MdiActiveDocument.Editor;
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
TypedValue[] acTypValAr = new TypedValue[1];
acTypValAr.SetValue(new TypedValue(1001, "SOUTH"), 0);
SelectionFilter acSelFtr = new SelectionFilter(acTypValAr);
PromptSelectionResult acSSPrompt;
using (Transaction tr = db.TransactionManager.StartTransaction())
{
acDocEd.SelectionAdded += OnSelectionAdded;
acSSPrompt = acDocEd.SelectAll(acSelFtr); ;
acDocEd.SelectionAdded -= OnSelectionAdded;
if (acSSPrompt.Status == PromptStatus.OK)
{
SelectionSet acSSet = acSSPrompt.Value;
Application.ShowAlertDialog("Number of objects selected: " + acSSet.Count.ToString());
}
else
{
Application.ShowAlertDialog("Number of objects selected: 0");
}
tr.Commit();
}
}
}
void OnSelectionAdded(object sender, SelectionAddedEventArgs e)
{
ObjectId[] ids = e.AddedObjects.GetObjectIds();
for (int i = 0; i < ids.Length; i++)
{
DBObject obj = ids[i].GetObject(OpenMode.ForRead);
ResultBuffer data = obj.GetXDataForApplication("SOUTH");
bool has = false;
foreach (TypedValue tv in data)
{
if (tv.TypeCode == 1000 && (string)tv.Value == curCasscode)
{
has = true;
break;
}
}
if (!has) e.Remove(i);
}
}
主体思路:editor提供了SelectionAdded事件,事件可以自定义。在选择集过滤的时候,根据需要,逐个扩展数据判断,过滤出符合要求的要素。
虽然也是逐个扩展数据判断,却大大提高了运行效率,比网友的解决方案要好一些。