• 转:ArcEngine10.0+VS2010+MFC 扫盲贴 .


    项目用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的最后面

    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 FilesArcGISDesktop10.0comesriSystem.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 FilesArcGISDesktop10.0comesriSystemUI.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR",/*"ICommand",*/"IProgressDialog") rename("ICommand", "esriICommand")   
    7. #import "D:Program FilesArcGISDesktop10.0comesriControls.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids   
    8. #import "D:Program FilesArcGISDesktop10.0comesriGeometry.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")   
    9. #import "D:Program FilesArcGISDesktop10.0comesriDisplay.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 FilesArcGISDesktop10.0comesriOutput.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")   
    11. #import "D:Program FilesArcGISDesktop10.0comesriGeoDatabase.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 FilesArcGISDesktop10.0comesriDataSourcesFile.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids   
    13. #import "D:Program FilesArcGISDesktop10.0comesriDataSourcesRaster.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR"/*,"IWorkspaceFactory","IWorkspace"*/)   
    14. #import "D:Program FilesArcGISDesktop10.0comesriCarto.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)  
    #pragma warning(push)
    #pragma warning(disable : 4192) /* Ignore warnings for types that are duplicated in win32 header files */
    #pragma warning(disable : 4146) /* Ignore warnings for use of minus on unsigned types */
    #import "libid:6FCCEDE0-179D-4D12-B586-58C88D26CA78" raw_interfaces_only no_implementation
    #import "D:Program FilesArcGISDesktop10.0comesriSystem.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids, exclude("OLE_COLOR", "OLE_HANDLE", "VARTYPE") rename("min", "esriMin") rename("max", "esriMax")
    #import "D:Program FilesArcGISDesktop10.0comesriSystemUI.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR",/*"ICommand",*/"IProgressDialog") rename("ICommand", "esriICommand")
    #import "D:Program FilesArcGISDesktop10.0comesriControls.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids
    #import "D:Program FilesArcGISDesktop10.0comesriGeometry.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")
    #import "D:Program FilesArcGISDesktop10.0comesriDisplay.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")
    #import "D:Program FilesArcGISDesktop10.0comesriOutput.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR")
    #import "D:Program FilesArcGISDesktop10.0comesriGeoDatabase.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR"/*,"ICursor"*/), rename("GetMessage", "esriGetMessage") ,rename("ICursor", "esriICursor"),rename("IRow", "esriIRow")
    #import "D:Program FilesArcGISDesktop10.0comesriDataSourcesFile.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids
    #import "D:Program FilesArcGISDesktop10.0comesriDataSourcesRaster.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR"/*,"IWorkspaceFactory","IWorkspace"*/)
    #import "D:Program FilesArcGISDesktop10.0comesriCarto.olb" raw_interfaces_only, raw_native_types, no_namespace, named_guids,exclude("OLE_COLOR","UINT_PTR") rename("ITableDefinition","esriITableDefinition")
    
    
    
    
    #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函数中使用如下几句关联控件和成员变量

    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. }  
    void CMy1111View::OnDraw(CDC* /*pDC*/)
    {
    	// TODO: 在此添加专用代码和/或调用基类
    
    
    	//关联控件代码
    	CWnd * pWndCal = GetDlgItem(IDC_MAPCONTROL1);
    	LPUNKNOWN pUnk = pWndCal ->GetControlUnknown( );
    	pUnk->QueryInterface( IID_IMapControl2, (LPVOID *)& m_ipMapControl );
    
    
    }

    4.接下来我们初始化许可

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

    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.1",&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. }  
    int CMy1111View::OnCreate(LPCREATESTRUCT lpCreateStruct)
    {
    	if (CFormView::OnCreate(lpCreateStruct) == -1)
    		return -1;
    
    
    	// TODO:  在此添加您专用的创建代码
    
    
    	//初始化Engine许可
    	::CoInitialize(NULL);
    	ArcGISVersionLib::IArcGISVersionPtr ipVer(__uuidof(ArcGISVersionLib::VersionManager));
    	VARIANT_BOOL succeeded;
    	if (FAILED(ipVer->LoadVersion(ArcGISVersionLib::esriArcGISDesktop , L"10.0",&succeeded)))
    		return -1;
    	IAoInitializePtr m_AoInit;//(CLSID_AoInitialize);
    	m_AoInit.CreateInstance (CLSID_AoInitialize);
    	esriLicenseStatus ls;
    	HRESULT h= m_AoInit->Initialize(esriLicenseProductCode::esriLicenseProductCodeEngineGeoDB ,&ls);	
    
    
    	return 0;
    }

    5.加载数据

    我们通过重载MFC的打开按钮来实现。给ID_FILE_OPEN添加消息响应,然后在OnFileOpen()函数中实现数据的加载。

    在这里我们通过调用自定义添加的函数LoadData()来实现。函数如下:

    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. }  
    void CAEMFCRibbonView::LoadData(/*CString strFileName*/)
    {
    	//char sfileter[]="Shape files(*.Shp)|*.Shp|mxd文档(*.mxd)|*.mxd|所有文件(*.*)";
    	CFileDialog dlg(TRUE, //TRUE为OPEN对话框,FALSE为SAVE AS对话框
    		NULL,
    		NULL,
    		OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
    		(LPCTSTR)_TEXT("所有文件|*.*|mxd文档(*.mxd)|*.mxd|Shape files(*.shp)|*.shp|"),
    		NULL);
    	CString m_strFileName;
    	if(dlg.DoModal()==IDOK)
    	{
    		//m_MapControl=new CMapControl2();
    
    
    		m_strFileName=dlg.GetPathName();//全路径名
    		//CString filepath=dlg.GetFolderPath();//路径名称,不带文件名
    		//CString filename=dlg.GetFileName();//文件名,不带路径
    		CString strExt = dlg.GetFileExt();//后缀名,不带点
    		if (strExt=="shp")
    		{
    			CComBSTR MX_DATAFILE;
    			//MX_DATAFILE = "F:\测试mxd文档\shenzhen.mxd" ;
    			MX_DATAFILE=dlg.GetPathName();
    			BSTR filePath=dlg.GetFolderPath().AllocSysString();
    			BSTR fileName=dlg.GetFileName().AllocSysString();
    			m_ipMapControl->AddShapeFile(filePath,fileName);
    		}
    		else if(strExt=="mxd")
    		{
    			CComBSTR MX_DATAFILE;
    			//MX_DATAFILE = "F:\测试mxd文档\shenzhen.mxd" ;
    			MX_DATAFILE=dlg.GetPathName();
    			VARIANT_BOOL bValidDoc;
    			//m_MapControlView.CheckMxFile( MX_DATAFILE );
    			m_ipMapControl->CheckMxFile( MX_DATAFILE, & bValidDoc );
    			//VARIANT vt = 0;
    			if (bValidDoc)
    				m_ipMapControl->LoadMxFile(MX_DATAFILE);
    		}
    		else
    		{
    			AfxMessageBox(_T("请选择合适的文件!"));
    			return;
    		}
    		m_ipMapControl->Refresh(esriViewAll);
    	}
    }

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

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

    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. }  
    void CAEMFCRibbonView::OnSize(UINT nType, int cx, int cy)
    {
    	CFormView::OnSize(nType, cx, cy);
    
    
    	// TODO: 在此处添加消息处理程序代码
    	CWnd *pMapCtl = GetDlgItem( IDC_MAPCONTROL1 );
    	//CRect MapCtlrect;
    	if ( pMapCtl )
    	{
    		//pMapCtl->GetWindowRect( &MapCtlrect );
    		pMapCtl->MoveWindow( 0,0, cx, cy );
    	}
    }


    先到这里,下午再来更新添加自定义的放大缩小等地图工具和取属性等。

  • 相关阅读:
    day32-python阶段性复习六
    golang 项目中坑
    golang crawler
    router
    golang in ubuntu
    go channel 案例分析
    go channel learning
    bee go + mgo
    URL escape and unescape
    [转]good sample of Go
  • 原文地址:https://www.cnblogs.com/skyofbitbit/p/3724721.html
Copyright © 2020-2023  润新知