3.MapX在VC++ 环境下GIS基本功能的实现

在进行MapX 开发之前,确保已经在计算机中正确的安装了MapX 控件。下面就用一个具体的实例,介绍在VC+ +中集成MapX 的方法。

3.1 将MapX支持类库加入工程

在您的项目中包括MapX.cpp和.h文件。这两个文件包含用于对MapX控件进行访问的类定义和方法实现。MapX.h 和 MapX.cpp 文件可能位于安装有 MapX 的 Samples50CPP 子目录中(如果您安装的事MapX 4.0,则路径为 … Samples40C++Cpp)。

利用VC++ 环境下的应用程序生成向导创建一单文档应用程序MapSample。将MapX.h和MapX.cpp文件拷贝到当前工程路径下,然后从Project菜单中选择Add to Project >Files命令,此时打开Insert Files into Project对话框,选择MapSample文件夹下的MapX.h和MapX〉cpp文件加入到工程中。

警告:不要选择Project菜单中的Add to Project > Components And Controls命令。这样做将会创建一个.cpp文件,但该文件将是不完整的。我一开始就是这么做的,结果很多常用函数都没有,郁闷了我很长时间。希望大家一起要切记这一点。

3.2 使用VC++创建MapX控件

在将包含该控件得视图中包括它:

#include “MapX.h”

Class CMapXSampleView : public CView

{

Protected:

CMapX m_ctrlMapX;

}

要声明表示用于MapX的控件ID的常数:

(1)选择“View”>”Resource Symble”。

(2)单击“New”。

(3)键入“IDC_MAP”来作为名称。

要在类向导中为WM_SIZE和WM_CREATE消息创建处理程序:

(1)转入”View”>”ClassWizard”;

(2)从“Class Name”组合框中选择您的视图类。

(3)在“Messages”列表框中,单击“WM_CREATE”,然后单击“Add Function”。

(4)接着还在该消息框中选择” WM_SIZE”并单击“Add Function”。

(5)然后,单击“Edit Code”

在创建视图时创建该控件。在CMapXSampleView::OnCreate中:

//create map with default size

//resize message will cause it to be size to the client area of the view

If(!m_ctrlMapX.Create(NULL,WS_VISIBLE, CRect(0,0,100,100),this,IDC_MAP))

Returen -1;

Keep the control’s size in sync with the containing window;

//resize the map to be the same size as our client area

Void CMapXSampleView:: OnSize(UINT nType, int cx, int cy)

{

CView::OnSize(nType, cx, cy);

if(cx!=0 && cy!=0)

m_ctrlMapX.MoveWindow(0,0,cx,cy);

}

像您为WM_CREATE消息所作的一样为WM_SETFOCUS消息创建新消息标头。

在我们的示例中,我们想要确保只要窗口被激活MapX就获得焦点:

void CMapXSampleView::OnSetFocus(CWnd* pOldWnd)

{

CView::OnSetFocus(pOldWnd);

m_ctrlMapX.SetFocus();

}

3.3 使用地图标准工具

在地图显示出来后,用户通常要以各种比例查看地图的全局、局部或细部,必须提供诸如放大、缩小和漫游等功能。采用MapX通用工具,可以非常方便地实现上述功能。设定MapX使用标准工具的方法很简单,只需设定地图对象的CurrentTool属性。下面的例子是用标准放大工具实现放大功能。

添加新菜单项资源,输入标题“工具”,在“工具”下添加子菜单,输入标题“放大”及ID 为ID_ZOOM_ IN。打开类向导,选择视图类CMapXSampleView,为菜单项ID_ZOOM_IN 添加COMMAND 消息映射函数OnZoomIn ( ),并编辑码如下。

void CMapXSampleView::OnZoomIn()

{

m_ctrlMapX.SetCurrentTool(miZoomInTool);// miZoomInTool为放大工具常量

}

编译运行程序,选择“工具|放大”,就会看到此时光标变为放大镜,单击鼠标就会实现放大功能。可用相同方法实现其他标准工具的功能。MapX提供的可用标准工具如下表。

工具

常数

说明

添加线条

