实现目标
- 遍历指定路径中的.gdb文件,并获取相关其中要素类、要素集
- 从.gdb中打卡指定FeatureClass,并对其创建FeatureLayer
- 修改FeatureLayer简单当时(颜色、线宽)
基本对象
异步对象
- QuenedTask :用于完成数据获取和处理过程中的异步操作
geodatabase相关
- GeoDataBase :用于提供GDB数据库的访问操作
- FileGeodatabaseConnectionPath:用于设置和管理数据库连接信息
- FeatureClass:要素类
- FetureClassDefinition:提供要素类基础信息访问接口(名称、别名、几何类型)
Map与Layer
- MapView:静态对象,用于获取Arcgis Pro中地图控件
- LayerFactory:图层工厂,用于提供统一的图层构建接口
- FeatureLayer:用于访问和操作要素图层
图层样式
- SymbolFactory:符号工厂,用于提供统一符号构建接口
- CIMLineSymbol:线状符号对象,用于设置线状符号的颜色、线宽等
- SimpleRendererDefinition:渲染器定义器,用于通过指定符号创建可被图层识别的渲染器
基本逻辑代码
//构建异步任务执行器,并通过匿名Action方式,确定具体要指定业务逻辑
QueuedTask.Run(() =>
{
//通过FileGeodatabaseConnectionPath将具体GDB路径转化为Geodatabase可以识别的连接信息
FileGeodatabaseConnectionPath connect = new FileGeodatabaseConnectionPath(new Uri("C:\\Test.gdb"));
//构建GDB对象
Geodatabase gdbBase = new Geodatabase(connect);
//通过Geodatabase对象遍历当前gdb中的要素定义信息
foreach (FeatureClassDefinition Definition in gdbBase.GetDefinitions<FeatureClassDefinition>())
{
//通过要素类定义对象,判断要素类的名称是否需要访问的要素类
if(Deinition.getName().Equals("TestLineFeatureClass"))
{
//通过类名获取要素类对象
FeatureClass fc = gdb.OpenDataset<FeatureClass>(tempFcName);
//通过图层工厂,为目标要素类创建要素图层[1]
FeatureLayer tempLayer = LayerFactory.Instance.CreateFeatureLayer(fc, MapView.Active.Map);
//通过符号工厂,创建一个简单的现状符号对象[2][3]
CIMLineSymbol linesymbol = SymbolFactory.Instance.ConstructLineSymbol();
//通过现状符号对象,设置其颜色,线宽等必要信息
linesymbol.SetColor(CIMColor.CreateRGBColor(255, 255, 0));
linesymbol.SetSize(8);
//定义渲染器对象,并利用符号对象设置当前渲染器的符号参考
SimpleRendererDefinition definition = new SimpleRendererDefinition();
definition.SymbolTemplate = linesymbol.MakeSymbolReference();
//将当前渲染器设置到目标图层中
tempLayer.SetRenderer(tempLayer.CreateRenderer(definition));
}
}
});
基本代码梳理
相关对象流程关系
- 数据库访问 : 构建连接信息-> 构建数据库->遍历类定义->通过类名获取类
- 图层创建:图层工厂+要素类+图层容器 -> 要素图层
- 图层样式;创建要素符号 -> 创建渲染器定义器 -> 符号与渲染器绑定 -> 目标图层设置渲染器
代码补充说明
- 在构建图层时,Arcgis 建议通过图层工厂进行创建,且必须设置图层容器
- 在构建符号对象是,不一定必须使用符号工厂,也可直接通过new方法构建
- 符号对象有很多中,此处只是展示了一种简单的现状符号
AE差异情况
异步性
Arcgis Pro中所有的数据访问操作都必须在子线程中进行,因而
1. 相关业务逻辑访问代码应通过QueuedTask对象执行(Esri 示例代码推荐)
2. 也可以创建异步方法,在自定义子线程中执行(根据实际情况选择)
跨线程修改UI
在数据访问且修改UI时,应特别注意跨线程修改UI的问题,一种简单但不方便的做法,可以使用委托实现:
//定义委托
private delegate void Del_AddListViewItem(string contet);
//委托实现
private void AddListViewItem(string content)
{
listView_Content.Items.Add(content);
}
QueuedTask.Run(() =>
{
foreach (var item in new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(tv_Path.Text))).GetDefinitions<FeatureClassDefinition>())
{
//在子线程中判断是否需要调用委托执行UI修改
if (listView_Content.InvokeRequired)
listView_Content.Invoke(new Del_AddListViewItem(AddListViewItem), item.GetName());
else
AddListViewItem(item.GetName());
}
}
对象修改
- 操作Geodatabase时,没有明确的工作空间概念,而是直接操作数据库对象
- 重新封装了由于访问数据FeatureClass和用于方位要素类基础信息FeatureClassDefinition
- 引入了很多简单工厂对象,为对象的构建提供了统一的访问形式
补充说明
- 暂时没有找到一种编码简单的异步UI修改方式
- 暂时没有找到可以不依靠图层容器直接创建图层的方法