您的位置:首页 > 其它

基于Dot Net平台和AE9.0开发通用地理信息系统平台

2007-07-26 09:53 375 查看
一/框架介绍:
    EngineFramework 1.0(通用地理信息系统开发框架)是基于.Net框架2.0和AE9.0进行设计和开发的,其设计原理充分借鉴了国内外多家软件框架设计思想,具有设计思想先进/框架层次架构清晰/高可定制和扩展性等特点.
EngineFramework 为基于ArcGIS Engine的桌面GIS应用程序提供了统一的开发规范和标准,框架中封装了从按钮到工具条的创建操作/可浮动窗体的创建操作等UI界面定制功能. EngineFramework的高扩展性是得益于其“平台+ 插件”模型的设计思想.此外,还设计了基于Service架构的服务器容器,在该容器的规约下,可以将任何插件组件都设计成为一个服务器组件,该思想的运用,极大方便了插件组件之间的通讯,也使系统的可扩展性发挥到了极至.
 EngineFramework 以其优秀的设计架构,通过简单的培训,就能使各级别的开发人员能够顺利进行框架扩展开发.

    EngineFramework 的主要设计目标就是解除耦合性,为行业地理信息系统提供统一的开发框架.框架以其先进的设计思想和接口规范具有很强的稳定性和可扩展性.其为开发人员提供了大量的系统扩展规范和开发原则,开发人员只有严格遵守该规范进行设计和开发,才可以实现扩展功能和系统的无缝集成.
二/平台优势:

EngineFramework 插件框架具有如下几点显著优势:
¨        通用性强
EngineFramework的通用性主要指其适合任何基于AE和.NET平台的桌面GIS应用软件开发领域,其主要实用于开发行如ArcMap应用程序/ArcToolBox应用程序/ArcCatalog应用程序以及ArcScene应用程序等.其为这些应用程序提供统一的开发框架,应用程序开发人员通过系统提供的扩展接口可以开发丰富的GIS桌面应用程序,利用EngineFramework提供的强大类库,开发人员可以定制高伸缩性的应用程序.
¨        高可扩展性
EngineFramework 的扩展性主要体现在插件和工具条的定制方面,在其框架支持下,开发人员可以将插件设计成内嵌的工具条按钮项也可以将其设计成独立的工具条,还可以将其设计成可浮动的窗体或者一个没有用户界面的组件服务器.总之,只要开发人员能够想出把插件设计成什么方式,框架都提供了内置的支持方式.
¨        高可维护性
利用EngineFramework的高可扩展性和其强大的框架模式,应用程序的维护将变得非常简单.例如当用户提出新的需求时,开发人员可以将新功能模块设计成插件组件,在保证新插件组件测试完全通过的情况下,开发人员就可以将此插件组件提交给用户,用户只需要将其(一个dll程序集)放到指定目录即可实现即插即用.在此过程中,开发人员不需要重新测试整个应用程序和编译整个程序,更不需要重新打包应用程序,这样便可以实现系统的远程维护.结合ClickOnce发布的优势,用户在启动应用程序的时候将能够自动下载插件,或者程序补丁,所有的这些操作,对用户来说都是透明的.这样的发布策略,对于一个具有多客户端应用程序的维护将变得非常轻松.
¨        易学易用
EngineFramework框架为开发人员提供了一致的编程规范,这些接口规范设计简单,开发人员只需要了解基于接口的编程原则和OOP的一些基本概念,就可以迅速进入开发状态.当然,如果开发人员对于框架设计原理和软件架构设计方面有较深研究的话,扩展开发将更加得心应手,甚至可以补充框架的不足,为框架的进一步完善提供建设性的意见.
 
 
     EngineFramework中要求所有工具按钮都实现Icommand接口,对于和MapControl或者PageLayoutControl交互的按钮还必须实现Itool接口。为了方便按钮的定制,系统提供了AbstractCommand和AbstractTool两个抽象类。其中AbstractTool又是从AbstractCommand中继承得来。下面分别以两个示例来说明按钮的定制过程。第一个示例的功能是点击一个按钮项时,将地图窗口放大到原来的两倍大小;第二个示例的功能是实现和地图控件交互的放大功能。