miAddLineTool

将线条图元添加到插入图层中。

添加点

miAddPointTool

单击该工具可将点图元添加到插入图层中。

添加折线

miAddPolyLineTool

将折线图元添加到插入图层中。

添加区域

miAddRegionTool

将区域图元添加到插入图层中。

箭头

miArrowTool

单击标题或注释此外,在可编辑图层中移动选定图元或调整选定图元的大小。

居中

miCenterTool

单击该工具可以重新将地图居中。

加标签

miLabelTool

在一个图元上单击可以给该图元加标签。

平移

miPanTool

拖动该工具可以重新将地图居中。

多边形选择

miPolygonSelectTool

单击该工具可以绘制一个多边形;该多边形内的对象将被选定。

半径选择

miRadiusSelectTool

拖动该工具可以选择半径内的图元。

矩形选择

miRectSelectTool

拖动该工具可以选择矩形内的图元。

选择工具

miSelectTool

单击该工具可以选择图元。

符号

miSymbolTool

放置符号注释。

文本

miTextTool

放置文本注释。

放大

miZoomInTool

放大。

缩小

miZoomOutTool

缩小。

3.4 使用自定义工具

MapX提供的地图标准工具能满足一般需要,但在一些特殊地方,用户可能需要某种特殊工具来完成某些特定的地图操作功能。因此,MapX提供了用户自定义工具的方法,这样可以大大扩展MapX的应用范围。开发者可使用地图对象的CreateCustomTool 方法创建自定义工具。一旦您已使用CreateCustomTool方法创建了定制工具后,就可以在用户使用定制工具时使用ToolUsed事件执行操作。

此示例进行测试以了解正使用哪一工具。然后,根据正在使用的工具,该示例或者:

• 更改光标下的地图图元的样式,或者

• 在用户单击处放置新符号。

void CMapXSampleView::OnToolUsed(short ToolNum, double X1, double Y1, double X2, double Y2, double Distance,BOOL Shift, BOOL Ctrl, BOOL* EnableDefault)

{

CString str;

CMapXPoint pnt;

str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %sn",

ToolNum, X1,Y1,X2,Y2,Distance,

(Shift)?"Shift":"",(Ctrl)?"Ctrl":"");

TRACE(str);

// change the style of the feature under the cursor

if (ToolNum == MAP_TOOL_CHANGESTYLE) {

try {

// Need the dispatch to use the point

if (pnt.CreateDispatch(pnt.GetClsid())) {

pnt.Set(X1, Y1);

}

else {

// something went wrong, can't use the point...

AfxThrowOleException(CO_E_CLASS_CREATE_FAILED);

}

CMapXLayers layers = m_ctrlMapX.GetLayers();

// Get the USA feature under the cursor

CMapXFeatures ftrs =

layers.Item("USA").SearchAtPoint(LPDISPATCH(pnt));

// work on only the first feature

CMapXFeatureftr = ftrs.Item(1);

// get the style object from the feature

CMapXStylestyle = ftr.GetStyle();

style.SetRegionBackColor(255);

// update the feature in the layer

ftr.Update();

}

catch (COleDispatchException *e) {

e->ReportError();

e->Delete();

}

catch (COleException *e) {

e->ReportError();

e->Delete();

}

}

// place a new symbol at the point clicked on

else if (ToolNum == MAP_TOOL_NEWPOINT) {

try {

CMapXLayers layers = m_ctrlMapX.GetLayers();

CMapXFeatureftr;

// Need the dispatch id to use the feature

if (ftr.CreateDispatch(ftr.GetClsid())) {

// Symbol feature

ftr.SetType(miFeatureTypeSymbol);

// Get the point object from the feature

// and call the Set method

ftr.GetPoint().Set(X1, Y1);

// Add it to the layer

layers.Item("USA").AddFeature(ftr);

}

else {

AfxThrowOleException(CO_E_CLASS_CREATE_FAILED);

}

}

catch (COleDispatchException *e) {

e->ReportError();

e->Delete();

}

catch (COleException *e) {

e->ReportError();

e->Delete();

}

}

}

3.5 处理MapX事件

