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,看到这个,我也就明白了。

转载于:https://www.cnblogs.com/zuiyirenjian/archive/2013/01/04/2843682.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/422012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

分享30个新鲜PSD网站模板免费下载

Web 设计始终是设计师充满挑战性的工作。他们需要的专业技能和与的伟大想法&#xff0c;来完成一个设计良好的网站。某个时候设计师需要帮助几个免费的资源&#xff0c;以使工作更轻松。这篇文章是一个完美的解决方案&#xff0c;为网站设计的资源。在这里我们目前 30 新鲜 PSD…

语法分析树(先看例子再看定义)

语法分析树&#xff08;先看例子再看定义&#xff09; 先讲例子 书上讲问题&#xff0c;先讲定义&#xff0c;一顿学术操作&#xff0c;让人云里雾里&#xff0c;然后出例子。其实这样往往让人觉得看书的过程就是放弃的过程。 关于语法分析树&#xff0c;我先从上篇文章的例…

middle函数C语言,C语言函数调用栈(三)

6 调用栈实例分析本节通过代码实例分析函数调用过程中栈帧的布局、形成和消亡。6.1 栈帧的布局示例代码如下&#xff1a;//StackReg.c#include //获取函数运行时寄存器%ebp和%esp的值#define FETCH_SREG(_ebp, _esp) do{\asm volatile( \"movl %%ebp, %0 \n" \"…

短信恢复 android,苹果手机短信恢复:安卓+苹果手机短信恢复教程,必须收藏!...

原标题&#xff1a;苹果手机短信恢复&#xff1a;安卓苹果手机短信恢复教程&#xff0c;必须收藏&#xff01;手机短信怎么恢复&#xff1f;日常生活中&#xff0c;大家或多或少会不小心把删除一些不必要的短信&#xff0c;比如注册某软件的验证码的短信&#xff0c;面试通知地…

Linux编程简介——VI

VI是Linux/Unix下标配的一个纯字符界面的文本编辑器。由于不支持鼠标功能&#xff0c;也没有图形界面&#xff0c;相关的操作都要通过键盘指令来完成&#xff0c;需要记忆大量命令。因此很多人不大喜欢它&#xff0c;但同时由于键盘的方式往往比鼠标来得快&#xff0c;一旦熟练…

xamarin android 标签,安卓端Tabbedpage调整在底部位置和标签及取消Android API28 以下的点击特效—-xamarin.forms学习笔记(一)...

使用tabbedpage时将安卓端导航放在底部,官网也有说明方法.总结:xmlns"http://xamarin.com/schemas/2014/forms"xmlns:x"http://schemas.microsoft.com/winfx/2009/xaml"xmlns:local"clr-namespace:aya"x:Class"aya.MainPage"xmlns:and…

android广播第三方库,Android Support 库:LocalBroadcastManager

在介绍完 Android Support 库发展历程(http://blog.chengyunfeng.com/?p1047)后&#xff0c; 再分别介绍下 Android Support 库中有用但是被忽略的一些功能。了解这些功能&#xff0c;在需要的时候可以避免在引入其他类似的第三方库或者避免自己重复制造轮子&#xff0c;提高开…

没有android:padding属性,android自定义无上下padding的textview

因为工作需要需要无上下padding的textview&#xff0c;经过查阅资料&#xff0c;很多说xml中的配置includefontpaddingfalse&#xff0c;但无法实现0 padding的需要。也有说通过设置负数的marginTop实现&#xff0c;但是不同字体&#xff0c;需要设置的值不同(因为自带的paddin…

科技论文的时态问题

如何在科技论文中使用时态英语谓语动词时态共有16种&#xff0c;在英文科技论文中用得较为频繁的主要有三种&#xff1a;即一般现在时、一般过去时和将来时。正确地使用动词时态是科研写作的基本功&#xff0c;我们在撰写英文论文时&#xff0c;如不能正确选用时态&#xff0c;…

android 卡片放大变详情页,ConstraintLayout动画实现布局卡片式滑动放大缩放

ConstraintLayout(约束布局)是Android Studio 2.2中主要的新增功能之一&#xff0c;Android studio升级到2.3版本之后&#xff0c;不管是新建Activity或fragment&#xff0c;xml默认布局由RelativeLayout更改为ConstraintLayout了。按照以往惯例先上效果图&#xff1a;GIF.gif上…

开源路由软件zebra的命令存储原理及使用方法

ZZ FROM: http://www.cnblogs.com/iTsihang/archive/2012/12/05/2783252.html zebra在设计命令格式的时候&#xff0c;将命令节点Node和命令Command分开&#xff0c;整个命令结构是一个树状的,如图&#xff1a; NODEn表示命令节点&#xff0c;CMDn表示具体的命令。在zebra的整…

网易邮箱写邮件HTML转换按钮,网易邮箱推出虚拟场景写信功能 身临其境写邮件...

当你用电子邮件给好友发出问候时&#xff0c;是否怀念着曾经繁茂成荫、绿野同行的过往&#xff1f;当你给他(她)写信表达思念时&#xff0c;是否憧憬着秋风初起、阳光清透的意境&#xff1f;近期&#xff0c;网易邮箱独家推出“虚拟场景写信”功能&#xff0c;可以帮助用户在写…