从以上两个示例中可以看出,定制工具项按钮功能就是如何实现AbstractCommand和AbstractTool的问题。在实现时需要注意以下几点问题:
1)              所有定制按钮都必须定义GlobeID特性,该特性将用于该按钮项的注册和查找;
2)              定制按钮必须在构造函数中填写该项的一些界面信息,如按钮标题和图标等。
3)              如果该按钮项具有非托管资源,需要重写Dispose(bool disposing)方法,以便顺利清除资源。
4)              如果需要和事件触发者进行通讯,可以利用base. EventSenderObject来获取事件触发者对象。如CommandButtonItem sender=base. EventSenderObject as CommandButtonItem。
定制功能开发完成后,就需要将其注册到系统中,可以通过ArcID.RegisterCommandItme方法在运行时对按钮进行注册。这样注册按钮具有一定的弊端,因为必须在程序启动或者插件加载前显示调用该方法。EngineFramework提供了基于配置文件的注册方法,等按钮项开发完成后,将其添加到EngineFramework的配置文件中,即可实现自动注册。该方法的原理是当主程序启动时,系统自动读取配置文件,并且对其中配置的按钮项执行注册。下面是注册后的配置表内容(红色部分)。
<?xml version="1.0"?>
<configuration>
 <configSections>
    <section name="commandSetup" type="ARSC.ArcEngine.arscFramework.CommandSection, ARSC.ArcEngine.arscFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
 </configSections>
 <commandSetup>
    <commands>
      <add CommandID="ARSC.ArcEngine.Command.ArcMap.CommandControlFixedZoomIn"
        CommandType="arscCmdTypeCommand" AssemblyPath="E:/Application Framework/EngineFramework/bin/Debug/ARSC.ArcEngine.Command.ArcMap.dll" />
         <add CommandID="ARSC.ArcEngine.Command.ArcMap.CommandControlZoomIn"
        CommandType="arscCmdTypeCommand" AssemblyPath="E:/Application Framework/EngineFramework/bin/Debug/ARSC.ArcEngine.Command.ArcMap.dll" />
    </commands>
 </commandSetup>
 <appSettings>
    <add key="ExtensionPath" value="E:/Application Framework/EngineFramework/bin/Debug/Extensions" />
 </appSettings>
<configuration>

1.1.2   工具条定制示例:
工具条是基于工具按钮项进行定制的,因此,预进行工具条的定制,必须首先定制工具按钮功能项。下面给出一个工具条定制示例:
[align=left]///<summary>[/align]
[align=left]    ///三维分析工具栏[/align]
[align=left]    ///</summary>[/align]
[align=left]    public class DDDBarDef:IBarDef [/align]
[align=left]    {[/align]
[align=left]         #region IBarDef 成员[/align]
[align=left]         #endregion[/align]
    }
工具条定制开发完成后就可以在程序启动时或者插件加载时将其添加到主程序中,可以通过如下方法进行按钮和工具条的加载:
1)   加载单独工具按钮项:
IcommandBars cmdBars;
IcommandBar viewToolBar;
cmdBars=_app.Document.CommandBars;
 