若要处理MapX事件,您首先需要为感兴趣的事件建立eventsink地图。用于事件DISPATCH id 的常数是在MapX.h中为MapX定制事件定义的,并且是在中为 OLE 普通事件定义的。

// From MapX.h

#define MAPX_DISPID_SELECTION_CHANGED 0x1

#define MAPX_DISPID_RESOLVEDATABIND 0x2

#define MAPX_DISPID_TOOLUSED 0x3

#define MAPX_DISPID_REQUESTDATA 0x4

#define MAPX_DISPID_DATAMISMATCH 0x5

#define MAPX_DISPID_MAPVIEWCHANGED 0x6

#define MAPX_DISPID_ANNOTATIONADDED 0x7

#define MAPX_DISPID_ANNOTATIONCHANGED 0x8

#define MAPX_DISPID_THEMEMODIFYREQUESTED 0x9

#define MAPX_DISPID_DRAWUSERLAYER 0x0a

#define MAPX_DISPID_POLYTOOLUSED 0x0b

// From

#define DISPID_CLICK (-600)

#define DISPID_DBLCLICK (-601)

#define DISPID_KEYDOWN (-602)

#define DISPID_KEYPRESS (-603)

#define DISPID_KEYUP (-604)

#define DISPID_MOUSEDOWN (-605)

#define DISPID_MOUSEMOVE (-606)

#define DISPID_MOUSEUP (-607)

#define DISPID_ERROREVENT (-608)

EVENT_SINK中的ON_EVENT 宏也为MapX控件指定一个ID (在该示例中为 IDC_MAP),指定该事件的参数,并且指定事件处理程序方法的名称。

在视图标头文件MapXSampView.h中,将“DECLARE_EVENTSINK_MAP ()”一行放置于“DECLARE_MESSAGE_MAP”行之下。

从CMapXSampleView.cpp:

BEGIN_EVENTSINK_MAP(CMapXSampleView, CView)

ON_EVENT(CMapXSampleView, IDC_MAP, DISPID_MOUSEMOVE,

OnMouseMoveInMap,VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS)

ON_EVENT(CMapXSampleView, IDC_MAP, MAPX_DISPID_MAPVIEWCHANGED,

OnMapViewChanged, VTS_NONE)

ON_EVENT(CMapXSampleView, IDC_MAP, DISPID_MOUSEUP,

OnMouseUpInMap, VTS_I2 VTS_I2 VTS_XPOS_PIXELS VTS_YPOS_PIXELS)

ON_EVENT(CMapXSampleView, IDC_MAP, MAPX_DISPID_TOOLUSED,

OnToolUsed, VTS_I2 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_BOOL

VTS_BOOL VTS_PBOOL)

ON_EVENT(CMapXSampleView, IDC_MAP,

MAPX_DISPID_THEMEMODIFYREQUESTED, OnThemeModifyRequested,

VTS_DISPATCH)

END_EVENTSINK_MAP()

随后是用于OnToolUsed 事件的事件处理程序代码。来自CMapXSampleView.h 的声明:

void OnToolUsed(short ToolNum, double X1, double Y1, double X2,double Y2, double

Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault);

…以及来自CMapXSampleView.cpp 的实现方式(我们只使用 TRACE 宏将参数输出到调试窗口):

void CMapxSampleView::OnToolUsed(short ToolNum, double X1, double Y1,

double X2, double Y2, double Distance, BOOL Shift, BOOL Ctrl, BOOL* EnableDefault)

{

CString str;

str.Format("Tool=%d, [%f,%f] [%f, %f], dist=%f, %s %sn",ToolNum, X1,Y1,X2,Y2,Distance,

(Shift)?"Shift":"",(Ctrl)?"Ctrl":"");

TRACE(str);

}

3.6 添加快捷菜单

DISPID_MOUSEUP事件可用于添加快捷(鼠标右键按钮)菜单。为您的快捷菜单创建菜单资源(如果菜单资源的ID为IDR_CONTEXTMENU)。OnMouseUpInMap 处理程序类似于以下代码:

// if right mouse button, display the context menu

