wuyi802606
路人甲
路人甲
  • 注册日期2016-03-23
  • 发帖数2
  • QQ
  • 铜币2枚
  • 威望1点
  • 贡献值0点
  • 银元0个
阅读:8908回复:4

用C++和QT来做ArcEngine的二次开发

楼主#
更多 发布于:2016-03-23 23:34
最近准备学习用C++和QT来做ArcEngine的二次开发,但是没有找到资料,有高手可以指导下嘛?<br />
喜欢1 评分0

最新喜欢:

realkinglionrealki...
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
1楼#
发布于:2016-03-24 17:19
项目用vc6.0+MapObject写的,现在却要升级成AE10,研究了好多天的AE10.0和c++,中间的曲折也不想多说了,废话少数,下面是实现ArcEngine基本功能的,仅供参考,如能帮到同仁们,那就很欣慰了。
前提:已经安装了ArcGIS10.0,ArcEngine10.0 C++开发包,已经安装了vs2010,win7 32位(64位暂未验证)
总的来说分为如下几步:
1.引入库文件
2.加入地图控件
3.将地图控件和成员变量绑定
4.初始化许可
5.加载数据
6.添加功能


1.首先请建立一个MFC的工程,这里选择在左侧已安装的模板的visual C++下的MFC,这里取工程名字叫1111,应用程序类型单文档和多文档都没有区别,但是在生成的类中基类要选择“CFormView”。点击完成。然后是在stdafx.h中引入库文件。
请将下面的代码原封不动的粘贴到stdafx.h的最后面



[cpp] view plain copy
 

  1. #pragma warning(push)  
  2. #pragma warning(disable : 4192) /* Ignore warnings for types that are duplicated in win32 header files */  
  3. #pragma warning(disable : 4146) /* Ignore warnings for use of minus on unsigned types */  
  4. #import "libid:6FCCEDE0-179D-4D12-B586-58C88D26CA78" raw_interfaces_only no_implementation  
  5. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriSystem.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids, exclude("OLE_COLOR", "OLE_HANDLE", "VARTYPE") rename("min", "esriMin") rename("max", "esriMax")  
  6. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriSystemUI.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR",/*"ICommand",*/"IProgressDialog") rename("ICommand", "esriICommand")  
  7. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriControls.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids  
  8. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriGeometry.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")  
  9. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriDisplay.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR") rename("RGB", "esriRGB") rename("CMYK", "esriCMYK") rename("ResetDC", "esriResetDC") rename("GetMessage", "esriGetMessage")  
  10. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriOutput.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")  
  11. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriGeoDatabase.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR"/*,"ICursor"*/), rename("GetMessage", "esriGetMessage") ,rename("ICursor", "esriICursor"),rename("IRow", "esriIRow")  
  12. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriDataSourcesFile.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids  
  13. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriDataSourcesRaster.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR"/*,"IWorkspaceFactory","IWorkspace"*/)  
  14. #import "D:\Program Files\ArcGIS\Desktop10.0\com\esriCarto.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR","UINT_PTR") rename("ITableDefinition","esriITableDefinition")  
  15.  
  16.  
  17.  
  18.  
  19. #pragma warning(pop)  



修改下:导入库文件时,不要排除IRow和ITableDefinition,而是重命名(比如esriIRow),不然会有很多不必要的麻烦,比如选择集取属性值出错等
注意:
(1)头三行和最后一行是忽略一些不必要的警告
(2)第四行一定要有,从esri官网上抄下来的,作用暂时不明确
(3)这里引入库文件的地址是绝对地址,我的ArcGIS安装在D盘,请改成对应的安装盘,也可以把*.olb文件取出来改成相对地址,随便。
(4)类似于rename("ICommand", "esriICommand")这样的语句,是因为esri的关键字与MFC的关键字冲突了,重命名下,在代码中使用AE的关键字的时候,也用已经重命名的关键字
(5)类似于exclude("OLE_COLOR"),是因为MFC中已经有了这样的类,不需要再导入了
(6)导入这些库文件是有前后顺序的,关于导入的顺序,请参开esri官网,地址如下
http://help.arcgis.com/en/sdk/10.0/arcobjects_cpp/componenthelp/index.html#//000200000001000000
这里有顺序的说明和大部分库文件的部分作用描述


