用VC实现GIS系统基本功能
文档说明:
此文档适合VC++的初学者,高手也可参考(希望能提出宝贵意见)。
开发前准备:
前提:必须在你的电脑上安装了MapX控件,并且准备好需要用到的电子地图(Mapinfo格式的)
VC++嵌入MapX进行二次开发可分为以下几个步骤来实现:
1对应用工程的预设置
在创建MapX控件之前,必须将MapX.h和MapX.cpp文件加入到工程中。对于VisualC++5.0及以上版本,从Project菜单中选择AddToProject->Files命令,打开InsertFilesintoProject对话框,选择MapX.cpp和MapX.h文件加入到工程中(在MapX自带的C++例子中有这两个文件)。
注意:不要选择Project菜单中的AddTOProject->ComponentsAndControls命令。如果选择该命令加入MapX控件,将创建一新的.cpp文件,但是该文本没有包括所有的MapX对象。
2对MapX属性的操作
对于C++程序来说,每个MapX对象(Objects)都在MapX.h和MapX.cpp中用一个类来实现,类的名字和MapX对象的名字相同,且已经在CmapX中定义了。
例如,DataSet对象用类CmapXDataset实现。这和C++类的定义相一致。而每个MapX对象的属性(Properties)是用类的成员函数来实现的。比如DataSet对象的名字(Name),就是用Name()函数来实现的,不过,Name()有两种使用方法,即Get和Set。如:
CStringGetName();//获取对象名字
voidSetName(LPCTSTR);//设置对象名字
3部分MapX工具的应用
(1)“全图”工具的改进
一般全图工具的代码为:
m_ctrlMapX.SetZoom(m_ctrlMapX.GetGeoSetWidth());
此方法的缺点是重新显示全图后,实际上是以上一个视图的中心作为屏幕中心进行显示,如果上一个视图在全图中的边缘位置,点击全图工具后实际上不是初始设置的全图。因此可以用如下代码实现:
CStringmapname=m_ctrlMapX.GetGeoSet();//取得当前地图的名字
m_ctrlMapX.SetGeoSet(mapname);//设置该地图为主视区显示图
(2)创建“信息”工具
MapX没有提供信息工具,该工具是自定制工具。有两种实现方法,其基本思想是:
(1)创建工具的鼠标指针类型(一般为“+”),当在工具栏上选择此工具后,设置为当前工具,然后跟踪鼠标在地图上点击的位置,触发ToolUsed事件,根据位置信息确定相应的对象,然后读取对象属性或绑定的数据库,弹出对话框,实现信息显示。此种方法只适用于显示地图的最上层对象(在MapX自带的C++例子“Buffer”中有具体实现代码)。
(2)用选择工具选中地图上所要显示信息的对象,然后再点击工具栏上的信息工具,弹出对话框,实现信息显示。此信息工具的实现代码与(1)不同,没有鼠标指针,实际上就是读取选中对象的属性或绑定的数据库的操作。此方法适合显示地图上的任意图层。
两种方法各有特点,第一种方法直接,但在实际应用中容易出现异常,第二种方法要多点击一次,但应用稳定,而且适用地图上的任意图层。
(3)“测距”工具的使用注意事项
MapX的Distance()函数是针对地球地图的,在非地球地图中使用要注意数值转换。否则测出的数据与实际相差甚远。
4用MapX进行GIS二次开发
(1)创建数据库
空间数据库可以通过两种方法创建,一种是通过MapX的图层生成功能创建。MapX生成的每一图层都对应一张表(table),该表中除了存有地理对象的位置坐标以外,还可以包含其他属性字段;另一种方法是通过导入带有地理位置信息的其他数据库生成。MapX可以通过数据绑定把这些数据库中的地理信息映射到地图图层上,MapX支持对多种常用数据库的访问。
(2)设置图层控制和地图投影
在把地图加入到MapX之前,我们可以使用MapX附带的图层管理工具GeosetManager把要加入的图层匹配在一起,建成一个图层组,该图层组规定了其中各个图层的名称、内容、属性及各图层之间的显示顺序。MapX中可以给图层设置四种属性:可显示、可选择、可编辑和自动标注。一般图层的属性是可显示的,需要查询的图层设置为可选择,需要修改的图层设置为可编辑,而自动标注可以自动显示图层中地理对象的标签。合理地设置这些属性将有助于系统实现地理信息的维护和查询功能。在匹配各个图层时,应该注意各个图层投影的设置。全部图层必须使用一致的投影方法才能精确匹配。MapX中的地图分为地球地图和非地球地图,地球地图中对象的坐标用经纬度来表示,非地球地图中对象的坐标通常是相对坐标,是相对于图中的某个基准点来设置的。如果图层的坐标不一致的话,必须先转换坐标才能进行匹配。
(3)设计编辑功能
MapX提供标准的地理对象类型定义,在MapX所提供的点、线、面类型选择对话框中可以方便地选择地理对象的类型,包括所使用的符号的形状、颜色、大小等属性。利用MapX提供的画图工具,可以为用户设计出多种多样的地理对象生成工具。利用MapX提供的多种地理信息对象的选择工具(如矩形、圆形选择工具),用户可以调用这些选择工具并和MapX所提供的编辑(删除、修改等)地理对象功能相结合,以完成地理信息系统中地理对象的编辑操作。但要注意,对于地理数据和非地理数据要分别对待。
(4)设计查询功能和分析统计功能
对于地理信息系统中所要求的有关地理信息查询功能和分析统计功能,MapX提供了一定的查询和分析手段,如MapX可以根据图层表中的字段值查询相对应的地理对象;可以提供对应于图层表中某个或某几个字段的分析饼图等。对于非地理信息,就要依据系统的具体要求用面向对象的语言设计查询和分析统计功能。
开发过程:
1.前期学习,因为是利用别人的空间进行二次开发,所以必须先熟悉别人提供的函数接口一起定义的数据结构(类)。
2.主要实现的功能:地图的显示,放大,缩小,移动,显示某一点的信息等。很多功能只需要用一个函数就可以解决了。
3.具体实现:
定义一个CMapX的全局或成员变量,m_ctrlMapX
(1)放大:m_ctrlMapX.SetCurrentTool(miZoomInTool);
(2)缩小:m_ctrlMapX.SetCurrentTool(miZoomOutTool);
(3)漫游:m_ctrlMapX.SetCurrentTool(miPanTool);
(4)各种类型的选择工具设置:
m_ctrlMapX.SetCurrentTool(miSelectTool);
m_ctrlMapX.SetCurrentTool(miRectSelectTool);
m_ctrlMapX.SetCurrentTool(miRadiusSelectTool);
m_ctrlMapX.SetCurrentTool(miPolygonSelectTool);
(5)设置用户自定义工具:
m_ctrlMapX.SetCurrentTool(INFO_TOOL);
(6)设置整张图显示
try
{
m_ctrlMapX.SetZoom(m_ctrlMapX.GetGeoSetWidth());
}
catch(COleDispatchException*e)
{
e->ReportError();
e->Delete();
}
catch(COleException*e)
{
e->ReportError();
e->Delete();
}
(7)设置居中工具:
m_ctrlMapX.SetCurrentTool(miCenterTool);
(8)地图属性信息:
m_ctrlMapX.PropertyPage();
(9)设置鼠标滚动放大缩小功能:
m_ctrlMapX.SetMousewheelSupport(miMousewheelNoAutoScroll);
(10)实现经纬度信息:
这里稍微要麻烦一些,需要用到OLE的消息处理机制,相当于需要自定义消息处理,在自动生成的消息映射代码后面添加如下(CPP文件里面):在MSDN里面有具体的使用方法,以及里面参数的意义。还有就是需要看MapX的帮助文档看里面对应的消息。
BEGIN_EVENTSINK_MAP(CMapXSampleView,CView)
//鼠标单击别选择了用户自定义的工具
ON_EVENT(CMapXSampleView,IDC_MAP,MAPX_DISPID_TOOLUSED,OnInfoToolUsed,
VTS_I2VTS_R8VTS_R8VTS_R8VTS_R8VTS_R8VTS_BOOLVTS_BOOLVTS_PBOOL)
//这是后面用到的
ON_EVENT(CMapXSampleView,IDC_MAP,DISPID_MOUSEMOVE,OnMouseMoveInMap,
VTS_I2VTS_I2VTS_XPOS_PIXELSVTS_XPOS_PIXELS)
//视图内容改变时
ON_EVENT(CMapXSampleView,IDC_MAP1,MAPX_DISPID_MAPVIEWCHANGED,OnMapViewChanged,VTS_NONE)
END_EVENTSINK_MAP()
响应函数:
//鼠标点击取图元信息
voidCMapXSampleView::OnInfoToolUsed(shortToolNum,doubleX1,doubleY1,doubleX2,doubleY2,doubleDistance,BOOLShift,BOOLCtrl,BOOL*EnableDefault)
{
if(ToolNum==INFO_TOOL)
{
m_gX=X1;
m_gY=Y1;
CInfoDlgdlg;
dlg.DoModal();
}
}
其中在CInfoDlg有一个比较主要重要函数实现实现某一图元的具体信息:
voidCInfoDlg::InfoToolUsed()
{
intiCount=0;
iCount=m_ctrlMapX.GetLayers().GetCount();
//这点是搜索中心
CMapXPointpt;
//这将搜索所有功能
CMapXFeaturesfs;
//这将保留我们目前正在客户的功能
CMapXFeaturefeature;
CMapXLayerlayer;
//创建一个调度的点
pt.CreateDispatch(pt.GetClsid());
pt.Set(m_gX,m_gY);
doubledLayerZoomMax,dLayerZoomMin;
doubledMapZoom;
dMapZoom=m_ctrlMapX.GetZoom();
for(inti=1;i<=iCount;i++)
{
layer=m_ctrlMapX.GetLayers().Item(i);
dLayerZoomMax=layer.GetZoomMax();
dLayerZoomMin=layer.GetZoomMin();
if((dLayerZoomMax>=dMapZoom&&dLayerZoomMin<=dMapZoom)|| (dLayerZoomMax==0&&dLayerZoomMin==0))
{
fs=m_ctrlMapX.GetLayers().Item(i).SearchAtPoint(pt);
if(fs.GetCount()!=0)
{
CStringbuffer;
CMapXDatasetds;
feature=fs.Item(1);
layer=feature.GetLayer();
COleVariantlayerVt;
layerVt.vt=VT_DISPATCH;
layerVt.pdispVal=layer.m_lpDispatch;
layerVt.pdispVal->AddRef();
ds=m_ctrlMapX.GetDatasets().Add(miDataSetLayer,layerVt);
COleVariantValueVt;
intiFieldCount=ds.GetFields().GetCount();
for(inti=0;i<iFieldCount;i++)
{
buffer=ds.GetFields().Item(i+1).GetName();
m_ctrlInfoList.InsertItem(i,buffer);
COleVariantvVal;
for(intj=0;j<iFieldCount;j++)
{
vVal=ds.GetValue(feature.GetFeatureID(),j+1);
//判断是否有对应的值
if(vVal.vt==VT_NULL)
{
continue;
}
vVal.ChangeType(VT_BSTR);
buffer=vVal.bstrVal;
m_ctrlInfoList.SetItemText(j,1,buffer);
}//endfor(intj=0;j<iFieldCount;j++)
}//endfor(inti=0;i<iFieldCount;i++)
break;
}//endif(fs.GetCount()!=0)
}//endif(dLayerZoomMax>=dMapZoom&&dLayerZoomMin<=dMapZoom)
}//endfor(inti=1;i<=iCount;i++)
}
(11)实现地图投影
m_ctrlMapX.GetDisplayCoordSys().PickCoordSys();
CMapXDatumdatum;
datum.CreateDispatch(datum.GetClsid());
datum.SetFromList(0);
m_ctrlMapX.GetDisplayCoordSys().Set(1,datum,COptionalVariant(), COptionalVariant(),
COptionalVariant(),COptionalVariant(),COptionalVariant(),COptionalVariant(),COptionalVariant(),
COptionalVariant(),COptionalVariant(),COptionalVariant(),COptionalVariant(),COptionalVariant());
(12)图层控制:
try
{
VARIANTvHelpFile,vHelpID;
vHelpFile.vt=VT_ERROR;
vHelpFile.scode=DISP_E_PARAMNOTFOUND;
vHelpID.vt=VT_ERROR;
vHelpID.scode=DISP_E_PARAMNOTFOUND;
CMapXLayerslayers=m_ctrlMapX.GetLayers();
layers.LayersDlg(vHelpFile,vHelpID);
}
catch(COleDispatchException*e)
{
e->ReportError();
e->Delete();
}
catch(COleException*e)
{
e->ReportError();
e->Delete();
}
(13)打开图形文件:
voidCMapXSampleView::OnFileOpen()
{
CFileDialogdlgFile(TRUE,"*.gst",NULL,OFN_HIDEREADONLY,szTabFilter,this);
dlgFile.m_ofn.lpstrTitle="OpenMapInfoMap";
if(dlgFile.DoModal()==IDCANCEL)
{
return;
}
m_strFilePath=dlgFile.GetPathName();
try
{
//ClosetheexistingsetofmaplayersandloadtheCanadamap
TRACE0("OldGeoset:"+m_ctrlMapX.GetGeoSet());
m_ctrlMapX.SetGeoSet(m_strFilePath);
((CMainFrame*)AfxGetApp()->GetMainWnd())->m_wndMyDialogBar.SetDlgItemText(IDC_EDIT_GEOSET_NAME,m_ctrlMapX.GetTitleText());
m_ctrlMapX.SetTitleText("");
TRACE0("NewGeoset:"+m_ctrlMapX.GetGeoSet());
}
catch(COleDispatchException*e)
{
e->ReportError();
e->Delete();
}
catch(COleException*e)
{
e->ReportError();
e->Delete();
}
}
4.总结:
开发GIS系统是相对比较复杂的,如果完全从零开始开发周期相对较慢,不过灵活性更高。现在有很多现成的开发包,把最基本的功能都实现了,我们只需要简单调用提供的一种就可以了。
相关推荐
VC开发GIS系统代码,教你实现一些GIS的基本功能
基于VC,MAPX开发的gis小型系统,基本功能已经实现
该实例实现了基本的GIS地图的显示、放大、缩小、漫游、归心、经纬度的动态显示、及历史轨迹回放、位图标注的添加、图层控制等功能,对VC GIS开发有一定的启示作用。有问题请联系我EMail:huyongfa000@163.com
运用地理信息系统软件工程原理,采用面向对象技术 和数据库技术,设计了一套GIS软件,并在Microsoft Visual C一6.0的平台上实现了该软件的放大、缩小、平移、图 层管理、制作简单的专题地图等基本功能以及其他相关...
LZW压缩算法VC实现、改进及其应用研究.pdf MATCOM与VC_混合编程中自定义函数作为输入参数的调用方法.pdf MATCOM与VC_混合编程方法在图像处理中的应用.pdf MATLAB与VC_混合编程在系统辨识中的应用.pdf Matlab与VC...
一、系统功能 <br> 矿图信息管理系统是煤矿应用GIS系统,其功能定位是: 1)各类矿图的动态叠加显示和控制; 2)矿图的动态浏览,即放大、缩小和漫游等; 3)信息查询,通过灵活的方式进行...
LZW压缩算法VC实现、改进及其应用研究.pdf MATCOM与VC_混合编程中自定义函数作为输入参数的调用方法.pdf MATCOM与VC_混合编程方法在图像处理中的应用.pdf MATLAB与VC_混合编程在系统辨识中的应用.pdf Matlab与VC...
LZW压缩算法VC实现、改进及其应用研究.pdf MATCOM与VC_混合编程中自定义函数作为输入参数的调用方法.pdf MATCOM与VC_混合编程方法在图像处理中的应用.pdf MATLAB与VC_混合编程在系统辨识中的应用.pdf Matlab与VC...
一、系统功能 <br> 矿图信息管理系统是煤矿应用GIS系统,其功能定位是: 1)各类矿图(或其它行业图纸,如水利、电力、交通、园林等)的动态叠加显示和控制; 2)矿图(或其它行业图纸,如水利、...
这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...
分布实施”的原则来进行,先建立一个静态的配电网GIS,即电力设施的AM/FM/GIS应用,包括系统的功能开发、基本图形数据的录入工作和设备台帐数据的录入,实现图形及设备的查询、统计和图形输出等基本GIS功能;...
这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...
本程序在VC6.0环境下开发数据库查询系统,使用ADO连接数据库,代码基本上实现了一般用户所需的功能,由于时间上关系并没有完成换乘模块,但只要你可以顺利的看懂完成本系统其他部分 ,相信换乘已不是难事了!
这套符号库是利用VC++语言开发的,并且已经在多个城市信息系统中使用过,有着很好的稳定性和高效性,作为VC开发的组件,它有简单的接口(只用了一个接口函数),强大的功能等特点(实现了所有城市图符号的绘制)。...
这是一套是一套非常完善的图形系统,适合在电力、煤炭、化工、仿真、网络、自动化等各种工业监控软件以及图形建模、图形管理、图形分析、中小型GIS系统、工作流、中文表格、表单、工程绘图等软件项目中应用。...
yearmonth.zip 选择年/月的控制(39KB)<END><br>64,calen32a.zip 提供日历功能的动态库, 含有演示代码(79KB)<END><br>65,mappin.zip 你可以在你的GIS(地图信息系统)中使用这些源程序,因为它演示了在地图上...
轻松实现地理信息系统功能,地图精美表现、样式任意定制,丰富的标注设置、动画GIF随意添加、专题图展示、路径分析、模糊搜索、 范围查询等“功能强大、易学易用”是DapperMap ActiveX的特色之一,在保持这一鲜明...
不该用Generics实现Abstract Factory的理由 C#2.0-泛型 C#2.0-extern C#2.0-可空类型 C#2.0-分部类 C#2.0-迭代器 C#2.0 的新增功能学习 泛型的序列化问题 .NET 2.0 泛型在实际开发中的一次小应用 C#2.0 Singleton 的...
我们基于GIS基础地理信息系统平台,采用VC6+GDI的模式,来实现会场和会标自定义、会议座位区域自定义、就座列排多少自定义、就餐接待主题自定义、表格宽窄餐桌大小自定义、姓名横竖排列自定义、姓名字号大小自定义...