在使用AE打开或者加载数据的第一步就是 通过工作空间工厂(IWorkspaceFactory)获取工作空间(IWorkspace),然后从工作空间中获取数据集(DataSet)、要素类(FeatureClass)、表(Table)等数据。
对于不同类型的空间数据库,对应着不同的工作空间类,这些类都继承了接口IWorkspaceFactory,然后通过IWorkspaceFactory接口的不同的方法如Create、Open、OpenFromFile产生不用类型的工作空间(IWorkspace)。
这种模式就是面向对象设计模式中的工厂模式,当我们想要扩展新的数据类型时,只需要创建对应的工作空间类,这个类继承自IWorkspaceFactory,然后创建相应的工作空间类,这个类继承自IWorkspace接口。 这样满足了依赖倒转的原则,实现了易维护,易重用,易扩展,灵活性好的设计。
我们来看一下类和接口之间的关系:
如果我们有新的数据类型,只需要创建如图所示的类,继承自IWorkspaceFactory接口即可。
其中Workspace类中包含了我们的大部分类型(file、geodata、sde)的对工作空间中数据的管理方法,我们也可以进行扩展,创建如图所示的类,继承自IWorkspace接口即可。
例子:
打开ShapeFile文件:
IWorkspaceFactory workspaceFactory = new ShapefileWorkspaceFactoryClass();
IWorkspace pworkspace = workspaceFactory.OpenFromFile(string_ShapefileDirectory, 0);
打开个人空间数据库:
IWorkspaceFactory pAccessWorkspaceFactory = new AccessWorkspaceFactory();
IWorkspace pWorkspace = pAccessWorkspaceFactory.OpenFromFile(pFullPath, 0);
打开SDE空间数据库:
IWorkspaceFactory pAccessWorkspaceFactory = new SdeWorkspaceFactory();
IWorkspace pWorkspace = arcSDEWorkspaceOpen("192.168.70.110", "esri_sde", "sde", "sde", "", "SDE.DEFAULT");
接下来对pWorkspace 中的数据进行操作。
假如我们现在要扩展空间数据类型,我们构造了一种“文本空间数据(txt)”,我们就要对现有的类和接口进行扩展。
首先我们创建工厂类TxtWorkspaceFactory,继承自IWorkspaceFactory,然后创建接口ITxtWorkspace接口,该接口中有对TxtWorkspace中数据的操作方法,然后创建TxtIWorkspace类,继承自IWorkspace接口和ITxtWorkspace接口,在TxtWorkspaceFactory类编码对数据的操作。
则实现代码如下:
IWorkspaceFactory ptxtWorkspaceFactory = new TxtWorkspaceFactory();
IWorkspace pWorkspace = ptxtWorkspaceFactory .OpenFromFile(pTxtPath, 0);
ITxtWorkspace txtWorkspace = pWorkspace as ITxtWorkspace ;
txtWorkspace 中的方法完成数据操作。
我猜想大概在ArcGIS Engine中也是这样架构的,达到易扩展,易维护、易重用和灵活性的效果。
在实际的开发中,我们可以借用配置文件中的信息来自动实例化某种数据,实现依赖注入。
<LocalFile IsEnable="true" MxdPath="C:\Users\ZHU\Desktop\To师姐\201301001_详查\201301001_详查.mxd"/>
<SDEServer IsEnable="false">
<ServerItem IsEnable="true" DBType="Oracle" IP="192.168.1.1" DBName="" Service="5151" SDEUser="SDE" SDEPassword="SDE" Version="SDE.DEFAULT" ConnectionType="ServiceConnect"/>
</SDEServer>
根据配置文件判断是那种数据类型,然后读取相应的参数,获得工作空间IWorkspace。
在GIS开发中,我们的框架通常使用单例模式进行创建,框架中包含 项目的信息、项目的坐标系信息、项目的MapControl、PageLayoutControl等。
/// <summary>
/// 宿主程序
/// </summary>
public partial class SBApplication : ISBApplication,ISBStatusControl, ISBMapStatuesControl,ISBDockManager
{
private const string LOGNAME = "SBApplication";
private static ISBApplication m_AppContext;
private static bool m_IsInitAppContext = false;
private Form m_platForm;//主窗体
private RibbonControl m_ctrlRibbon;//Ribbon控件
private DockManager m_platDock;//DockManager
private RibbonStatusBar m_platStatusBar;//状态栏
private AxMapControl m_platMapControl;//MapControl
private AxTOCControl m_platTOCControl;//TOCControl
private TabbedView m_platTabbedView;//多文档窗体
private ImageList m_imageList;//图标集合
private ISBTool m_currentTool;//当前操作工具
private List<PopupMenu> m_lstPopupMenus;//地图右键弹出菜单
private XtraTabControl m_tabControl;//TabControl
private string m_version;//版本
private EnumLoadSpatialDataType m_loadSpatialDataType;//空间数据加载类型
private SystemMenu m_systemMenu;//系统菜单配置
//返回静态宿主程序类AppContext
public static ISBApplication AppContext
{
get { return m_AppContext; }
}
/// <summary>
/// 构造函数,为地图控件和Button控件,TOC控件绑定事件。
/// </summary>
/// <param name="platForm"></param>
/// <param name="platDock"></param>
/// <param name="platTabbedView"></param>
/// <param name="platMapControl"></param>
/// <param name="platTOCCOntrol"></param>
/// <param name="imageList"></param>
private SBApplication(RibbonForm platForm, DockManager platDock, TabbedView platTabbedView, AxMapControl platMapControl,AxTOCControl platTOCCOntrol, ImageList imageList)
{
m_platForm = platForm;
m_ctrlRibbon = platForm.Ribbon;
m_platDock = platDock;
m_platTabbedView = platTabbedView;
m_platStatusBar = platForm.StatusBar;
m_platMapControl = platMapControl;
m_platTOCControl = platTOCCOntrol;
m_imageList = imageList;
m_loadSpatialDataType = EnumLoadSpatialDataType.LoadSDELayer;
m_ctrlRibbon.ItemClick +=new DevExpress.XtraBars.ItemClickEventHandler(m_ctrlRibbon_ItemClick);
m_platMapControl.OnMouseDown +=new IMapControlEvents2_Ax_OnMouseDownEventHandler(m_platMapControl_OnMouseDown);
m_platMapControl.OnMouseMove +=new IMapControlEvents2_Ax_OnMouseMoveEventHandler(m_platMapControl_OnMouseMove);
m_platMapControl.OnMouseUp +=new IMapControlEvents2_Ax_OnMouseUpEventHandler(m_platMapControl_OnMouseUp);
m_platMapControl.OnDoubleClick +=new IMapControlEvents2_Ax_OnDoubleClickEventHandler(m_platMapControl_OnDoubleClick);
m_platMapControl.OnKeyDown +=new IMapControlEvents2_Ax_OnKeyDownEventHandler(m_platMapControl_OnKeyDown);
m_platMapControl.OnKeyUp +=new IMapControlEvents2_Ax_OnKeyUpEventHandler(m_platMapControl_OnKeyUp);
m_platMapControl.OnExtentUpdated +=new IMapControlEvents2_Ax_OnExtentUpdatedEventHandler(m_platMapControl_OnExtentUpdated);
m_platMapControl.OnFullExtentUpdated +=new IMapControlEvents2_Ax_OnFullExtentUpdatedEventHandler(m_platMapControl_OnFullExtentUpdated);
m_platMapControl.OnMapReplaced +=new IMapControlEvents2_Ax_OnMapReplacedEventHandler(m_platMapControl_OnMapReplaced);
m_platMapControl.OnSelectionChanged +=new EventHandler(m_platMapControl_OnSelectionChanged);
m_platMapControl.OnAfterDraw +=new IMapControlEvents2_Ax_OnAfterDrawEventHandler(m_platMapControl_OnAfterDraw);
m_platMapControl.OnViewRefreshed +=new IMapControlEvents2_Ax_OnViewRefreshedEventHandler(m_platMapControl_OnViewRefreshed);
m_platTOCControl.OnMouseDown +=new ITOCControlEvents_Ax_OnMouseDownEventHandler(m_platTOCControl_OnMouseDown);
}
/// <summary>
/// 初始化宿主程序入口
/// </summary>
/// <param name="platForm">主界面</param>
/// <param name="platDock">DockManager</param>
/// <param name="platTabbedView">多文档窗体</param>
/// <param name="platMapControl">地图控件</param>
/// <param name="platTOCCOntrol">TOC控件</param>
/// <param name="imageList">图标集合</param>
public static void InitAppContext(RibbonForm platForm, DockManager platDock, TabbedView platTabbedView, AxMapControl platMapControl, AxTOCControl platTOCCOntrol,ImageList imageList)
{
if (!m_IsInitAppContext)
{
if (platForm == null || platDock == null || platTabbedView == null || platMapControl == null)
{
return;
}
m_AppContext = new SBApplication(platForm, platDock, platTabbedView, platMapControl, platTOCCOntrol,imageList);
m_IsInitAppContext = true;
}
}
通过静态方法获取宿主程序
SBApplication.InitAppContext(this, dockManager1, tabbedView, axMapControl1, axTOCControl1, imageList1);
SBApplication.AppContext.Version = m_systemMenuAdmin.Version;
SBApplication.AppContext.LoadMenuPlugins(m_systemMenuAdmin);
m_AppContext = SBApplication.AppContext;
这里大概包含了所有的设计模式中创建对象的模式,ARCGIS Engine中还包含了很多的设计模式,后面再叙述吧····