“纵生”式开发入门

最后更新时间:2019年8月16日

3.3.1 搭建开发环境

本章节涉及MapGIS三维桌面GIS示例开发环境如下:

 Micorsoft Visual Studio 2010;

 MapGIS开发授权安装包;

 MapGIS桌面开发包安装包;

 MapGIS插件扩展开发向导。

前三个软件的安装过程请参考前面内容。为了方便“纵生”式开发用户,快速的开发出符合标准规范的功能插件,MapGIS提供了专门的MapGIS插件导向包,包含了很多MapGIS插件资源,在司马云的产品开发页面下载插件扩展开发向导的安装包程序,双击下载后的VstInstaller.exe程序进行安装,具体安装过程如下:

安装向导

图 3-23 安装向导

安装过程

图 3-24 安装过程

完成安装

图 3-25 完成安装

3.3.2 三维可视化入门范例实现

3.3.2.1 创建插件工程

(1) 新建MapGIS插件项目:打开Microsoft Visual Studio开发工具,“文件-新建-项目”,项目名称“InitOpen”:

新建插件项目界面图

图 3-26 新建插件项目界面图

(2) 配置插件属性:在上一步窗口单击“确定”之后,在弹出窗口中勾选“传统风格界面元素”下的“MenuBar”(即界面表现为菜单插件),以及“插件元素”下的“Command”(即命令式插件):

配置插件属性示意图

图 3-27 配置插件属性示意图

注意:此处创建的命令式插件同时为其创建了界面元素(MenuBar),即该命令式插件绑定有界面元素; 您亦可只创建命令式插件,由后续在数据中心设计器中自动绑定到对应界面元素下(如菜单栏、工具条等)。

(3) 配置“插件元素”属性:单击“插件元素”下的“Commad”节点设置“Caption”属性为“打开文档”,即插件显示名称,如下图:

配置插件元素属性示意图

图 3-28 配置插件元素属性示意图

(4) 配置“传统风格界面元素”属性:首先单击“传统风格界面元素”下的“MenuBar” 节点,如下图:

配置菜单插件属性示意图

图 3-29 配置菜单插件属性示意图

然后添加子菜单项,具体方法:单击上图“数据”栏下的“Items”后的按钮,在弹出的“Item集合编辑器”对话框中点击“添加”按钮,并配置右侧该菜单项的属性“Key”为“InitOpen.Command1”,格式:插件命名空间.插件类名。如下图:

给菜单栏绑定命令按钮示意图

图 3-30 给菜单栏绑定命令按钮示意图

最后点击上图“确定”按钮,弹出如图 3-30 配置item属性后的菜单插件所示界面,再次单击“创建”按钮,实现命令式菜单插件的创建。

配置item属性后的菜单插件

图 3-31 配置item属性后的菜单插件

创建成功后,InitOpen工程如下图:

Command1.cs代码示意图

图 3-32 Command1.cs代码示意图

3.3.2.2 引入开发库

为项目添加必要的MapGIS程序集引用,这里需引用MapGIS.GeoMap.dll、MapGIS. PluginEngine.dll、MapGIS.SceneControl.dll等。

3.3.3 加载场景

(1) 在“InitOpen”项目中添加类“ContentsView”项,方法:右键InitOpen工程添加新建项,在弹出的“新建项-InitOpen”中,在中间栏中选择“类”项,命名为“ContentsView1”。

(2) 在新的ContentsView1.cs文件中,添加对MapGIS.PluginEngine命名空间的引用。

程序代码 3.10 MapGIS.PluginEngine命名空间引用

    using MapGIS.PluginEngine;
    using MapGIS.Scene3D;
    using MapGIS.GeoMap;
    using System.Windows.Forms;
    using System.Drawing;

(3) 修改“ContentsView1”类,使该类继承于MapGIS.PluginEngine. ISceneContentsView场景视图类,将ISceneContentsView插件中的SceneControl场景控件绑定到ContentsView1插件中,在ContentsView1.cs文件中添加如下函数,具体代码如下:

程序代码 3.11 ContentsView1类中初始代码

    public class ContentsView1 : ISceneContentsView
    {      
        IApplication app = null;//应用程序
        MapGIS.Scene3D.SceneControl control = null;//三维场景控件
        ITool ISceneContentsView.ActiveTool//激活工具
        {
            get
            {
                return null;
            }
            set
            {                
            }
        }
        SceneControl ISceneContentsView.SceneControl//绑定场景控件
        {
            get { return this.control; }
        }
        Bitmap IContentsView.Bitmap
        {
            get { return null; }
        }
        string IContentsView.Caption//视图标题
        {
            get { return "场景视图"; }
        }
        bool IContentsView.ControlBox//控制箱
        {
            get { return true; }
        }
        bool IContentsView.InitCreate
        {
            get { return true; }
        }
        string IContentsView.Name
        {
            get { return "ContentsView1"; }
        }
        Control IContentsView.ObjecthWnd
        {
            get { return this.control; }
        }
        void IContentsView.OnActive(bool isActive)
        {            
        }
        void IContentsView.OnClose()
        {           
            if (this.control != null)
            {
                this.control.Dispose();
                this.control = null;
            }
        }
        void IContentsView.OnCreate(IApplication app)
        {
        }        
    }

注意:只要新建的类继承于IPlugin,则该类就相当于自定义的MapGIS 10插件,就可以被当成插件进行使用。

(4) 在OnCreate方法中初始化类的全局变量,以及注册相应的插件加载事件和卸载事件,具体代码如下:

程序代码 3.12 OnCreate方法具体代码

     void IContentsView.OnCreate(IApplication app)
        {
            //初始化
            this.app = app;
            this.control = new SceneControl();
            //注册插件加载事件
            this.app.PluginContainer.PluginLoadedEvent += new PluginLoadedHandler(PluginContainer_PluginLoadedEvent);
            //注册插件卸载事件
            this.app.PluginContainer.PluginUnLoadedEvent += new PluginUnLoadedHandler(PluginContainer_PluginUnLoadedEvent);
        }

(5) 在插件加载事件中实现打开一幅指定路径的地图文档,并将文档处于第一个的场景显示在SceneControl场景控件中,在插件卸载事件中释放相应的资源,具体代码如下:

程序代码 3.13显示场景关键代码

     public void PluginContainer_PluginLoadedEvent(IPlugin plugin)
        {
            Scene curScene = null;//场景对象
            Document doc = this.app.Document;//文档对象
            Scenes sceneList = doc.GetScenes();//场景列表
            if (sceneList == null || sceneList.Count <= 0)
            {
                doc.Open(@"D:\MapGIS 10\Sample\三维模型图.mapx");//打开文档
                sceneList = doc.GetScenes(); 
            }
            if (sceneList != null && sceneList.Count > 0)
            {
                curScene = sceneList.GetScene(0);//获取场景对象
                G3DLayer layer = curScene.GetLayer(0);//获取三维图层对象
                if (layer != null)
                {
                    layer.State = LayerState.Visible;//设置图层状态为可见
                }
                control.Mode = curScene.Mode;//设置场景模型
                control.Append(curScene);//添加场景
                control.Reset();//场景复位
            }        
        }

        #region  插件卸载事件
        public void PluginContainer_PluginUnLoadedEvent(IPlugin plugin)
        {
            if (plugin != null && plugin is ISceneContentsView)
            {
                IContentsView view = null;
                this.app.PluginContainer.ContentsViews.TryGetValue(typeof(ContentsView1).ToString(), out view);//获取当前场景
                if (view != null)
                {
                    view.OnClose();
                }
               // 去除事件监听
                this.app.PluginContainer.PluginLoadedEvent -= new PluginLoadedHandler(PluginContainer_PluginLoadedEvent);
            }
        }
      #endregion

注意:打开的是指定路径的地图文档,doc.Open(@"D:\MapGIS 10\Sample\三维模型图.mapx");若该路径不存在,则不显示地图文档。

(6) 右击“InitOpen”项目,在弹出菜单中选择“生成”项,将编译生成该插件文件,生成后的默认所在目录如:…\InitOpen\InitOpen\bin\Debug\InitOpen.dll。将生成的插件文件“InitOpen.dll”拷贝到平台安装目录“..\MapGIS\Program\plugin”目录下,然后打开数据中心设计器(..\MapGIS\Program\MapGIS.AppLoader.exe),实现加载场景功能。生成插件文件如下图所示:

生成InitOpen插件示意图

图 3-33 生成InitOpen插件示意图

(7) 至此为止就完成在插件创建时,就可以打开一幅指定路径的地图文档的功能。在数据中心设计器加载完MapGIS.WorkSpace.Plugin.dll和InitOpen.dll这两个库之后,就可以打开刚才指定路径的地图文档,具体效果如下图:

生成InitOpen插件示意图

图 3-34 生成InitOpen插件示意图

说明:数据中心设计器操作方法如下:

打开MapGIS Visual Studio.exe后,点击“新建解决方案”,在解决方案目录下,右键点击“引用”,选择“添加引用”,选择“..\MapGIS\Program\plugin”目录下所需的插件即可。然后右键单击解决方案,选择“运行”。

3.3.4 浏览场景

在命令按钮插件Command1中实现打开指定路径的地图文档,并将该地图文档显示到SceneControl控件中的功能,实现方法如下:

打开Command1.cs文件,添加如下命名空间引用:

程序代码 3.14 添加命名空间引用

    using System.Drawing;
    using MapGIS.PluginEngine;
    using MapGIS.Scene3D;
    using MapGIS.GeoMap;
    using System.Windows.Forms;

定义全局变量:

程序代码 3.15 定义全局变量

IApplication hk = null;//应用程序 在Command1.cs的OnCreate方法中,添如下代码,以获取当前视窗的应用程序,代码如下:

程序代码 3.16 获取当前应用

    public void OnCreate(IApplication hook)
        {
            hk = hook;
        }

Command1.cs的OnClick方法中,添加如下代码:

程序代码 3.17 OnClick方法的关键代码

      public void OnClick()
        {
            //打开地图文档
            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Filter = "地图文档(*.mapx)|*.mapx";
            if (openFileDialog.ShowDialog() == DialogResult.OK)
            {
                //获取地图文档路径
                string fileName = openFileDialog.FileName;
                if (this.hk != null && !String.IsNullOrEmpty(fileName))
                {
                    //地图文档对象
                    Document doc = this.hk.Document;
                    //打开地图文档
                    doc.Open(@fileName);
                    //定义场景对象
                    Scene curScene = null;
                    Scenes sceneList = doc.GetScenes();
                    if (sceneList != null && sceneList.Count > 0)
                    {//获取地图文档中第一个场景
                        curScene = sceneList.GetScene(0);
                        //获取场景中第一个图层
                        G3DLayer layer = curScene.GetLayer(0);
                        if (layer != null)
                        {//设置图层状态为可见
                            layer.State = LayerState.Visible;                    
                        }
                    }               
                }
            }            
        } 
 

编译插件,并将生成的插件拷贝到拷贝到平台安装目录“..\MapGIS\Program\plugin”目录下,然后打开插件加载器(..\MapGIS\Program\MapGIS.AppLoader.exe),在MapGIS.AppLoader中依次添加MapGIS.WorkSpace.Plugin.dll和InitOpen.dll两个插件(注意先后顺序),效果如图 3-35 打开文档”按钮示意图所示:

打开文档”按钮示意图

图 3-35 打开文档”按钮示意图

选择地图文档路径示意图

图 3-36 选择地图文档路径示意图

打开三维景观建模.mapx地图文档示意图

图 3-37 打开三维景观建模.mapx地图文档示意图

说明:三维景观建模.mapx地图文档为MapGIS提供的示例数据,位于:..\MapGIS\sample下。

3.3.5 三维量算

场景中必须至少有一个处于可见状态或者以上状态的地形图层时,才可以实现三维量算功能。 在“InitOpen”项目中添加一个“MapGIS模板”的菜单栏(MenuBar),命名为MenuBar2.cs,设置菜单的“名称”属性为“地形分析”,添加方法为,右键InitOpen工程,选择【添加】【新建项】,在弹出的界面中选择如图 3-38 添加“MapGIS模板”所示信息:

添加“MapGIS模板”

图 3-38 添加“MapGIS模板”

点击上图的【添加】按钮,弹出如下界面,设置Name属性为“地形分析”,点击图 3-39 设置Name属性所示的【确定】按钮,完成菜单添加。

设置Name属性

图 3-39 设置Name属性

继续添加一个命令按钮插件,右键InitOpen工程,选择【添加】【新建项】,选择相关项如图 3-40 Command模板所示:

Command模板

图 3-40 Command模板

点击上图的【添加】按钮,在弹出的界面中设置Name属性为“ToolCmd”;Caption属性设置为“距离量算”,如图 3-41所示:

设置Command属性

图 3-41 设置Command属性

点击上图中的【确定】按钮,完成添加操作。

