在QT中调用google earth并打开KML文件

最近由于项目需求,需要在自己做的软件中调用卫星地球,笔者先后尝试了高德、百度和谷歌地球,最后选择了谷歌地球。原因在于高德地图的卫星地球模式清晰度完全不能满足使用要求;百度地图的清晰度虽然可以满足使用要求,但清晰度也不如google earth,且百度地图的调用方法是将其网页嵌入自己的软件界面中,对于我这个不熟悉javascript的人来说难度较大;所以我选择google earth,清晰度最高,学习资料也多,与本项目合作的公司也用的是google earth,美中不足的是用google earth得翻墙。

由于笔者软件是在QT平台上编写的,下面来说说在QT中调用google earth的方法,环境是win10+QT5.9.9+Google earth pro 7.3.2.5776。

现有博客也有不少讲如何在QT中调用google earth的,如博客1博客2。本人也是主要参考这两篇博客编写程序,但这两篇博客有较多坑没有说到,导致我在实际搬砖中仍举步维艰,所以在此我主要说一下写代码中遇到的坑。

首先是google earth版本的选择,在网上的大部分博客中都选择了GoogleEarth_7.1.2.2041,但我在安装这个软件之后,不知什么原因,并不能正常运行(在已用翻墙软件的情况下),所以我最后选择了Google earth pro 7.3.2.5776,那为什么这个版本就行我到现在也不清楚,而最新版的Google earth pro 7.3.3.7699就不行,可能是调用接口没开放的原因吧,如果大家想要Google earth pro 7.3.2.5776的安装包,联系我就好(文末QQ)。

代码编写我是直接复制了博客2的,并在其基础上多加了些注释和打开kml文件的功能。

google.h

#ifndef GOOGLE_H
#define GOOGLE_H

#include <QMainWindow>
#include <guiddef.h>
//#include "windows.h"
#include "googleearth.tlh"

#import "C:\Program Files (x86)\Google\Google Earth\client\googleearth.exe" no_namespace

static const CLSID CLSID_ApplicationGE ={0x8097D7E9,0xDB9E,0x4AEF, {0x9B,0x28,0x61,0xD8,0x2A,0x1D,0xF7,0x84}};
static const CLSID IID_IApplicationGE ={0x2830837B,0xD4E8,0x48C6, {0xB6,0xEE,0x04,0x63,0x33,0x72,0xAB,0xE4}};


namespace Ui {
class Google;
}

class Google : public QMainWindow
{
    Q_OBJECT

public:
    explicit Google(QWidget *parent = 0);
    ~Google();

    static void KillProcess(const QString& strProcName);

    void StartGE(void);

private slots:
    
    void on_actOpenKML_triggered();  //打开KML文件

private:
    IApplicationGE* m_GEApp;

    HWND m_GEParentHandle;//GE视图父窗口句柄
    HWND m_GEHandle;    //GE视图区窗口句柄
    HWND m_GeMainHandle;//GE主窗体句柄

    Ui::Google *ui;
};

#endif // GOOGLE_H

google.c

#include "google.h"
#include "ui_google.h"
#include "windows.h"
#include "windef.h"
#include "tchar.h"


Google::Google(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Google)
{
    ui->setupUi(this);

    //试图清除其他事先运行的GE
    this->KillProcess("Google Earth");
    this->KillProcess("GoogleEarth");
    this->KillProcess("GoogleCrashHandler");

    StartGE();
}

Google::~Google()
{
    PostMessage(m_GeMainHandle, WM_QUIT, 0, 0);  //结束google earth进程
    delete ui;
}


void Google::KillProcess(const QString &strProcName)
{
    DWORD dwProcID;
    HANDLE hProcess;
    TCHAR wProcName[260];
    int Len = strProcName.toWCharArray(wProcName);
    wProcName[Len] = _T('\0');
    HWND h = FindWindow(0,wProcName);
    if(h)
    {
        GetWindowThreadProcessId(h,&dwProcID);
        hProcess = OpenProcess(PROCESS_TERMINATE,JOB_OBJECT_ASSIGN_PROCESS,dwProcID);
        TerminateProcess(hProcess,0);
    }
}


