zoukankan      html  css  js  c++  java
  • Qt+ArcGIS Engine 10.1 开发(一)

    Qt作为一个跨平台C++图形用户界面应用程序开发框架,相当于微软的MFC(只能运行在Windows平台上),Qt命运多舛,几经易主,现在属于芬兰IT服务公司Digia。

    1. Qt环境安装

    Qt的最新版本是Qt5.0,该版本是在12月中旬发布的,在这里我用的是Qt4.8。1版本,也不建议大家着急着用最新版本,关于软件的下载地址可以在下面找到。

    http://download.qt.nokia.com/qt/source/

    http://qt-project.org/downloads#qt-other

    安装过程很单,只需要点击下一部即可。

    因为我采用的是VS2010作为Qt的集成开发环境,整个开发环境需要下载两个软件

    http://download.qt.nokia.com/qt/source/qt-win-opensource-4.8.1-vs2010.exe

    http://releases.qt-project.org/vsaddin/qt-vs-addin-1.1.11-opensource.exe

     

    说明:

    如果有人不愿意这么做,还可以使用QtCreator以及qt-win-opensource-4.8.1-mingw.exe的组合,因为新版本的QtCreator已经不包含mingw,所以要单独下载。

     

    1. Qt的第一个程序

    安装完后,需要配置几个环境变量,QMAKESPE(根据自己的情况配置,因为我用的是VS2010,所有配置win32-msvc2010),如下图:

    QTDIR(Qt的安装目录),如下图:

    在Path中添加Qt的bin目录如下图:

    打开VS2010,新建工程可以找到Qt4 的模板:

     

     

    完成之后,在VS中运行,出现下面的界面,因为我们什么都没做,在弹出的界面上什么都没有,不过没关系,只要能出现,就说明我们的Qt已经可以使用了,如下图:

     

    1. ArcGIS Engine的环境

    安装ArcGIS ArcObjects for Cross Platform C++ 的SDK,这个没有什么好说的。

    1. ArcGIS Engine+Qt(控制台开发)

    安装了SDK之后,我们就需要将ArcGIS Engine的类库等引入到开发环境中,在Qt中引入ArcGIS Engine的类库等信息.在新建立的Qt控制台程序工程右键,找到C/C++,然后找到常规,在右侧的附加包含目录中输入下面三个目录的地址(因为我的有x(86),所以出现了下面的特殊符号):

    说明:在MFC中我们除了引入三个目录地址,还配置了预处理器定义"ESRI_WINDOW",在这里我并没有配置。

    配置好这个之后,在主程序文件中输入代码(这个代码我在这里就不做解释,到时候可以看这个文档的姊妹篇- 《VC2010+ArcGIS Engine10.1开发》

    ,最后效果如下:

    #include <QtCore/QCoreApplication>

    #include "ArcSDK.h"

    #include "qtextstream.h"

    int main(int argc, char *argv[])

    {

        ::CoInitialize(NULL);

    #pragma region 绑定许可

        IArcGISVersionPtr ipVer(__uuidof(VersionManager));

        VARIANT_BOOL succeeded;

        if (FAILED(ipVer->LoadVersion(esriArcGISEngine , L"10.1",&succeeded)))

            return 0;

    #pragma endregion

        //

    #pragma region 初始化许可

        IAoInitializePtr ipInit(CLSID_AoInitialize);

        esriLicenseStatus status;

        ipInit->Initialize(esriLicenseProductCodeEngine, &status);

        if (status != esriLicenseCheckedOut)

        {

            AoExit(0);

            return 0;

        }

            

    #pragma endregion

        QCoreApplication a(argc, argv);

    #pragma region 打开工作空间

        IWorkspaceFactoryPtr ipWorkspaceFactory(CLSID_ShapefileWorkspaceFactory);

        IWorkspacePtr pWs;

        BSTR bstr_str;

        QString q_str="D:\\guest\\chinasimplify";

            bstr_str = SysAllocString(q_str.utf16());

        HRESULT hr=ipWorkspaceFactory->OpenFromFile(bstr_str,0,&pWs);

        SysFreeString(bstr_str);

        QString q_str1="china_simply.shp";

            BSTR bStringWS=SysAllocString(q_str1.utf16());

        if (FAILED(hr))

        {

            return 0;

        }

    #pragma endregion

    #pragma region QI 这里和NET下不一样

        IFeatureWorkspacePtr ipRastWork (pWs);

    #pragma endregion

    #pragma region 打开要素类并获取个数

        IFeatureClassPtr pFtClass;

        hr=ipRastWork->OpenFeatureClass(bStringWS,&pFtClass);

        SysFreeString(bStringWS);

        if (FAILED(hr))

        {

            return 0;

        }

        long pCount=0;

        pFtClass->FeatureCount(NULL,&pCount);

    #pragma endregion

         QString s = QString::number(pCount, 10);

         QTextStream cout(stdout);

         cout<<s<< endl;

         QString str;

         QTextStream in(stdin);

         in >> str;

        return a.exec();

    }

     

    运行后可以看到下面的效果

     

    1. ArcGIS Engine+Qt(GUI开发)

    在MFC中我们介绍了两种开发GUI的方法,一种是通过生成相应的Activex控件MFC类,另一种是通过插入Activex控件的方法,在Qt里面做GUI的AE开发,也有两种不同的做法,而这两种做法需要引入的头文件也有差异,除了头文件的差异,我们需要配置额外的信息,在这里我们分别对两种方法介绍。

    1. ArcGIS Engine+Qt(GUI开发,使用Esri提供的控件类)

      1. 额外的配置

    对于这种方法,需要配置很多信息,在工程项目的连接器的常规中找到SDK的lib目录(在MFC的开发中,我们应该没有这个步骤),如下图:

     

    在附加依赖项中输入qt4ctl.lib和aoctl.lib文件如下图:

     

    此外还要在环境变量中配置Path(不一定要在Path中配置,只要在运行的时候能找到相应的文件即可),要不然在运行的时候会报下面的错误,如下图:

     

    这是因为Qt的AE在运行的时候用到了Engine安装目录下的bin下的三个文件:Qt4ctl.dll, aoctl.dll, ctlbase.dll,只要将Engine的bin目录配置到Path中就可以了,如下图:

    1. Esri提供的控件类

    当这些信息配置好了,我们就可以开发出GUI程序了,在Qt中我们认为一个可视化的组件是一个QWidget,这个QWidget类似MFC中的窗体,一旦有了这些QWidget,就可以用父组件的addWdiget方法加入,Esri提供了继承这些控件QWidget的类,我们可以在qtaxtcl.h头文件中找到,如下:

    class ESRI_EXT_CLASS QAxCtl

        : public QWidget

    {

    public:

        QAxCtl(const char *progID = NULL, QWidget *parent = NULL, const char *name = NULL);

        QAxCtl(const ControlDataPtr progID, QWidget *parent = NULL, const char *name = NULL);

        ~QAxCtl();

        HRESULT getInterface(IUnknown **ppUnk);

        HRESULT setCursor(HCURSOR cur);

    protected:

        bool eventFilter(QObject *qo, QEvent *qe);

    #if defined(ESRI_UNIX)

        bool x11Event(XEvent *event);

    #endif /* ESRI_UNIX */

    private:

        char *m_sProgID;

        AxContainerPtr m_pAxCont;

        void initialize(const char *progID);

    };

    1. 代码编写

    我们将这种GUI开发的先决条件都准备好了,下来就开始一个简单的GUI,这个例子我只将TOC,Map和Toolbar三个控件添加上去,并在Toolbar上添加了几个命令和工具,完整的代码如下(功能也比较简单,界面也不好看,只是当做一个例子,大家就将就看):

    #include <stdio.h>

    #include <qapplication.h>

    #include <qpushbutton.h>

    #include <qboxlayout.h>

    #include <qsplitter.h>

    #include <ArcSDK.h>

    #include <AxCtl/qt4axctl.h>

    #include <Ao/AoControls.h>

    void add_toolbar_items(IToolbarControl* pToolbar);

    int main(int argc, char **argv)

    {

            ::CoInitialize(NULL);

    #pragma region 绑定许可

        IArcGISVersionPtr ipVer(__uuidof(VersionManager));

        VARIANT_BOOL succeeded;

        if (FAILED(ipVer->LoadVersion(esriArcGISEngine , L"10.1",&succeeded)))

            return 0;

    #pragma endregion

            IAoInitializePtr ipInit(CLSID_AoInitialize);

            esriLicenseStatus status;

            ipInit->Initialize(esriLicenseProductCodeEngine, &status);

            if (status != esriLicenseCheckedOut)

            {

                printf("Invalid Licensing.\n");

                AoExit(0);

            }

        

        QApplication qapp(argc, argv);

        QWidget window;

        window.resize(500,400);

          

        

        QVBoxLayout vbox(NULL);

        QAxCtl tlb(AoPROGID_ToolbarControl);

        tlb.setMinimumHeight(30);

        tlb.setMaximumHeight(30);

        QSplitter split;

        QAxCtl toc(AoPROGID_TOCControl);

        QAxCtl map(AoPROGID_MapControl);

        window.setLayout(&vbox);

        vbox.addWidget(&tlb);

    split.addWidget(&toc);

        split.addWidget(&map);

        vbox.addWidget(&split);

        

            IToolbarControlPtr ipToolbar;

            IMapControl3Ptr ipMap;

            ITOCControlPtr ipToc;

            HRESULT hr;

            hr = tlb.getInterface((IUnknown **)&ipToolbar);

            hr = toc.getInterface((IUnknown **)&ipToc);

            hr = map.getInterface((IUnknown **)&ipMap);

            if (ipToolbar != 0)

                ipToolbar->SetBuddyControl(ipMap);

            if (ipToc != 0)

                ipToc->SetBuddyControl(ipMap);

            add_toolbar_items(ipToolbar);

        window.show();

        qapp.exec();    

        ipInit->Shutdown();

        ::CoUninitialize();

        AoExit(0);

        return 0;

    }

    void add_toolbar_items(IToolbarControl* pToolbar)

    {

        CComVariant varTool;

        long itemindex;

        if (!pToolbar)

            return;

        varTool = L"esriControlCommands.ControlsOpenDocCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsAddDataCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapZoomInTool";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_TRUE, 0,

            esriCommandStyleIconOnly, &itemindex);

          

        

        varTool = L"esriControlCommands.ControlsMapZoomOutTool";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapZoomInFixedCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapZoomOutFixedCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapPanTool";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapFullExtentCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapZoomToLastExtentBackCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsMapZoomToLastExtentForwardCommand";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsSelectFeaturesTool";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

        varTool = L"esriControlCommands.ControlsSelectTool";

        pToolbar->AddItem(varTool, 0, -1, VARIANT_FALSE, 0,

            esriCommandStyleIconOnly, &itemindex);

    }

    运行效果如下图:

    1. 小结

    这种方式跟在MFC中使用Axtivex的MFC类比较类似,都是自己实例化一个控件,然后将这个控件添加到父类控件中,但是Esri提供的这个方式,也有自己的弊端,不能调试,只能在Release版本下运行,估计是这中方式需要的几个dll,没有提供Debug版本的,如果调试,那么程序会在我们实例化控件的地方跳出去,这个问题搞了我好几天,总找不到什么原因,借助伟大的Google,最后在Esri的英文论坛中也看到类似的,论坛中在求这个dll和相关lib的debug,看到这个,我也就明白了。

    1.  
  • 相关阅读:
    iot 表索引dump《2》
    heap表和iot表排序规则不同
    Cannot complete the install because one or more required items could not be found.
    iot表输出按主键列排序,heap表不是
    iot 表主键存放所有数据,且按数据插入顺序排序
    iot表和heap表排序规则不同
    org.eclipse.graphiti.ui.editor.DiagramEditorInput.
    Oracle 排序规则
    perl 异步超时 打印错误
    14.6.3 Grouping DML Operations with Transactions 组DML操作
  • 原文地址:https://www.cnblogs.com/zuiyirenjian/p/2843682.html
Copyright © 2011-2022 走看看