2.引入了库文件,接下来加入地图控件。
请在类视图中找到CMy1111View,然后右键“转到对话框视图“,然后从左侧工具箱中拖一个ESRI MapControl到视图框中,如果没有ESRI的控件,请先右键建立一个选项卡,取名ESRI,然后右键选择项-COM组件选项卡,选择ESRI MapControl,OK。如下图:
3.将地图控件和成员变量绑定
首先请在CMy1111View类头文件中添加一个成员变量如下
IMapControl2Ptr m_ipMapControl;/*指向当前地图文档的指针*/
然后给这个类添加虚函数OnDraw(),然后再OnDraw函数中使用如下几句关联控件和成员变量



[cpp] view plain copy
 

  1. void CMy1111View::OnDraw(CDC* /*pDC*/)  
  2. {  
  3.    // TODO: 在此添加专用代码和/或调用基类  
  4.  
  5.  
  6.    //关联控件代码  
  7.    CWnd * pWndCal = GetDlgItem(IDC_MAPCONTROL1);  
  8.    LPUNKNOWN pUnk = pWndCal ->GetControlUnknown( );  
  9.    pUnk->QueryInterface( IID_IMapControl2, (LPVOID *)& m_ipMapControl );  
  10.  
  11.  
  12. }  



4.接下来我们初始化许可
请给CMy1111View类添加消息WM_CREATE,生成OnCreate()函数,然后再OnCreate()函数中添加如下代码初始化AE许可



[cpp] view plain copy
 

  1. int CMy1111View::OnCreate(LPCREATESTRUCT lpCreateStruct)  
  2. {  
  3.    if (CFormView::OnCreate(lpCreateStruct) == -1)  
  4.        return -1;  
  5.  
  6.  
  7.    // TODO:  在此添加您专用的创建代码  
  8.  
  9.  
  10.    //初始化Engine许可  
  11.    ::CoInitialize(NULL);  
  12.    ArcGISVersionLib::IArcGISVersionPtr ipVer(__uuidof(ArcGISVersionLib::VersionManager));  
  13.    VARIANT_BOOL succeeded;  
  14.    if (FAILED(ipVer->LoadVersion(ArcGISVersionLib::esriArcGISDesktop , L"10.0",&succeeded)))  
  15.        return -1;  
  16.    IAoInitializePtr m_AoInit;//(CLSID_AoInitialize);  
  17.    m_AoInit.CreateInstance (CLSID_AoInitialize);  
  18.    esriLicenseStatus ls;  
  19.    HRESULT h= m_AoInit->Initialize(esriLicenseProductCode::esriLicenseProductCodeEngineGeoDB ,&ls);  
  20.  
  21.  
  22.    return 0;  
  23. }  



5.加载数据
我们通过重载MFC的打开按钮来实现。给ID_FILE_OPEN添加消息响应,然后在OnFileOpen()函数中实现数据的加载。
在这里我们通过调用自定义添加的函数LoadData()来实现。函数如下:



