SuperMap Objects是一款相当不错的GIS开发平台,封装了好多实用而且比较方便二次开发的接口,同时安装Objects后,SuperMap提供了详细的开发联机帮助以及部分范例说明,给GIS开发者提供了不少便利。但是由于各方面的原因,目前的帮助文档是基于VB开发环境整理的。对于其他开发环境(比如VC,Delphi等)的帮助说明,不能通过联机帮助进行查阅,开发者一般也就只能参考SuperMap提供的相关环境下的示范工程。本文重点介绍VC开发环境下使用Objects若干环节的开发说明,在以后的文章中,大明将陆续为大家对其他开发环境下如何进行Objects开发进行详尽描述。
| 在使用VC进行Objects开发,安装了Objects后,我们可以先熟悉一下Objects的主要目录,尤其是Bin文件夹以及Sample Code Library文件夹。Objects目录的Bin文件夹主要是SuperMap的控件、注册工具和反注册程序,为了方便在相关开发环境中调用而封装出来的包裹类(InterfaceClass和TypeLibrary目录下的文件)。Sample Code Library文件夹下罗列了目前各主流开发环境下的范例程序,在进行VC二次开发的时候如果遇到相关功能接口使用问题,可以参考此目录下的VC范例相关工程。 |
| InterfaceClass文件夹下的.cpp和.h包裹类文件,一般用于单(多)文档或者对话框工程中需要动态创建SuperMap相关控件时使用。TypeLibrary目录下的文件一般是在VC类向导中从TypeLib添加对象时使用。 |
| 开发时相关控件可以手工添加,也可以通过SuperMap提供的包裹类,动态创建控件。手工添加控件,通过手工设置控件变量时,在工程目录会自动生成很多SuperMap相关类的文件,看起来比较繁杂。如果想通过手工创建控件,那么在定义控件变量的时候,建议将SuperMap类文件夹下的文件拷贝到工程目录,添加到工程中,在头文件中定义控件变量,然后通过DoDataExchange进行变量跟控件的对应设置。 |
| //控件对象定义举例: CSuperMap m_SuperMap;//地图控件变量的定义 CSuperWorkspace m_SuperWorkspace;//工作空间控件变量定义 |
| VC开发对话框工程中一般是手工添加SuperMap相关控件,但是有时由于工程的特殊性(比如单/多文档或者程序需要)经常需要动态创建控件。对于动态创建控件的程序,好多客户反映编译出来的Release版本即使在有运行许可的情况下也不能执行程序,报找不到许可的错误。对于这种情况的问题一般是由于动态创建控件时没有传入BSTR类型参数导致的。正确动态创建控件示范代码如下: |
| //创建SuperMap相关实例 BSTR bStr=L"SuperMap"; m_SuperWkspace.Create("Workspace", WS_CHILD, CRect(0, 0, 10, 10), this, 1001, NULL, false,bStr); m_SuperMap.Create("SuperMap", WS_CHILD|WS_VISIBLE, CRect(0, 0, 10, 10), this, 1002, NULL, false,bStr); |
| 加载了SuperMap相关类后,我们可以使用类里面提供的对象,以及对象中封装的属性、方法来实现我们需要的功能。关于对象在VC里面的定义,可以参考下面的方法。 |
| CsoPoint objPoint;//定义一个简单点对象 CsoGeometry objGeometry;//定义几何对象 CsoDataset objDataset;//定义数据集对象 CsoLayers objLayers;//定义图层对象 |
| 在看SuperMap Objects提供的范例、帮助文档或者BBS的Objects版块,有时会看到Iso*开头的变量类型,关于Iso* 跟Cso*对象的区别,好多朋友感觉比较疑惑,不知如何使用Iso*类型的变量。其实这两种对象使用上面没有区别,如果直接用SuperMap提供的类库,基本所有对象都是Cso开头的,但是可能极个别对象由于在封装的时候由于没有封装完全,在通过向导添加到类中的时候VC自动在前面设置了一个I(表示接口类的意思)。 |
| 使用对象实现系统所需功能,查找接口联机帮助时,有些接口的说明,会注示“该对象可创建…”这样的语句。对于这类对象,在初始化时一般需要创建。如果定义此类对象后,可以从其他对象获取值,那可以不创建。创建示范如下: |
| objPoint.CreateDispatch("SuperMap.soPoint");//点对象的创建 objPoint.SetX(100.0);//设置坐标 objPoint.SetY(120.0); objStyle.CreateDispatch("SuperMap.soStyle");//风格对象创建 objStyle.SetPenWidth(6);//风格对象设置属性 objStyle.SetPenColor(RGB(255,0,0)); objPoint=objPoints.GetItem(COleVariant(1L));//从点集对象获取点对象 objStyle=objLayer.GetStyle();//从图层对象获取风格 |
| 程序编程时变量类型的转换时常用到,比如将字符串转换为数字,将变体型变量转换为双精度,将时间类型值转换为字符串等等。使用Objects开发过程中也会经常涉及到Objects接口之间的类型转换,从父对象获取子对象,或者将子对象转换为父对象时一般需要进行类型的转换。如果用VB,直接设置或者赋值就可以了,而在VC中需要使用AttatchDispatch方法进行转换。下面示范的是如何将几何对象转换为点对象,以及如何将数据集转换为矢量数据集(暂时假设已经可以转换),在实际使用时为了增强程序的容错能力和程序的稳定性,建议事先对需要转换的对象进行判断。 |
| objGeoPoint.AttatchDispatch(objGeometry,FALSE);//将几何对象(父)转换为点几何对象(子) objDatasetVector.AttatchDispatch(objDataset,FALSE);//将数据集对象(父)转换为矢量数据集(子) objGeometry.AttatchDispatch(objGeoLine,FALSE);//将线对象(子)转换为几何对象(父) |
| 我们在使用了变量(尤其是创建出来的变量)使用后需要释放,对于这类变量释放代码示范如下: |
| objPoints.ReleaseDispatch();//释放点集对象 objPoints=NULL; |
| 变体型参数使用示范:SuperMap Objects提供的接口中,有些接口需要传入的参数或者返回的参数为变体型的(在Objects联机帮助中一般说明为VARIANT) |
| objDataset=objDatasets.GetItem(COleVariant(1L));//获取数据集集合中的第一个数据集 objDataset=objDatasets.GetItem(COleVariant(“DatasetName”));//获取数据集集合中名称为DatasetName的数据集 COleVariant VarValue;//定义变体型变量 CString strValue; VarValue = objRecordset.GetFieldValue(COleVariant("NAME"));//获取字段值 VarValue.vt=VT_BSTR;//设置变体值类型 strValue=""; strValue = VarValue.bstrVal;//获取值 |
| 手工添加SuperMap控件后,通过VC类向导,可以比较方便地添加SuperMap相关事件,但是对于动态创建的SuperMap控件,怎样添加程序中需要用到的事件函数,有些Objects开发者针对这个问题缩手无策。一个比较容易的方法,我们先看一下通过类向导添加的事件。在对应的cpp文件中,可以看到多了类似下面这一段: |
| BEGIN_EVENTSINK_MAP(CYourDlg, CDialog) //{{AFX_EVENTSINK_MAP(CYourDlg) ON_EVENT(CYourDlg, IDC_SUPERMAPCTRL1, 1/*GeometrySelected*/, OnGeometrySelected, VTS_I4) //}}AFX_EVENTSINK_MAP END_EVENTSINK_MAP() |
| void CYourDlg::OnGeometrySelected(long nSelectedGeometryCount) { // TODO: Add your control notification handler code here } |
| 其中CYourDlg 为对话框类名,IDC_SUPERMAPCTRL1为SuperMap控件的ID,1为SuperMap内部对GeometrySelected事件定义的事件编号,OnGeometrySelected为具体函数名(函数名可以自己设置,不过最好简单易懂),VTS_I4为GeometrySelected事件需要用到的参数。 |
| afx_msg void OnGeometrySelected(long nSelectedGeometryCount); DECLARE_EVENTSINK_MAP() |
| 其实现上面这些就是相关事件的定义以及实现事件的具体函数。我们在给动态创建的SuperMap控件(其他控件也类似)添加相关事件时,只要参考上面的语句,在对应的cpp和头文件中添加类似语句就可以了,添加的时候CYourDlg、CDialog、IDC_SUPERMAPCTRL1、OnGeometrySelected等改成跟自己的程序匹配的变量就可以了。最好的方法是建立一个简单的对话框工程,在窗体上添加SuperMap控件,通过类建立好事件后,把相关代码拷贝到自己的工程中,这样既快捷又不会出错,推荐大家使用。 |
|
当时我在学习VC下使用SuperMap进行开发也费了不少劲儿,在上面这些细节位置开发时经常出现问题,现整理出来,希望对大家有些帮助。
本文由卫图天下原创,转载请注明出处。 | |