//创建视图工具栏
[align=left]viewToolBar=cmdBars.CreateBar("ViewToolBar", "视图工具栏", arscCmdBarType.arscCmdBarTypeCommonToolbar, BarDockStyle.Top);[/align]
[align=left] [/align]
[align=left]//添加放大工具按钮项到工具条[/align]
[align=left]IUID uid = new GUIDClass();[/align]
[align=left]uid.Value = "ARSC.ArcEngine.Command.ArcMap.CommandControlZoomIn";[/align]
[align=left]viewToolBar.AddCommandItem(uid);[/align]
[align=left] [/align]
[align=left]//添加缩小工具按钮添加到工具条[/align]
[align=left]uid.Value = "ARSC.ArcEngine.Command.ArcMap.CommandControlZoomOut";[/align]
[align=left]viewToolBar.AddCommandItem(uid);[/align]
[align=left] [/align]
2)   加载定制工具条:
IcommandBars cmdBars;
cmdBars=_app.Document.CommandBars;
IcommandBar viewToolBar= cmdBars.CreateBar(new DDDBarDef());
这里需要注意一点,即工具按钮的注册类型问题。系统目前支持如下几种类型的按钮项,分别是arscCmdTypeCommand(普通按钮类型)/ arscCmdTypeMenu(菜单类型)/ arscCmdTypeUIComboBoxCtrl(下拉列表框类型)/ arscCmdTypeUIColorComboBoxCtrl(颜色下拉列表框类型)/ arscCmdTypeUIEditBoxCtrl(静态文本框类型),为了扩充功能,后续将继续扩展该按钮类型。该模式的利用,避免了定制按钮项只是普通命令按钮类型,还可以通过AbstractCommand封装整个菜单项,即将整个菜单项作为单个AbstractCommand进行处理。
浮动窗体定制示例:
系统所有的浮动窗体都是由EngineFramework统一进行管理的,系统通过IdockableWindowManager接口用于浮动窗体的注册查找以及卸载功能。浮动窗体首先必须由IdockableWindoDef接口进行定义,该接口中有一个DockableControl属性,在定制开发时,通过将实际的控件(UserControl)或者窗体通过该属性返回即可。建议定制窗体界面元素利用UserControl进行定制。下面以一个例子进行说明。该例子主要定制了一个ArcToolBox的工具箱浮动窗体。ArcToolBox工具箱内部又实现了插件机制,可以实现插件自动加载。
示例代码如下:
[align=left]///<summary>[/align]
[align=left]    ///定义ArcToolBox工具箱窗体。[/align]
[align=left]    ///</summary>[/align]
[align=left]    [GlobleID("ARSC.ArcEngine.ArcToolBox.ArcToolBoxWindowDef")][/align]
[align=left]    public sealed class ArcToolBoxWindowDef:IDockableWindowDef [/align]
[align=left]{[/align]
[align=left]        //自定义UserControl控件类型。[/align]
[align=left]        private ToolBoxControl _toolBoxCtrl;[/align]
[align=left] #region IDockableWindowDef 成员[/align]
[align=left]         #endregion[/align]
}
浮动窗体定制完成后需要进行注册,注册是通过运行时代码进行注册的,注册方法如下:
IDockableWindowManager dockWinManager
= this.m_app as IDockableWindowManager;
[align=left]ArcToolBoxWindowDef toolBoxDef = new ArcToolBoxWindowDef();[/align]
[align=left] [/align]
[align=left]//注册ArcToolBox浮动窗体[/align]
[align=left]IDockableWindow arcToolBoxWindow =dockWinManager.RegisterDockableWindow(toolBoxDef);[/align]
[align=left] [/align]
[align=left]//初始化工具箱[/align]
[align=left]toolBoxDef.InitializeArcToolBox(Application.StartupPath + "//ArcToolBox");[/align]
[align=left] [/align]
[align=left]//浮动为Tab模式[/align]
[align=left]arcToolBoxWindow.DockTo(tocWindow, arscDockFlags.arscDockAsTab);[/align]
[align=left] [/align]
[align=left]//显示浮动窗体[/align]
arcToolBoxWindow.Show();
注意:开发浮动窗体时,也需要定义一个GlobeID特性用于唯一标示该浮动窗体。
上面提到ArcToolBox内部也实现为插件机制。因此,可以对其进行插件扩展,从而丰富应用程序的功能。扩展ArcToolBox工具箱非常简单,首先从BaseToolBoxItem基类型定制用户界面,重写其中Execute()方法,实现具体的功能。定制开发后,需要配置一个XML文件,该文件描述定制后其在ArcToolBox树结点中的显示内容。下面是一个配置例子和界面示例。
<?xml version="1.0" encoding="utf-8"?>
<ArcToolBox>
<ToolSet caption="Spatial Analysis">
<ToolItem caption ="Buffer Analysis" class="ARSC.ArcEngine.ToolBox.Analysis.BufferAnalysisToolItem"/>
<ToolItem caption ="Clip Analysis" class="ARSC.ArcEngine.ToolBox.Analysis.ClipAnalysisToolItem"/>
</ToolSet>
<ToolSet caption="Data Management">
<ToolSet caption="subset">
<ToolItem caption ="Buffer Analysis2" class="ARSC.ArcEngine.ToolBox.Analysis.BufferAnalysisToolItem"/>
<ToolItem caption ="Clip Analysis" class="ARSC.ArcEngine.ToolBox.Analysis.ClipAnalysisToolItem"/>
</ToolSet>
</ToolSet>
</ArcToolBox> 
该模式扩展开发比较简单,需要注意的地方就是配置文件的中class项,该项应该是类型全名。此外要求配置文件必须的命名必须是其程序集名称(去掉dll)+“ToolBox.xml”的文件。