BOOL CMapxSampleView::OnMouseUpInMap(short Button, short Shift,

OLE_XPOS_PIXELS x,OLE_YPOS_PIXELS y)

{

if (Button == 2) { // right button

CMenu menu; // top-level menu

CMenu *pMenu=NULL; // pop-up menu

// Load the menu resource.

menu.LoadMenu(IDR_CONTEXTMENU);

// TrackPopupMenu cannot display the top-level menu, so get

// the handle of the first pop-up menu.

pMenu = menu.GetSubMenu(0);

if (!pMenu) {

return TRUE;

}

SetMenuDefaultItem(pMenu->m_hMenu, ID_VIEW_PROPERTIES,

FALSE);

// Display the floating pop-up menu. Track the right mouse

// button on the assumption that this function is called

// during WM_CONTEXTMENU processing.

POINT pt;

GetCursorPos(&pt);

pMenu->TrackPopupMenu(TPM_LEFTALIGN | TPM_RIGHTBUTTON,

pt.x, pt.y, this, NULL);

// Destroy the menu.

menu.DestroyMenu();

}

return TRUE;

}

3.7 MapX异常错误处理

MapX通过报告(引发)COleDispatchException 来报告大多数错误。在调用 MapX 时捕获异常错误是十分重要的,因为MFC的默认异常错误处理程序不捕获它们并且您的应用程序将退出。在消息框中显示对错误的说明也是非常有用的。错误消息的文本将帮助您确定是否正确使用了 MapX 图元,或者是否已发生某一其它问题。

COleDispatchException类还在公共成员m_wCode中包括错误代码,以便您的程序可以标识和处理不同类型的错误。对于错误代码及其说明的列表,请参见联机帮助中的 MapX 错误代码。

如果在尝试调用MapX时具有一般的OLE错误(在您使用过时的MapX.h 或 MapX.cpp 版本时可能发生),则 MFC 将引发 COleException。建议你在调用 MapX 时捕获全部两个异常错误类型。

MapX 也可能在 Error 事件中传递错误(尽管非常少见)。只有在不从MapX属性或方法直接调用的异步处理(像redraw)期间出现某种类型的错误时,才可能发生上述情况。

在此示例的 ThemeModifyRequested 事件的事件处理程序中,我们显示普通的“主题”属性对话框以让用户更改主题颜色等。请注意异常错误处理的方式。

// Note: in objects passed to events, the event handler

// does not change the reference count

// ie: do not call release on the object

void CMapxSampleView::OnThemeModifyRequested(LPDISPATCH Theme)

{

try {

CMapXTheme theme;

COptionalVariant vHelpFile, vHelpID;

// mark as optional since we don't have a helpfile

theme.AttachDispatch(Theme, FALSE); // don't auto release

theme.ThemeDlg(vHelpFile, vHelpID);

// could decide to bring up legend dlg here instead

//CMapXLegend leg(theme.GetLegend());

//leg.LegendDlg(vHelpFile, vHelpID);

}

catch (COleDispatchException *e) {

e->ReportError();

e->Delete();

}

catch (COleException *e) {

e->ReportError();

e->Delete();

}

}

