资源描述
C#调用Google Earth COM API开发(一)
2009-07-18 来自: 字体大小:【大 中 小】
· 摘要:Google Earth提供了个人免费版、Plus版、Pro版,个人开发只安装个人免费版就可以了,如果需要更多的功能,那么只有每年上交$400购买专业版了。
·
-
一、准备
Google Earth提供了个人免费版、Plus版、Pro版,个人开发只安装个人免费版就可以了,如果需要更多的功能,那么只有每年上交$400购买专业版了
到目前为止,GoogleEarth的二次开发接口还比较少,功能太弱,仅仅提供了1.0的类库。
GoogleEarth COM API参考文档可以在这里找到:
C#调用COM的参考资料多如牛毛,大家可以到网上搜一下
二、例子
这里提供一个利用VS2008 + Google Earth 5.0开发一个“Hello world”程序
首先,确保已经正确安装GE,打开VS2008 ,新建一个Windows应用程序项目,在“项目”菜单中选择“添加引用…”,切换到“COM”选项卡,选择“Google Earth 1.0 Type Library”,其实就是Google Earth的主程序
在项目的引用中你可以看到已经添加了一个EARTHLib的引用,然后我们就可以调用其中的接口进行开发了。
下面就是小例子的代码(功能很简单,只有三个,打开GE,然后让GE保存一张截图,然后可以打开这个截图看看。呵呵)
1: // 功能:GE实例
2: // 描述:GE COM API 网址:
3: // 作者:温伟鹏
4: // 日期:2008-01-20
5:
6: using System;
7: using System.Collections.Generic;
8: using System.ComponentModel;
9: using System.Data;
10: using System.Drawing;
11: using System.Text;
12: using System.Windows.Forms;
13: using EARTHLib;
14: using System.Runtime.InteropServices;
15: using System.IO;
16: using System.Diagnostics;
17:
18: namespace GEDemo
19: {
20: public partial class Form1 : Form
21: {
22: /// <summary>
23: /// 标记GE是否已经启动
24: /// </summary>
25: private bool isGeStarted = false;
26: /// <summary>
27: /// 定义GE应用程序类
28: /// </summary>
29: private ApplicationGEClass GeApp;
30:
31: public Form1()
32: {
33: InitializeComponent();
34: }
35:
36: private void button1_Click(object sender, EventArgs e)
37: {
38: StartGE();
39: }
40:
41: /// <summary>
42: /// 启动GE
43: /// </summary>
44: private void StartGE()
45: {
46: if (isGeStarted)
47: {
48: return;
49: }
50:
51: try
52: {
53: GeApp = (ApplicationGEClass)Marshal.GetActiveObject("GoogleEarth.Application");
54:
55: isGeStarted = true;
56: }
57: catch
58: {
59: GeApp = new ApplicationGEClass();
60:
61: isGeStarted = true;
62: }
63: }
64:
65: private void button2_Click(object sender, EventArgs e)
66: {
67: string ssFile = Path.Combine(Application.StartupPath, "ScreenShot.jpg");
68:
69: try
70: {
71: //quality的取值范围在(0,100)之间,质量越高,quality越大
72: GeApp.SaveScreenShot(ssFile, 100);
73:
74: MessageBox.Show("成功保存截屏图像:" + ssFile);
75: }
76: catch(Exception ex)
77: {
78: MessageBox.Show("保存截屏图像时发生错误:" + ex.Message);
79: }
80: }
81:
82: private void button3_Click(object sender, EventArgs e)
83: {
84: string ssFile = Path.Combine(Application.StartupPath, "ScreenShot.jpg");
85:
86: if (!File.Exists(ssFile))
87: {
88: MessageBox.Show("未能找到保存的截屏图像!");
89: return;
90: }
91:
92: Process.Start(ssFile);
93: }
94:
95: private void button4_Click(object sender, EventArgs e)
96: {
97: this.Close();
98: Application.Exit();
99: }
100:
101: }
·
· C# 调用 Google Earth Com API开发(二)
继《C#调用GoogleEarth Com API开发(一)》,我Neil又带给大家第二篇文章。这一篇文章在第一篇的基础上,展示如何调用Windows API将GoogleEarth的界面隐藏掉,并将GoogleEarth的地图显示在自定义的窗体上。废话少说,直接上代码。
1、主窗口代码:
1: // 功能:GE实例(二)
2: // 描述:GE COM API 网址:
3: // 作者:温伟鹏
4: // 日期:2009-02-08
5:
6: using System;
7: using System.Collections.Generic;
8: using System.ComponentModel;
9: using System.Data;
10: using System.Drawing;
11: using System.Text;
12: using System.Windows.Forms;
13: using EARTHLib;
14:
15: namespace GEDemo
16: {
17: public partial class Form2 : Form
18: {
19: /// <summary>
20: /// 用来关闭GoogleEarth的消息定义
21: /// </summary>
22: static readonly Int32 WM_QUIT = 0x0012;
23:
24: private IntPtr GEHWnd = (IntPtr)5;
25: private IntPtr GEHrender = (IntPtr)5;
26: private IntPtr GEParentHrender = (IntPtr)5;
27: /// <summary>
28: /// 定义GE应用程序类
29: /// </summary>
30: private ApplicationGEClass GeApp;
31:
32: public Form2()
33: {
34: InitializeComponent();
35: }
36:
37: protected override void OnLoad(EventArgs e)
38: {
39: base.OnLoad(e);
40:
41: if (!this.DesignMode)
42: {
43: GeApp = new ApplicationGEClass();
44:
45: GEHWnd = (IntPtr)GeApp.GetMainHwnd();
46:
47: NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_BOTTOM, 0, 0, 0, 0,
48: NativeMethods.SWP_NOSIZE + NativeMethods.SWP_HIDEWINDOW);
49:
50: GEHrender = (IntPtr)GeApp.GetRenderHwnd();
51: GEParentHrender = (IntPtr)NativeMethods.GetParent(GEHrender);
52:
53: NativeMethods.MoveWindow(GEHrender, 0, 0, this.Width, this.Height, true);
54:
55: NativeMethods.SetParent(GEHrender, this.Handle);
56: }
57: }
58:
59: protected override void OnClosing(CancelEventArgs e)
60: {
61: base.OnClosing(e);
62:
63: NativeMethods.PostMessage(GeApp.GetMainHwnd(), WM_QUIT, 0, 0);
64: }
65: }
66: }
2、NativeMethods类定义:
1: // 功能:Windows API调用
2: // 描述:大家可以参照MSDN
3: // 作者:温伟鹏
4: // 日期:2009-02-08
5:
6: using System;
7: using System.Collections.Generic;
8: using System.Text;
9: using System.Runtime.InteropServices;
10:
11: namespace GEDemo
12: {
13: public class NativeMethods
14: {
15: [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
16: public static extern bool SetWindowPos(IntPtr hWnd, IntPtr hWndInsertAfter, int x, int y, int cx, int cy, UInt32 uflags);
17:
18: [DllImport("user32.dll", CharSet = CharSet.Auto)]
19: public static extern IntPtr PostMessage(int hWnd, int msg, int wParam, int lParam);
20:
21: #region 预定义
22:
23: public static readonly IntPtr HWND_BOTTOM = new IntPtr(1);
24: public static readonly IntPtr HWND_NOTOPMOST = new IntPtr(-2);
25: public static readonly IntPtr HWND_TOP = new IntPtr(0);
26: public static readonly IntPtr HWND_TOPMOST = new IntPtr(-1);
27: public static readonly UInt32 SWP_NOSIZE = 1;
28: public static readonly UInt32 SWP_NOMOVE = 2;
29: public static readonly UInt32 SWP_NOZORDER = 4;
30: public static readonly UInt32 SWP_NOREDRAW = 8;
31: public static readonly UInt32 SWP_NOACTIVATE = 16;
32: public static readonly UInt32 SWP_FRAMECHANGED = 32;
33: public static readonly UInt32 SWP_SHOWWINDOW = 64;
34: public static readonly UInt32 SWP_HIDEWINDOW = 128;
35: public static readonly UInt32 SWP_NOCOPYBITS = 256;
36: public static readonly UInt32 SWP_NOOWNERZORDER = 512;
37: public static readonly UInt32 SWP_NOSENDCHANGING = 1024;
38:
39: #endregion
40:
41: public delegate int EnumWindowsProc(IntPtr hwnd, int lParam);
42:
43: [DllImport("user32", CharSet = CharSet.Auto)]
44: public extern static IntPtr GetParent(IntPtr hWnd);
45:
46: [DllImport("user32", CharSet = CharSet.Auto)]
47: public extern static bool MoveWindow(IntPtr hWnd, int X, int Y, int nWidth, int nHeight, bool bRepaint);
48:
49: [DllImport("user32", CharSet = CharSet.Auto)]
50: public extern static IntPtr SetParent(IntPtr hWndChild, IntPtr hWndNewParent);
51:
52: [DllImport("user32.dll", ExactSpelling = true, CharSet = CharSet.Auto)]
53: public static extern IntPtr GetWindow(IntPtr hWnd, int uCmd);
54:
55: public static int GW_CHILD = 5;
56: public static int GW_HWNDNEXT = 2;
57: }
58: }
3、执行效果:
· C# 调用 Google Earth Com API开发(三)
好久没有更新《C#调用Google Earth Com API开发》系列文章了,今天带给大家的是第三篇,本篇相对于第二篇主要改进了三个方面。
1) 实现GoogleEarth显示画面随窗口大小改变而改变
2) 截获GoogleEarth鼠标消息,实现单击、双击功能;鼠标滚轮缩放现在只能放大!O(∩_∩)O~
3) 实现GoogleEarth彩色截图(测试环境:Windows 2003 Server ,Vista与Win7中不可用,XP未测)
下面还是继续看代码:
1、GoogleEarth动态改变大小
1: /// <summary>
2: /// 重新改变GoogleEarth视图的大小
3: /// </summary>
4: private void ResizeGoogleControl()
5: {
6: NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_PAINT, 0);
7: NativeMethods.PostMessage(GEHWnd, NativeMethods.WM_QT_PAINT, 0, 0);
8:
9: RECT mainRect = new RECT();
10: NativeMethods.GetWindowRect(GEHWnd, out mainRect);
11: clientRect = new RECT();
12: NativeMethods.GetClientRect(GEHrender, out clientRect);
13:
14: int offsetW = mainRect.Width - clientRect.Width;
15: int offsetH = mainRect.Height - clientRect.Height;
16:
17: int newWidth = this.Control.Width + (int)offsetW;
18: int newHeight = this.Control.Height + (int)offsetH;
19:
20: NativeMethods.SetWindowPos(GEHWnd, NativeMethods.HWND_TOP,
21: 0, 0, newWidth, newHeight,
22: NativeMethods.SWP_FRAMECHANGED);
23:
24: NativeMethods.SendMessage(GEHWnd, (uint)NativeMethods.WM_COMMAND, NativeMethods.WM_SIZE, 0);
25: }
2、鼠标消息
此例子中对于鼠标消息到处理使用了钩子,调用HookAPI.dll实现。
1: /// <summary>
2: /// 鼠标钩子
3: /// </summary>
4: private MouseHook mouseHook;
5:
6: // 设置鼠标钩子
7: mouseHook = new MouseHook();
8: mouseHook.MouseClick += new MouseEventHandler(mouseHook_MouseClick);
9: mouseHook.MouseDbClick += new MouseEventHandler(mouseHook_MouseDbClick);
10: mouseHook.MouseWheel += new MouseEventHandler(mouseHook_MouseWheel);
11: // 启动鼠标钩子
12: mouseHook.StartHook(HookType.WH_MOUSE_LL, 0);
单击事件:
1: /// <summary>
2: /// 鼠标钩子。鼠标单击事件
3: /// </summary>
4: /// <param name="sender"></param>
5: /// <param name="e"></param>
6: void mouseHook_MouseClick(object sender, MouseEventArgs e)
7: {
8: IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
9: if (hWnd == this.GeRenderHWnd)
10: {
11: Point point = this.Control.PointToClient(e.Location);
12: // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
13: if (this.Control.ClientRectangle.Contains(point))
14: {
15: Console.WriteLine("点击了GoogleEarth...");
16:
17: DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
18:
19: ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseClickPoint);
20:
21: Thread thread = new Thread(pts);
22: thread.Start(dp);
23:
24: }
25: }
26: }
27:
28: protected void ShowMouseClickPoint(object obj)
29: {
30: //Thread.Sleep(20);
31: DoublePoint dp = (DoublePoint)obj;
32: PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
33: Console.WriteLine("鼠标点击了:Lnt=" + pGe.Longitude.ToString()
34: + ";Lat=" + pGe.Latitude.ToString());
35: }
双击事件:
1: /// <summary>
2: /// 鼠标钩子。鼠标双击事件
3: /// </summary>
4: /// <param name="sender"></param>
5: /// <param name="e"></param>
6: void mouseHook_MouseDbClick(object sender, MouseEventArgs e)
7: {
8: IntPtr hWnd = NativeMethods.WindowFromPoint(e.Location);
9: if (hWnd == this.GeRenderHWnd)
10: {
11: Point point = this.Control.PointToClient(e.Location);
12: // 如果鼠标击点位置在控件内部,则说明鼠标点击了GoogleEarth视图
13: if (this.Control.ClientRectangle.Contains(point))
14: {
15: Console.WriteLine("xx双击了GoogleEarth...");
16:
17: DoublePoint dp = ((GERenderPanel)Control).DetermineScreenCoordinates(point.X, point.Y);
18:
19: ParameterizedThreadStart pts = new ParameterizedThreadStart(ShowMouseDbClickPoint);
20:
21: Thread thread = new Thread(pts);
22: thread.Start(dp);
23:
24: }
25: }
26: }
27:
28: protected void ShowMouseDbClickPoint(object obj)
29: {
30: //Thread.Sleep(20);
31: DoublePoint dp = (DoublePoint)obj;
32: PointOnTerrainGE pGe = GeApp.GetPointOnTerrainFromScreenCoords(dp.X, dp.Y);
33: Console.WriteLine("xx鼠标双击了:Lnt=" + pGe.Longitude.ToString()
34: + ";Lat=" + pGe.Latitude.ToString());
35:
36: MessageBox.Show("我还是出来一下吧!省得你不知道你已经双击了鼠标!");
37: }
这两处代码还比较简陋,比如未添加主窗口焦点检测,相信读者可以自行添加。O(∩_∩)O~
3、截图
程序中有两种截图功能,一种是GoogleEarth自带的截图功能,只能截取黑白图片;另一种为彩色截图,但是Vista以上操作系统不支持,还未找到合适的方法实现Vista与Win7兼容。
1) GoogleEarth自带截图功能:
1: GEViewContent view = GetGEView();
2:
3: if (view != null)
4: {
5: ApplicationGE ge = view.GeApplication;
6: if (ge != null && ge.IsInitialized() > 0)
7: {
8: using (SaveFileDialog sfd = new SaveFileDialog())
9: {
10: sfd.Filter = "jpg图片|*.jpg";
11: sfd.AddExtension = true;
12: sfd.CheckPathExists = true;
13: sfd.Title = "保存Google Earth截图";
14:
15: if (sfd.ShowDialog() == DialogResult.OK)
16: {
17: ge.SaveScreenShot(sfd.FileName, 100);
18: }
19: }
20: }
21: }
2) 彩色截图:
1: GEViewContent view = GetGEView();
2: if (view != null)
3: {
4: int nWidth = view.Control.Width;
5: int nHeight = view.Control.Height;
6: Point pt = view.Control.PointToScreen(view.Control.Location);
7: int nXSrc = pt.X;
8: int nYSrc = pt.Y;
9:
10: IntPtr hRender = view.GeRenderHWnd;
11:
12: if (hRender != IntPtr.Zero)
13: {
14: // 取得Rend
展开阅读全文