将ToolCmd命令按钮插件添加到“地形分析”菜单项中,在MenuBar2.cs文件中的关键代码如下:

程序代码 3.18将ToolCmd插件绑定到菜单项中的关键代码

       public MenuBar2()
        {
            this.items = new IItem[1];
            this.items[0] = new Item();
            this.items[0].Key = "InitOpen.ToolCmd";
            this.items[0].Group = false;
            this.items[0].ShowLargeImage = false;                     
        }

在Command2.cs中添加如下命名空间的引用:

程序代码 3.19 引用命名空间

    using MapGIS.PluginEngine;
    using System.Drawing;
    using MapGIS.Scene3D;

在Command2.cs中定义如下全局变量:

程序代码 3.20 定义全局变量

    IApplication hk=null;//初始化应用
    SceneControl sceneCtrl = null;//初始化三维场景控件

在Command2.cs的OnCreate方法中添加如下代码:

程序代码 3.21 OnCreate方法

    public void OnCreate(IApplication hook)
        {
            hk = hook;
        }

在Command2.cs的OnClick方法中实现距离量算功能,具体代码如下:

程序代码 3.22量算工具关键代码

    public void OnClick()
        {
            //获取当前场景
            IContentsView view = null;            this.hk.PluginContainer.ContentsViews.TryGetValue(typeof(ContentsView1).ToString(), out view);
            if (view == null)
                return;
            //获取当前场景控件  
            sceneCtrl = view.ObjecthWnd as SceneControl;
            //量算工具
            LengthMeasureTool lengthTool = new LengthMeasureTool(sceneCtrl);
            //设置量算类型为表面距离
            lengthTool.SetMeasureType(LengthMeasureType.Surface_Length , 6);
            //启动量算工具
            lengthTool.Start();
        }  

保存并编译工程,将生成的InitOpen.dll拷贝到“..\MapGIS\Program\plugin”目录下,然后打开插件加载器(..\MapGIS\Program\MapGIS.AppLoader.exe),加载InitOpen.dll插件,距离量算效果如图 3-42所示:

量算距离效果示意图

图 3-42 量算距离效果示意图

3.3.6 应用搭建与打包

MapGIS数据中心设计器采用自动编译的形式编译工程,每次保存和运行工程时,系统将自动编译工程文件。下面为编译工程后打包输出的具体实现步骤:

(1) 新建解决方案,打开数据中心设计器MapGIS Visual Studio.exe(..\MapGIS\Program目录下),点击【文件】【新建】,新建一个“传统风格程序”,命名为“三维可视化示例”;在“引用”中添加(..\MapGIS\Program\plugin目录下)MapGIS.WorkSpace.Plugin.dll和InitOpen.dll这两个库,效果如图 3-43 所示:

添加引用库示意图

图 3-43 添加引用库示意图

(2) 右键“三维可视化示例”工程,选择“生成”菜单,编译工程。应用程序默认生成到..\MapGIS\Program\plugin目录下,双击生成的“三维可视化示例.exe”或直接在“数据中心设计器”中按F5,运行应用程序,运行效果如下图所示:

三维可视化示例应用运行效果图

图 3-44 三维可视化示例应用运行效果图

(3) 右键单击左侧“解决方案‘三维可视化示例’”节点项,弹出右键菜单,如下所示:

编译工程示意图

图 3-45 编译工程示意图

(4) 点击上图中的“生成插件包”项,弹出“生成插件包”对话框,可以在“参数”列中设置包的标志图片、包的预览图片、文件、目录等信息,默认将包中所涉及的插件文件都包含其中,如下图所示:

生成插件包示意图

图 3-46 生成插件包示意图

(5) 点击图 3-46 的“生成”按钮,开始编译工程,其输出窗口信息如下图所示。编译时默认将生成的包文件输出到MapGIS的Program目录下,生成的包文件后缀名为*.dczip,分别如图 3-47 、图 3-48 所示:

插件包生成成功示意图-1

图 3-47 插件包生成成功示意图-1

插件包生成成功示意图-2

图 3-48 插件包生成成功示意图-2

3.3.7 应用上传

通过打包工具生成的桌面应用包,可上传到www.smaryun.com,供终端用户共享使用。可参考: http://www.smaryun.com/dev/resource_center.html#/type27/tag183/page1/doc698 《桌面“框架+插件”产品开发上架及购买使用帮助文档》,此处不再赘述。