ArcGIS Engine中的设计模式——工厂模式

在使用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中还包含了很多的设计模式,后面再叙述吧····

 

转载于:https://www.cnblogs.com/The-SEA/p/4484193.html

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值