用VC++对MapX进行二次开发总结(二)(相关推荐

  1. 微信商城开源版二次开发(二)

    微信商城开源版二次开发(二) 最近想了解如何Java对接微信平台,快速搭建完整项目开发,发现网上有很对开源的这类二开源码.https://gitee.com/luozijing123/JooLun-w ...

  2. Firefox ios 火狐浏览器iOS版本二次开发(二)

    Firefox ios 火狐浏览器iOS版本二次开发(二) 编译 Firefox ios源代码下载地址: Firefox CSDN下载地址 Firefox ios版本采用的是swift语言来进行开发的 ...

  3. pythoncad二次开发视频_revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档...

    二次开发 revit二次开发|bim软件二次开发|revit二次开发教程|Revit二次开发技术文档2019-07-08赞( 0 ) 记录一下CAD二次开发的一些简单实例. 1.helloworld ...

  4. ug二次开发python_NXOpen二次开发.pdf

    NXOpen二次开发 NXOpen 二次开发 二○一三年十二月 目 录 第一章 NXOpen 简介1 1.1 NX API 简介1 1.1.1 NX API 架构与统一对象模型1 1.1.2 现有 N ...

  5. ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985

    ProE二次开发 Creo二次开发 MCADEx Tools 免费工具QQ群 156242985 转载于:https://www.cnblogs.com/esdtech/p/4199884.html

  6. arcgis二次开发python-ArcGIS 二次开发专题 序

    依据ArcGIS 组件式开发及应用的目录结构,将系统性的学习ArcGIS 二次开发的道路分为三个部分.这个系列包含以下三个部分: Part1 基础 1. 前言 1.1 组件式GIS 1.2 ArcOb ...

  7. 织梦二次开发写php,PHP教程—DedeCMS二次开发(二)

    织梦内容管理系统(DedeCMS),是一个集内容发布.编辑.管理检索等于一体的网站管理系统(Web CMS),他拥有国外CMS众多特点之外,还结合中国用户的需要,对内容管理系统概念进行明确分析和定位. ...

  8. arcgis python实例_arcgis二次开发_arcgis二次开发python_arcgis二次开发实例

    [1.rar] - QQ连连看的源码.单消秒杀挂机等功能喜欢的朋友请拿去研究 [qqCHAR.rar] - qq 验证码识别程序 可以叫准确的识别出qq登陆前的验证码 [1.rar] - 本书以Vis ...

  9. python二次开发odoo_odoo二次开发 - 战鹏的Blog - OSCHINA - 中文开源技术交流社区

    #odoo Odoo 的前身是 OpenERP,是一个开源的企业 ERP 系统.odoo官网 通过官网可以看到odoo可以干很多事情,例如销售.CRM等等. #odoo文档 我们可以在odoo文档看到 ...

最新文章

  1. CVPR 2020论文开源项目一页看尽,附代码论文
  2. 解析PHP实现多进程并行执行脚本
  3. Atitit。 《吠陀》 《梨俱吠陀》overview 经读后感  是印度上古时期一些文献的总称...
  4. leetcode 643. 子数组最大平均数 I(滑动窗口)
  5. php查询数据方法,php查询数据库的方法
  6. 网站服务器在境外境内怎么维护,涉黄网站服务器移至境外 境内维护人员将受制裁...
  7. 【渝粤教育】国家开放大学2019年春季 2610药剂学 参考试题
  8. 洛谷 P2383 狗哥玩木棒
  9. 使用easyos递归删除城通网盘的日志
  10. 计算机文档分段,Word文档如何快速分段
  11. wps怎么把当前页面设置为横向_wps单页面方向设置为横向的方法
  12. iOS依赖注入框架系列(一):介绍Typhoon
  13. Linux下Makefile的automake生成全攻略(转)
  14. 广州大学数据库实验三——数据库系统设计综合实验
  15. Kali Linux入门教程(非常详细)从零基础入门到精通,看完这一篇就够了。
  16. 【转】Unity3.5是一次较大的更新.它包含的新功能和改进会让你爱不释手.
  17. 高新技术企业的优惠政策有哪些
  18. 服务器虚拟化fc配置,设置虚拟化主机-连接-FC存储
  19. 数据插补—拉格朗日插值法
  20. openlayer3 系列 4 - 加载天地图

热门文章

  1. 谁在抢占「低代码」高地?
  2. 安卓10自带录屏_手机自带的录屏功能真是太强大了,完全秒杀第三方工具
  3. 计算机英语system,电脑英语Computer System 计算机系统
  4. 2048核心算法,数字移动合并检测
  5. java emr_java – EMR – 在Hadoop(和YARN)中使用自定义日志记录appender
  6. Linux入门(2)——Linux下的文件管理
  7. Vue2.5+Vue-cli3.0+Vue-router仿制京东金融前端页面
  8. u9过期老玉米挖掘软件V2版-过期域名采集软件-网址采集软件-域名采集软件-未注册域名检测软件-老域名采集工具
  9. springboot 大文件分片上传、断点续传和秒传
  10. 光模块的中心波长和传输距离