码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2015-05-07 11:44:51      阅读:308      评论:0      收藏:0      [点我收藏+]

标签:

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

 

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

标签:

原文地址:http://www.cnblogs.com/The-SEA/p/4484193.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!