1.1   高级插件开发实例
在EngineFramework框架下,可以将插件设计成工具条也可以设计成可浮动的窗体,甚至还可以设计成一个没有用户界面的组件服务对象。如设计一个TimerService服务类,该类主要为EngineFramework提供状态栏时间显示功能。插件开发是EngineFramework功能扩展的支撑点,为了使插件开发变得简单,EngineFramework提供了抽象基类BaseExtension,该类主要维护插件内部状态和负责插件的初始化操作。如果查看对象模型图,可以看出BaseExtension继承了IExtension接口和IextensionConfig接口。IExtension接口负责插件与主框架的通讯以及插件的初始化操作。IextensionConfig接口主要定义了插件的状态信息接口。下面给出一个示例,该示例利用插件实现一个工具栏,即当插件加载时,其为主框架生成一个工具栏。
[align=left]///<summary>[/align]
[align=left]    ///三维分析扩展模块。[/align]
[align=left]    ///</summary>[/align]
[align=left]    [GlobleID("ARSC.ArcEngine.DDDAnalysis.DDDExtension")][/align]
[align=left]    [LicenseProvider(typeof(DemoLicenseProvider))][/align]
[align=left]    public class DDDExtension : BaseExtension, INameParserService[/align]
[align=left]    {[/align]
[align=left]        public override void Startup(object initializationData)[/align]
[align=left]        {[/align]
[align=left]            //you must call the base.Startup method first.[/align]
[align=left]            base.Startup(initializationData);[/align]
[align=left]            //create the specified command bar.[/align]
[align=left]            ICommandBars cmdBars = base._app.Document.CommandBars;[/align]
[align=left]            cmdBars.CreateBar(new DDDBarDef());[/align]
[align=left]        }[/align]
[align=left]        public override void Shutdown()[/align]
[align=left]        {[/align]
[align=left]           try[/align]
[align=left]            {[/align]
[align=left]                IUID barID = new GUIDClass("ARSC.ArcEngine.DDDAnalysis.DDDAnalysisToolBar");[/align]
[align=left]                ICommandBars cmdBars = base._app.Document.CommandBars;[/align]
[align=left]                ICommandBar cmdBar = cmdBars.FindBar(barID);[/align]
[align=left]               if (cmdBar != null)[/align]
[align=left]                {[/align]
[align=left]                    cmdBars.RemoveBar(cmdBar);[/align]
[align=left]                    cmdBar.DestroyBar();[/align]
[align=left]                }[/align]
[align=left]            }[/align]
[align=left]            finally[/align]
[align=left]            {[/align]
[align=left]                //you must call the base.Shutdown lastly.[/align]
[align=left]                base.Shutdown();[/align]
[align=left]            }[/align]
[align=left]        }[/align]
[align=left] [/align]
[align=left]        #region INameParserService 成员[/align]
        #endregion
[align=left]}[/align]