[cpp] view plain copy
 

  1. void CAEMFCRibbonView::LoadData(/*CString strFileName*/)  
  2. {  
  3.    //char sfileter[]="Shape files(*.Shp)|*.Shp|mxd文档(*.mxd)|*.mxd|所有文件(*.*)";  
  4.    CFileDialog dlg(TRUE, //TRUE为OPEN对话框,FALSE为SAVE AS对话框  
  5.        NULL,  
  6.        NULL,  
  7.        OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,  
  8.        (LPCTSTR)_TEXT("所有文件|*.*|mxd文档(*.mxd)|*.mxd|Shape files(*.shp)|*.shp|"),  
  9.        NULL);  
  10.    CString m_strFileName;  
  11.    if(dlg.DoModal()==IDOK)  
  12.    {  
  13.        //m_MapControl=new CMapControl2();  
  14.  
  15.  
  16.        m_strFileName=dlg.GetPathName();//全路径名  
  17.        //CString filepath=dlg.GetFolderPath();//路径名称,不带文件名  
  18.        //CString filename=dlg.GetFileName();//文件名,不带路径  
  19.        CString strExt = dlg.GetFileExt();//后缀名,不带点  
  20.        if (strExt=="shp")  
  21.        {  
  22.            CComBSTR MX_DATAFILE;  
  23.            //MX_DATAFILE = "F:\\测试mxd文档\\shenzhen.mxd" ;  
  24.            MX_DATAFILE=dlg.GetPathName();  
  25.            BSTR filePath=dlg.GetFolderPath().AllocSysString();  
  26.            BSTR fileName=dlg.GetFileName().AllocSysString();  
  27.            m_ipMapControl->AddShapeFile(filePath,fileName);  
  28.        }  
  29.        else if(strExt=="mxd")  
  30.        {  
  31.            CComBSTR MX_DATAFILE;  
  32.            //MX_DATAFILE = "F:\\测试mxd文档\\shenzhen.mxd" ;  
  33.            MX_DATAFILE=dlg.GetPathName();  
  34.            VARIANT_BOOL bValidDoc;  
  35.            //m_MapControlView.CheckMxFile( MX_DATAFILE );  
  36.            m_ipMapControl->CheckMxFile( MX_DATAFILE, & bValidDoc );  
  37.            //VARIANT vt = 0;  
  38.            if (bValidDoc)  
  39.                m_ipMapControl->LoadMxFile(MX_DATAFILE);  
  40.        }  
  41.        else  
  42.        {  
  43.            AfxMessageBox(_T("请选择合适的文件!"));  
  44.            return;  
  45.        }  
  46.        m_ipMapControl->Refresh(esriViewAll);  
  47.    }  
  48. }  



运行程序已经可以看到地图控件,点击打开文件按钮,选择一个shp文件,确定,效果如下:

这个时候地图控件还没有充满整个客户区屏幕,我们添加WM_SIZE消息响应,并添加如下代码,就能自动调整尺寸了。



[cpp] view plain copy
 

  1. void CAEMFCRibbonView::OnSize(UINT nType, int cx, int cy)  
  2. {  
  3.    CFormView::OnSize(nType, cx, cy);  
  4.  
  5.  
  6.    // TODO: 在此处添加消息处理程序代码  
  7.    CWnd *pMapCtl = GetDlgItem( IDC_MAPCONTROL1 );  
  8.    //CRect MapCtlrect;  
  9.    if ( pMapCtl )  
  10.    {  
  11.        //pMapCtl->GetWindowRect( &MapCtlrect );  
  12.        pMapCtl->MoveWindow( 0,0, cx, cy );  
  13.    }  
  14. }  


先到这里,下午再来更新添加自定义的放大缩小等地图工具和取属性等。
举报 回复(0) 喜欢(0)     评分
明天依旧光明
路人甲
路人甲
  • 注册日期2018-05-26
  • 发帖数1
  • QQ
  • 铜币1枚
  • 威望0点
  • 贡献值0点
  • 银元0个
2楼#
发布于:2018-05-26 11:18
请问楼主有没有将qt+C++进行ArcGIS的二次开发呢?
举报 回复(0) 喜欢(0)     评分
绝影fly
路人甲
路人甲
  • 注册日期2018-09-25
  • 发帖数1
  • QQ
  • 铜币1枚
  • 威望0点
  • 贡献值0点
  • 银元0个
3楼#
发布于:2018-09-25 16:18
最近也在做相关研究,目前基本框架搭建起来了,欢迎交流
举报 回复(0) 喜欢(0)     评分
gis
gis
管理员
管理员
  • 注册日期2003-07-16
  • 发帖数15945
  • QQ554730525
  • 铜币25337枚
  • 威望15352点
  • 贡献值0点
  • 银元0个
  • GIS帝国居民
  • 帝国沙发管家
  • GIS帝国明星
  • GIS帝国铁杆
4楼#
发布于:2018-09-29 17:50
感觉现在用这样的环境开发应用系统的不多了,毕竟效率不算太高
举报 回复(0) 喜欢(0)     评分
游客

返回顶部