void Google::StartGE()
{
    HRESULT hr;
    hr = CoCreateInstance(CLSID_ApplicationGE,NULL,CLSCTX_LOCAL_SERVER,IID_IApplicationGE,(void**) &m_GEApp);
    if(SUCCEEDED(hr))
    {
        bool onlie = m_GEApp->IsInitialized();
        onlie = m_GEApp->IsOnline();
        m_GeMainHandle = (HWND)m_GEApp->GetMainHwnd();//隐藏启动的GE
        ::SetWindowPos(m_GeMainHandle, HWND_BOTTOM, 0 , 0, 0, 0, SWP_NOSIZE|SWP_HIDEWINDOW);
        m_GEHandle =(HWND) m_GEApp->GetRenderHwnd();//截获GE的视图区
        RECT rect;
        ::GetWindowRect((HWND)this->winId(), &rect);//取得当前视图窗口客户区大小
        m_GEParentHandle = ::GetParent(m_GEHandle);//保存GE视图区旧的父窗体句柄
        ::SetParent(m_GEHandle, (HWND)ui->GE_Widget->winId());//截获GE视图
        ::SetWindowPos(m_GeMainHandle,HWND_BOTTOM,rect.left,rect.top,rect.right-rect.left+650,rect.bottom-rect.top+150,SWP_FRAMECHANGED);//显示GE
    }
}

//打开KML文件
void Google::on_actOpenKML_triggered()
{

    QString fileName = QFileDialog::getOpenFileName(this,
                            QString("Open KML file"), ".",
                            QString("KML File(*.kml *.kmz)"));
    if (!fileName.isEmpty())
    {
        string filename = fileName.toStdString();
        m_GEApp->OpenKmlFile(_bstr_t(filename.c_str()),1);
    }
}

值得说一下的是文中这句代码决定了你将谷歌地球的界面放在你的QT哪个窗口中,比如这里放的是ui->GE_Widget;

::SetParent(m_GEHandle, (HWND)ui->GE_Widget->winId());

而下面这句话是来设置google earth界面的大小的;

::SetWindowPos(m_GeMainHandle,HWND_BOTTOM,rect.left,rect.top,rect.right-rect.left+650,rect.bottom-rect.top+150,SWP_FRAMECHANGED);

在打开KML文件时,要注意由下面这句代码将文件名转为_bstr_t形式,不然打不开KML文件;

_bstr_t(filename.c_str())

最后大家记得用下面这句代码结束google earth进程,不然你下次运行程序很可能无法调用google earth。

PostMessage(m_GeMainHandle, WM_QUIT, 0, 0);

总结一下,我在做的时候很多时间都耗费在google earth版本的选择上,因为真的试了很多,同样的代码就是调用不起来,而版本Google earth pro 7.3.2.5776就行,真的是个玄学,还有就是我在运行程序的时候翻墙软件一直开着,不然google earth不能用。

贴两个运行程序的界面图,如下所示:

刚运行时:

打开KML文件后:

没错,我是做输电线路的,哈哈,图中的Q1,Q2等标记和连线就是读取KML文件后自动标记上去的。

欢迎各位大佬与我交流哈。

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Google Earth KML文件生成工具是一种用于创建KML(Keyhole Markup Language)文件的工具。KML文件是一种用于地图可视化和地理信息展示的开放标准文件格式,它可以包含地图坐标、文本、图像、视频和其他地理信息。 Google Earth KML文件生成工具的主要功能是帮助用户创建和编辑KML文件,以实现地图数据的可视化和交互。使用该工具,用户可以通过简单的拖拽和点击操作来添加标记、路径、面和图层等元素,并指定它们的属性和样式。用户还可以导入和导出各种地图数据格式,如Shapefile、CSV和GPX,以便更方便地利用现有的地图数据。 KML文件生成工具通常会提供丰富的地图编辑功能,如测距、面积计算、缩放和旋转等,以支持用户更精细的地图设计。某些工具还具备高级功能,如卫星图像覆盖、地形生成和地理编码等,以满足用户更复杂的地理数据处理需求。 最重要的是,Google Earth KML文件生成工具往往与Google Earth软件无缝集成,可以直接将生成的KML文件导入到Google Earth进行可视化展示。Google Earth是一款功能强大的虚拟地球软件,用户可以在其展现自己创建的地图数据,并享受全球范围的真实地貌、三维建筑和街景等视觉体验。 总之,Google Earth KML文件生成工具是一种便捷的工具,具备易用性和灵活性,可以帮助用户快速创建和编辑KML文件,并通过Google Earth进行地图数据的可视化展示。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值