[align=left]从代码中可以看出,定制一个插件非常简单,其方便性主要体现在框架的兼容性和扩展性。需要注意的是,在开发插件工具条时,同样需要注册工具条按钮项,其注册方法前面已经介绍过,这里不再赘述。此外,同样需要在插件顶部定义GlobeID特性,用于唯一标示插件。[/align]
[align=left]系统提供了插件管理器主要用于插件的加载,对于插件的加载可以根据用户的需求进行灵活的定制。如从配置文件进行插件的加载或者从指定文件夹下加载其中所有插件程序集。如果想实现自定义插件加载方法,可以继承IpluginLoadStrategy接口,实现其中的Load方法即可。插件加载的代码如下:[/align]
[align=left]////提取插件路径[/align]
[align=left]            string extPath = ConfigurationManager.AppSettings["ExtensionPath"];[/align]
[align=left]            IExtensionManager manager= ExtensionManager.GetExtensionManager(m_app);[/align]
[align=left] IPluginLoadStrategy strategy = new FolderSearchStrategy(extPath);[/align]
[align=left]            ExtensionContext context=new ExtensionContext (strategy);[/align]
[align=left]        manager.LoadExtension(context);[/align]
[align=left]系统建议提供基于配置文件的插件加载,配置方式如下:[/align]
[align=left]配置后配置文件如下(部分):[/align]
[align=left]<configSections>[/align]
[align=left]    <section name="extensionsSetup" type="ARSC.ArcEngine.arscFramework.ExtensionSection, ARSC.ArcEngine.arscFramework, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />[/align]
[align=left] </configSections>[/align]
[align=left] <extensionsSetup>[/align]
[align=left]    <extensions>[/align]
[align=left]      <add Name="DDDAnalsis" GUID="ARSC.ArcEngine.DDDAnalysis.DDDExtension"[/align]
[align=left]        PluginSort="1" ProductName="三维分析工具栏" Category="高级分析扩展模块" Description="提供高级三维功能,如登高线生成。"[/align]
[align=left]        LargeImage="LargeImage" SmallImage="SmallIamge" Developer="张学宝"[/align]
[align=left]        Copyright="www.arsc.com" UpdateURL="www.arsc.com" ResourceName="MyResource"[/align]
[align=left]        LoadImmediately="true" SupportService="true" TypeName="ARSC.ArcEngine.DDDAnalysis.DDDExtension"[/align]
[align=left]        AssemblyPath="E:/Application Framework/EngineFramework/bin/Debug/Extensions/ARSC.ArcEngine.DDDAnalysis.dll" />[/align]
[align=left]    </extensions>[/align]
[align=left] </extensionsSetup>[/align]
[align=left]为了增强EngineFramework的高可扩展性,其又设计为基于Service的架构模型,Service架构模式的思想是将每一个组件都设计成一个组件服务器,该服务器可以为其他组件提供额外功能。Service架构模式的实现可以方便的实现插件之间的通讯和消息传递,该模式的运用,可以极大的提高系统的可扩展性。为了能使插件支持组件服务,必须将配置文件中的SupportService设置为true才可以。如果想访问该组件服务,可以使用如下方法:[/align]
[align=left]InameParserService parserService=base._app.GetService(typeof(DDDExtension)) as InameParserService;[/align]
[align=left]If(parserService != null)[/align]
[align=left]{String fullName= parserService.Parse(“zhang”, “xueyou”)}[/align]

1.1   系统高级扩展实例
[align=left]利用EngineFramework可以开发行如ArcMap的应用程序,也可以扩展成ArcScene的应用程序,ArcCatalog的应用程序和ArcGlobe的应用程序。EngineFramework的战略也是为所有ArcGIS桌面应用程序提供统一的开发框架模型,在该框架下支持下进行系统功能定制。目前EngineFramework只提供了行如ArcMap的桌面框架模型,其他几个产品框架预进行后续开发。该级别的开发需要很强的软件设计能力,并且要求熟悉EngineFramework核心模块和ArcGIS框架模型。[/align]
[align=left]下面以定制ArcMap应用程序为例,进行框架扩展开发,(注:这里只给出示意性代码)[/align]
[align=left]///<summary>[/align]
[align=left]    /// ArcMap应用程序核心对象。[/align]
[align=left]    ///</summary>[/align]
[align=left]    public class MxApplication : BaseApplication, IMxApplication,IChangeDataView[/align]
[align=left]{[/align]
    // 这里重写BaseApplication 成员
[align=left]       protected override void CreateDocument()[/align]
[align=left]       {[/align]
[align=left]           Return new MxDocument();[/align]
[align=left]       }[/align]
[align=left]}[/align]
[align=left]    ///<summary>[/align]
[align=left]    ///地图文档核心对象。[/align]
[align=left]    ///</summary>[/align]
[align=left]    public class MxDocument : BaseDocument, IMxDocument, IDocumentDirty, [/align]
[align=left]        IContentsViewEdit, IdocumentEvents[/align]
[align=left]    {[/align]
[align=left]       ///全部省略[/align]
[align=left]    }[/align]
[align=left]从例子中可以看出,如果想开发ArcGlobe应用程序,只需要继承BaseApplication抽象类型,重写其中的CreateDocument()方法,该方法返回GlobeDocument类型,并且使GlobeDocument类型继承BaseDocument类型即可实现扩展框架。[/align]

