Z-GIS
Z-GIS简介(Z-GIS框架 Z-GIS框架的运行环境 Z-GIS的名称由来 Z-GIS的设计思想)
Z-GIS二次开发范例(C#)(创建启动画面 创建用户登录模块 创建命令 创建地图交互工具 创建Combobox下拉框 创建任意复杂控件 二次开发高级功能)
Z-GIS简介
Z-GIS框架
Z-GIS是一个企业级的通用插件式GIS应用程序框架,Z-GIS框架能够从根本上解决架构稳定性和需求多变性之间的矛盾。
Z-GIS框架不仅仅支持二次开发,还支持二次设计。Z-GIS系列软件就是在Z-GIS统一框架的基础上进行构建(设计、开发)的。
Z-GIS框架完全可以应用于任何领域、任何类型、任何规模、甚至任何开发语言的GIS产品(或项目),同时不需要对Z-GIS框架本身做任何改动。基于Z-GIS框架进行产品(线)开发,将大大减少开发的工作量。我们会提供相应的开发源码来验证、说明Z-GIS统一框架基本特性。
在Z-GIS框架安装程序中,暂时只提供Z-GIS框架在国土行业的应用范例及C#(.NET)开发范例源码,如需要其他语言的开发范例源码请联系作者!基于Z-GIS框架进行产品开发需要符合COM规范,但也并非必须完全符合COM规范。
Z-GIS框架的运行环境
Z-GIS框架是基于某个特定的GIS平台而构建的高级的、企业级应用框架;所以,Z-GIS框架运行环境取决特定的GIS平台。如:如果是基于ESRI公司的ArcEngine构建的Z-GIS框架,那么它的运行环境则是Windows + ArcEngine;如果是基于超图的GIS平台构建的Z-GIS框架,那么它的运行环境则是Windows + 超图的GIS环境。
Z-GIS的名称由来
Z-GIS框架由周健设计并加以实现。Z就是周汉语拼音的首字母。
Z-GIS的设计思想
Z-GIS的设计思想是封装变化部分,固化稳定部分;严格遵循开闭原则,针对接口编程;做到底层实现依赖高层抽象。
封装变化主要是指针对业务组件部分的封装,让业务组件部分可以独立演化而不影响其他部件,从而保证软件的高内聚低偶合; 固化稳定部分主要是指框架本身的稳定性,稳定的部分应该固化从而最大限度的保证软件的稳定性。
开闭原则是指对扩展开放、修改关闭;针对接口编程(即针对抽象编程),可以从很大程度上保证软件对开闭原则的遵循。
要做到底层实现依赖高层抽象,是因为底层业务逻辑的实现往往和用户的需求密切相关;用户的需求是多变的,因而底层的实现是多变的、在稳定性方面是非常脆弱的。高层抽象主要指两个方面,一是指框架,框架位于系统的最高层,其和用户的需求没有直接关系;二是指框架提供的接口,框架提供的接口除了用于实现系统必要功能以外,便主要是用于扩展,这些和用户的需求也没有直接的关系;因此,高层抽象部分应该是稳定的。所以,从总体上保证底层实现依赖高层抽象,是保证软件设计合理性的重要手段之一。
Z-GIS接口
顶级接口
由Z-GIS框架直接提供的主要接口如下:
IZhoujianApplication
IZhoujianCommand 该接口继承于ICommand接口。
IZhoujianTool 该接口继承于ITool接口。
IZhoujianControl 该接口用于实现任意复杂控件在界面中显示,实现该接口必须要实现IZhoujianCommand。
IZhoujianStartForm
IZhoujianProgressBar
IZhoujianStatusBar
间接接口
Z-GIS是支持二次设计的,在Z-GIS二次设计时设计的接口称为间接接口:如在国土行业的应用范例中,对Z-GIS进行了二次设计。在二次设计中,设计了一个通用的(反馈)消息的组件,该组件对应的接口是IZhoujianMessageBox。类似的接口还有IZhoujianCJCommandLine、IZhoujianCJParameter、IZhoujianLayerControl、IZhoujianDatasource等等。
间接接口的使用
所有的间接接口都是要注册到Z-GIS框架中的,注册过程是可视化的。对于已经注册在Z-GIS系统中的间接接口的使用方法是:通过调用IZhoujianApplication接口提供的方法(函数)先获取相应的接口,再使用相应的接口提供方法(或属性)。
Z-GIS二次开发范例(C#)
创建启动画面
基于Z-GIS框架进行二次开发时,可以根据产品(或项目)的需求,灵活创建个性化的启动界面。创建个性启动界面只要实现IZhoujianStartForm接口即可。范例如下:(注本功能代码为Delphi实现,其他均为C#)
unit unt_ZhoujianCJStartFormIMP;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, ActiveX, Classes, ComObj, ZhoujianCJ_TLB, StdVcl,
zhoujianUI_Tlb, forms, frm_CJForm;
type
TCJStartForm = class(TTypedComObject, IZhoujianStartForm)
protected
function Show: HResult; stdcall;
function Close: HResult; stdcall;
function SendMessage(const MessageInfo: WideString): HResult; stdcall;
function Get_Description(out Value: WideString): HResult; stdcall;
private
frm: TfrmCJForm;//定义一个窗体,作启动画面用
end;
implementation
uses ComServ;
//返回本启动画面的描述信息
function TCJStartForm.Get_Description(out Value: WideString): HResult;
begin
Value := ''采集子系统启动画面(Z-GIS系列软件)''
end;
//向启动画面发送当前程序正在启动的相应信息
function TCJStartForm.SendMessage(const MessageInfo: WideString): HResult;
begin
frm.lblinfo.Caption := MessageInfo;
Application.ProcessMessages;
end;
//程序启动后,做销毁操作
function TCJStartForm.Close: HResult;
begin
frm.Free;
frm := nil;
end;
//显示启动画面
function TCJStartForm.Show: HResult;
var
L, T, H, V: Longint;
begin
frm := TfrmCJForm.Create(Application);
H := GetSystemMetrics(SM_CXSCREEN);
V := GetSystemMetrics(SM_CYSCREEN);
L := Round((H / 2)) - Round((frm.Width / 2));
T := Round((V / 2)) - Round((frm.Height / 2));
frm.Left := L;
frm.Top := T;
AnimateWindow(frm.Handle, 1000, AW_CENTER);
AnimateWindow(frm.Handle, 400, AW_CENTER + AW_HIDE);
AnimateWindow(frm.Handle, 300, AW_CENTER);
end;
initialization
TTypedComObjectFactory.Create(ComServer, TCJStartForm, Class_CJStartForm,
ciMultiInstance, tmApartment);
end.
创建用户登录模块
对于一般的管理信息系统而言,都会有用户登录模块(即完成用户登录,验证用户合法性的功能)。对于GIS类型的信息系统来说,用户登录模块也是必不可少的。基于Z-GIS框架进行二次开发要增加这样的一个功能,是通过Z-GIS中间件来实现的;在Z-GIS框架中只要实现一个IZhoujianMidWare接口即可完全这样的功能。具体代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ZhoujianUI;
using System.Windows.Forms;
namespace UserLoginSpace
{
[Guid("3308ca48-c67e-4ed9-a283-d6b66fd66ab3")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("MDataSource.Class1")]
public class UserLoginIMP : IZhoujianMidWare, IUserInfo
{
private IZhoujianApplication mApp = null;
private IUserInfo mUserInfo = null;
private string _UserDepartment,_UserName;
//假设IUserInfo接口只有两个元素,分别是UserName,UserDepartment,表示用户名和所属部门
#region IUserInfo 成员
public string UserName
{
get { return _UserName; }
}
public string UserDepartment
{
get { return _UserDepartment; }
}
#endregion
#region IZhoujianMidWare 成员
public string Name
{
get { return "User Login"; }
}
public void OnCreate(IZhoujianApplication ZApplication)
{
//首先,让用户进行认证, frmLogin是一个已经存在的窗体,作用户登录界面
mUserInfo = this as IUserInfo;
frmLogin frm = new frmLogin(mUserInfo);
if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
{ //通过认证
mApp = ZApplication;
//通过验证以后,可能会根据针对不同用户进行不同的初始化操作
//在此处添加业务代码
//最后在应用程序的状态栏上显示当前登录的用户信息
mApp.StatusBar.setValue(1,string.format("用户名:{0} 部门: {1}",mUserInfo.UserName,mUserinfo.UserDepartmen));
}
else
{ //否则,结束应用程序
ZApplication.Quit();
}
}
public object get_MidWare(string UniqueName)
{ //在实际的应用中可能要根据UniqueName参数的情况不同而返回不同的值,这里只返回了用户信息
//本例中,对于其他模块还可以通过接口查询操作来获取用户信息,但Z-GIS推荐使用本方法。
return mUserInfo;
}
#endregion
}
}
创建命令
创建命令只要实现IZhoujianCommand接口即可,代码如下:
//第一步:首先是引用相关的命名空间
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ZhoujianUI;
namespace CommandDEmo
{
[Guid("d21d37d1-2599-4ce4-a555-4c079071b86f")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("CommandDEmo.Class_CommandDEmo")]
//借助相应的类来实现IZhoujianCommand
public class CommandDemoIMP: IZhoujianCommand
{
#region IZhoujianCommand 成员
/// <summary>
/// 设置命令按钮的图标
/// </summary>
public int Bitmap
{
get
{
return Resource1.forCommand.GetHbitmap().ToInt32();//注意一定要是Bitmap Handle
}
}
//设置命令按钮标题
public string Caption
{
get { return "demo Command"; }
}
public string Category
{
get { return "Demo"; }
}
public bool Checked
{
get { return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "【demo】创建命令按钮!"; }
}
public string Name
{
get {return "command demos"; }
}
int i = 0;
//命令被点击时,要执行相关操作的入口
public void OnClick()
{
MessageBox.Show("我被点了"+ ++i+"下!!!") ;
}
public void OnCreate(object hook)
{ //这里可以加入初始化时要做的操作
//hook 可以通过强制类型转换成IZhoujianApplication
}
public string Tooltip
{//这是命令按钮的提示信息
get { return Message; }
}
#endregion
}
}
创建地图交互工具
//创建命令除了要实现IZhoujianCommand接口,同时还要实现IZhoujianTool接口,IZhoujianTool定义了所有与地图交互操作的方法。代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using ZhoujianUI;
using System.Windows.Forms;
namespace ToolEDemo
{
[Guid("ca5fc134-a474-450f-89d3-f210cacce31c")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ToolEDemo.Class1")]
public class DemoToolIMP: IZhoujianCommand,IZhoujianTool
{
ContextMenuStrip mPopMenu =null;
IZhoujianApplication mApp = null;
#region IZhoujianTool 成员
public int Cursor
{
get
{
return Resource1.forCursor.Handle.ToInt32();
}
}
/// <summary>
/// 当激活其他工具时…………
/// </summary>
/// <returns></returns>
public bool Deactivate()
{
mApp.StatusBar.SetValue(1, "");
return true;
}
public bool OnContextMenu(int x, int y)
{
if (mPopMenu != null) mPopMenu.Show(x, y);
return true;
}
public void OnDblClick()
{
MessageBox.Show("在地图上双击了一次!");
}
public void OnKeyDown(int keyCode, int shift)
{
//MessageBox.Show("OnKeyDown");
}
public void OnKeyUp(int keyCode, int shift)
{
//MessageBox.Show("OnKeyUp");
}
/// <summary>
///
/// </summary>
/// <param name="button"></param>
/// <param name="shift"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public void OnMouseDown(int button, int shift, int x, int y)
{
//MessageBox.Show("OnMouseDown");
}
/// <summary>
/// 处理鼠标在地图上移动时的事件
/// </summary>
/// <param name="button"></param>
/// <param name="shift"></param>
/// <param name="x"></param>
/// <param name="y"></param>
public void OnMouseMove(int button, int shift, int x, int y)
{
mApp.StatusBar.SetValue(1, string.Format("正在移动鼠标,位置X={0};Y={1}【注:是屏幕坐标】",x,y));
}
public void OnMouseUp(int button, int shift, int x, int y)
{
//MessageBox.Show("OnKeyDown");
}
public void Refresh(int hdc)
{
//该方法高级操作才会用到
}
#endregion
#region IZhoujianCommand 成员
public int Bitmap
{
get
{
return Resource1.forCommand.ToBitmap().GetHbitmap().ToInt32();//注意:返回的必须是bitmap handle
}
}
public string Caption
{
get { return "Tool例"; }
}
public string Category
{
get { return "工具"; }
}
public bool Checked
{
get { return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "这是一个鼠标与地图进行交互的范例!" ; }
}
public string Name
{
get { return "tool demox"; }
}
public void OnClick()
{
}
public void OnCreate(object hook)
{
mApp = hook as IZhoujianApplication;
InitializePopMenu();
}
/// <summary>
/// 初始快捷菜单
/// (如果,不熟悉通过代码进行快捷菜单的初始化,可以在窗体设计器中进行相应操作及设计 )
/// </summary>
private void InitializePopMenu()
{
if (mPopMenu == null) mPopMenu = new ContextMenuStrip();
mPopMenu.Items.Add("第1项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第2项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第3项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第4项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第5项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第6项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第7项").Click += new EventHandler(DemoToolIMP_Click);
mPopMenu.Items.Add("第8项").Click += new EventHandler(DemoToolIMP_Click);
}
/// <summary>
/// 处理快捷菜单事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void DemoToolIMP_Click(object sender, EventArgs e)
{
MessageBox.Show((sender as ToolStripItem).Text + ",被点了!");
}
public string Tooltip
{
get { return Message; }
}
#endregion
}
}
创建Combobox下拉框
//在工具栏上创建下拉框除了要实现IZhoujianCommand接口,同时还要实现IZhoujianControl接口,IZhoujianControl接口只定义了一个方法,用于返回可视化Windows控件的句柄。代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using ZhoujianUI;
namespace ComboboxDemo
{
[Guid("191e0060-f725-4144-ac16-0bbae7571a36")]
[ClassInterface(ClassInterfaceType.None)]
[ProgId("ComboboxDemo.Class1")]
public class ComboBoxIMP: IZhoujianCommand, IZhoujianControl
{
IZhoujianApplication mApp = null;
ComboBox mCbx = new ComboBox();
#region IZhoujianControl 成员
public int WinControlHandle
{
get { return mCbx.Handle.ToInt32(); }
}
#endregion
#region IZhoujianCommand 成员
public int Bitmap
{
get { return -1; }
}
public string Caption
{
get { return "ComboBox"; }
}
public string Category
{
get { return "控件案例"; }
}
public bool Checked
{
get { return false; }
}
public bool Enabled
{
get { return true; }
}
public int HelpContextID
{
get { throw new NotImplementedException(); }
}
public string HelpFile
{
get { throw new NotImplementedException(); }
}
public string Message
{
get { return "这是一个在工具栏上新增ComboBox范例。"; }
}
public string Name
{
get { return "combexTest"; }
}
public void OnClick()
{
//这个方法不会被使用到
}
public void OnCreate(object hook)
{
mApp = hook as IZhoujianApplication;
initializeCombobox();
}
/// <summary>
/// 初始化Combobox
/// 并增加items 增加事件
/// </summary>
private void initializeCombobox()
{
if (mCbx == null) mCbx = new ComboBox();
mCbx.Items.Add("第一项");
mCbx.Items.Add("第二项");
mCbx.Items.Add("第三项");
mCbx.Items.Add("第四项");
mCbx.Items.Add("第五项");
mCbx.Items.Add("第六项");
mCbx.MouseEnter += new EventHandler(mCbx_MouseEnter);
mCbx.MouseLeave += new EventHandler(mCbx_MouseLeave);
mCbx.SelectedValueChanged += new EventHandler(mCbx_SelectedValueChanged);
}
/// <summary>
/// 当ComboBox选项改变的时候,将其当前值在程序标题栏上显示
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_SelectedValueChanged(object sender, EventArgs e)
{
mApp.Caption = mCbx.SelectedItem.ToString();
MessageBox.Show("您选择了【"+mCbx.SelectedItem.ToString()+"】");
}
/// <summary>
/// 清除任务栏上 提示信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_MouseLeave(object sender, EventArgs e)
{
mApp.StatusBar.SetValue(0, "");
}
/// <summary>
/// 在任务栏上显示 提示信息
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void mCbx_MouseEnter(object sender, EventArgs e)
{
mApp.StatusBar.SetValue(0, Tooltip);
}
public string Tooltip
{
get { return "这是一个在工具栏上新增ComboBox范例。"; }
}
#endregion
}
}
创建任意复杂控件
在菜单或工具栏中创建任意复杂控件的方法同创建Combobox类似,只要在IZhoujianControl的 public int WinControlHandle 中返回任意复杂控件的句柄即可。代码如下:
public int WinControlHandle
{
get {
return hComplexHandle; //hComplexHandle为任意复杂控件的句柄
}
}
二次开发高级功能
由于高级功能比较复杂(会涉及二次设计、多个模块间的通信及模块的依赖关系),所以代码会非常的多。如要了解二次开发高级功能,可以安装Z-GIS框架程序,其中包含少量二次开发的高级功能。