(1)点击地图窗口实现放大两倍
(气死我了,怎么一粘贴代码就说不能超过20000字啊,我的可没这么多字符啊)

[align=left]///<summary>[/align]
[align=left]///固定放大[/align]
[align=left]///</summary> [GlobleID("ARSC.ArcEngine.Command.ArcMap.CommandControlFixedZoomIn")][/align]
[align=left]    public class CommandControlFixedZoomIn : AbstractCommand[/align]
[align=left]    {[/align]
[align=left]        private IMxDocument m_mxDoc;[/align]
[align=left]        public CommandControlFixedZoomIn()[/align]
[align=left]        {   //打开资源文件[/align]
[align=left]            //获取图标[/align]
[align=left]        }[/align]
[align=left]        public override void OnCreate(object hook)[/align]
[align=left]        {[/align]
[align=left]            base.OnCreate(hook);[/align]
[align=left]            m_mxDoc = base.m_app.Document as IMxDocument;[/align]
[align=left]        }[/align]
[align=left]        public override void OnClick()[/align]
[align=left]        {[/align]
[align=left]            IActiveView activeView = m_mxDoc.ActiveView;[/align]
[align=left]            IPoint centerPnt = new PointClass();[/align]
[align=left]            centerPnt.PutCoords((activeView.Extent.XMax + activeView.Extent.XMin) / 2,[/align]
[align=left]                (activeView.Extent.YMax + activeView.Extent.YMin) / 2);[/align]
[align=left] [/align]
[align=left]            IEnvelope envelop = activeView.Extent;[/align]
[align=left]            envelop.Expand(0.5, 0.5, true);[/align]
[align=left]            activeView.Extent.CenterAt(centerPnt);[/align]
[align=left]            activeView.Extent = envelop;[/align]
[align=left]            activeView.Refresh();[/align]
[align=left]        }[/align]
    }

[align=left]///<summary>[/align]
[align=left]///拉框放大地图窗口[/align]
[align=left]///</summary>[/align]
[align=left][GlobleID("ARSC.ArcEngine.Command.ArcMap.CommandControlZoomIn")][/align]
[align=left]public class CommandControlZoomIn :AbstractTool [/align]
[align=left]{[/align]
[align=left]        protected IMxDocument m_mxDoc;[/align]
[align=left]        protected INewEnvelopeFeedback m_envelopeFeedback;[/align]
[align=left] [/align]
[align=left]        //拉框起点[/align]
[align=left]        protected IPoint m_startPoint = null;[/align]
[align=left] [/align]
[align=left]        ///<summary>[/align]
[align=left]        ///构造函数执行初始化操作,主要执行图标生成[/align]
[align=left]        ///</summary>[/align]
[align=left]        public CommandControlZoomIn()[/align]
[align=left]        {[/align]
[align=left]            #region私有成员初始化[/align]
[align=left]            #endregion[/align]
[align=left]        }[/align]
[align=left]        public override void OnCreate(object hook)[/align]
[align=left]        {[/align]
[align=left]            base.OnCreate(hook);[/align]
[align=left]            m_mxDoc = base.m_app.Document as IMxDocument;[/align]
[align=left]        }[/align]
[align=left]        #region ITool 成员[/align]
[align=left]        public override void OnMouseDown(int button, int shift, int x, int y)[/align]
[align=left]        {}[/align]
[align=left]        public override void OnMouseMove(int button, int shift, int x, int y)[/align]
[align=left]        {}[/align]
[align=left]        public override void OnMouseUp(int button, int shift, int x, int y)[/align]
[align=left]        {}[/align]
[align=left] public override bool Enabled[/align]
[align=left]        {[/align]
[align=left]            return true;[/align]
[align=left]        }[/align]
[align=left]        #endregion[/align]
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